یکی از رفتارهای مهم PHP که خیلیها ازش خبر ندارن، Copy-on-Write یا همون COW هست.
مثلاً:
$data = range(1, 1_000_000);
$copy = $data;
شاید فکر کنی الان PHP دو آرایهی یکسان داخل Memory ساخته.
اما نه. 👀
زبانPHP در این مرحله میتونه هر دو متغیر رو به همون دادهی موجود در Memory ارجاع بده.
تا وقتی که یکی از اونها تغییر نکرده:
$data = range(1, 1_000_000);
$copy = $data;
عملاً لازم نیست فوراً یک کپی کامل ساخته بشه.
اما وقتی تغییر ایجاد میکنی:
$copy[0] = 999;
اینجاست که PHP باید داده رو از هم جدا کنه.
یعنی:
$data ───────┐
├──> Same Memory
$copy ───────┘
↓ تغییر
$data ─────────> Original Data
$copy ─────────> New Copy
🔥 نکته مهمتر
این موضوع وقتی مهم میشه که با آرایههای بزرگ کار میکنی.
مثلاً:
function process(array $data): void
{
$data['status'] = 'processed';
}
$users = getHugeArray();
process($users);
ممکنه با دیدن array $data فکر کنی PHP از همون ابتدا کل آرایه رو کپی کرده.
اما Pass-by-Value در PHP الزاماً به معنی Copy فوری نیست.
زبانPHP میتونه از Copy-on-Write استفاده کنه و فقط زمانی واقعاً کپی ایجاد کنه که داده نیاز به تغییر داشته باشه.
---
⚠️ اما اینجا یک دام وجود داره
اگر واقعاً نمیخوای آرایه کپی بشه و فقط میخوای تابع روی همان داده کار کنه، میتونی از Reference استفاده کنی:
function process(array &$data): void
{
$data['status'] = 'processed';
}
ولی این به معنی «همیشه بهتر بودن Reference» نیست.
حالا Referenceها میتونن باعث پیچیدهتر شدن رفتار کد و ایجاد Side Effect بشن.
پس صرفاً برای کاهش Memory نباید کورکورانه از & استفاده کرد.
---
🧠 نکته حرفهای امروز
در PHP:
Assignment ≠ Copy فوری
و:
Pass-by-Value ≠ Copy فوری
به لطف Copy-on-Write، PHP تا زمانی که لازم نباشه داده رو واقعاً Duplicate نمیکنه.
بنابراین وقتی Performance و Memory برات مهمه، باید تفاوت بین:
Value
Reference
Copy-on-Write
و
Actual Memory Copy
رو بشناسی.
این دقیقاً یکی از تفاوتهای بین «کدی که فقط کار میکنه» و «کدی که رفتار PHP Engine رو میفهمه» است. 🐘
@CodeVerse_dev