«Allowed Memory Size of 134217728 Bytes Exhausted» — كابح طوارئ تطبيق PHP الخاص بك
\n\nهل سبق لك أن رأيت هذه الرسالة في منتصف الليل، عندما يتعطل موقعك فجأة، وتظهر في السجلات كتابة بيضاء على خلفية سوداء؟ إذا كان الأمر كذلك، فأنت لست وحدك. آلاف المطورين على Stack Overflow تساءلوا لماذا يستهلك سكربت PHP الذي يبدو غير ضار فجأة كل 128 ميجابايت من ذاكرة الوصول العشوائي ويتعطل مع خطأ فادح.
\n\nدعنا نفهم ما يعنيه هذا الخطأ حقًا، ولماذا يحدث، والأهم من ذلك، كيفية إصلاحه نهائيًا. لن نقوم فقط بزيادة حد الذاكرة — بل سنتعلم كتابة كود لا يستهلك الموارد مثل طالب جائع في الكافتيريا.
\n\nماذا يعني «134217728 Bytes Exhausted»؟
\n\nالرقم 134,217,728 هو 128 ميجابايت. هذا هو مقدار الذاكرة المسموح لسكربت PHP باستخدامه افتراضيًا. عندما يحاول السكربت تخصيص المزيد — بام! — وستحصل على Fatal Error. هذه آلية حماية تمنع سكربتًا واحدًا من تعطيل الخادم بأكمله.
ولكن المشكلة هي: 128 ميجابايت قليلة جدًا للتطبيقات الحديثة. معالجة ملف XML كبير، إنشاء تقرير من قاعدة بيانات، العمل مع الصور أو المكتبات الثقيلة — كل هذا يمكن أن يتجاوز الحد بسهولة.
\n\nلماذا يحدث هذا؟ ثلاثة أسباب رئيسية
\n\n- \n
- الحلقات الجشعة والتكرار — عندما تقوم بتحميل جميع البيانات إلى الذاكرة دفعة واحدة، بدلاً من معالجتها على أجزاء. \n
- تسرب الذاكرة — المتغيرات الثابتة، المصفوفات العامة، والاستخدام الخاطئ لـ
staticيمكن أن تتراكم البيانات. \n - المكتبات والإضافات الثقيلة — مثل معالجة الصور عبر GD أو العمل مع PDF. \n
كيفية إصلاح الخطأ: من البسيط إلى المعقد
\n\nالطريقة 1: زيادة حد الذاكرة (حل سريع)
\n\nالطريقة الأكثر وضوحًا هي ببساطة إعطاء PHP ذاكرة أكبر. لكن تذكر: هذا ليس علاجًا، بل مسكن ألم. إذا كان كودك سيئًا، فسيستهلك 512 ميجابايت و1 جيجابايت أيضًا.
\n\nهناك ثلاث طرق لزيادة الحد:
\n\n1. في ملف php.ini (تغيير دائم):
\nmemory_limit = 256M\n\n2. في .htaccess (إذا كان متاحًا):
\nphp_value memory_limit 256M\n\n3. داخل السكربت نفسه (للتشغيل الحالي فقط):
\nini_set('memory_limit', '256M');\n\nلكن تحذير: إذا كنت على استضافة مشتركة، قد لا يسمح لك المضيف بزيادة الحد فوق عتبة معينة. وحتى لو سمح — لا تسيء الاستخدام.
\n\nالطريقة 2: تحسين الكود — الحل الحقيقي
\n\nبدلاً من إعطاء السكربت ذاكرة أكبر، دعنا نعلمه استخدام ما هو متاح بذكاء.
\n\nاستخدم unset() لتحرير الذاكرة
\n\nPHP ليست C++، لكن إدارة الذاكرة اليدوية لا تزال تعمل. عندما لا تحتاج إلى متغير كبير بعد الآن — احذفه:
\n\n$data = file_get_contents('huge_file.csv');\n// معالجة البيانات\nprocessData($data);\n// تحرير الذاكرة\nunset($data);\n\n\nعالج البيانات على أجزاء
\n\nبدلاً من تحميل 100,000 سطر من قاعدة البيانات إلى الذاكرة، استخدم المؤشرات أو الحدود:
\n\n// سيء: تحميل كل شيء في الذاكرة\n$users = $db->query("SELECT * FROM users")->fetchAll();\n\n// جيد: معالجة سطر بسطر\n$stmt = $db->query("SELECT * FROM users");\nwhile ($row = $stmt->fetch()) {\n processUser($row);\n // PHP سيحرر الذاكرة تلقائيًا بعد كل تكرار\n}\n\n\nاستخدم المولدات (yield)
\n\nالمولدات هي سحر للعمل مع مجموعات البيانات الكبيرة. لا تخزن جميع القيم في الذاكرة:
\n\nfunction getLargeData() {\n for ($i = 0; $i < 1000000; $i++) {\n yield $i;\n }\n}\n\nforeach (getLargeData() as $value) {\n // معالجة عنصر واحد في كل مرة\n echo $value . "\\n";\n}\n