خطأ PHP فادح: حجم الذاكرة المسموح به — كسر الخرافات والضبط

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا يتعطل سكريبت PHP الخاص بك؟

\n\n

هل سبق لك أن رأيت شاشة بيضاء مع رسالة مرعبة «Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted»؟ إذا كان الأمر كذلك، فأنت لست وحدك. هذا السؤال على Stack Overflow حصل على آلاف المشاهدات، وكل مطور PHP ثاني واجهه مرة واحدة على الأقل في حياته.

\n\n

الرقم 134217728 بايت هو بالضبط 128 ميغابايت (الحد الافتراضي للعديد من الاستضافات). عندما يحاول سكريبتك استخدام مساحة أكبر، يقول PHP «توقف» ويطرح خطأ فادحًا. لكن لا داعي للذعر! في هذه المقالة، سنشرح لماذا يحدث هذا، وكيفية إصلاحه، والأهم من ذلك، كيفية تحسين الأداء حتى لا يزعجك خطأ الذاكرة مرة أخرى.

\n\n

المقالة مكتوبة للموقع التعليمي PythonLib، لكن كل الكود والأمثلة بلغة PHP. هيا بنا!

\n\n

ما هو memory_limit ومن أين يأتي «134217728»؟

\n\n

في PHP، هناك توجيه memory_limit يحدد الحد الأقصى للذاكرة المتاحة لسكريبت واحد. بشكل افتراضي، في العديد من التكوينات (خاصة على الاستضافات المشتركة)، تكون القيمة 128M (أو 134217728 بايت).

\n\n

يمكنك التحقق من الحد الحالي بهذه الطريقة:

\n\n
<?php\necho ini_get('memory_limit'); // سيظهر، مثلاً، "128M"\n?>
\n\n

عندما يتجاوز سكريبتك هذا الحد، يقوم PHP بإنهاء التنفيذ فورًا بخطأ فادح. الأسباب قد تكون مختلفة: من كود غير مثالي إلى تحميل ملفات ضخمة في الذاكرة.

\n\n

السيناريوهات النموذجية المسببة للخطأ

\n\n
    \n
  • العمل مع مصفوفات كبيرة — مثل قراءة ملف CSV بالكامل في الذاكرة.
  • \n
  • حلقات مع تسريبات — نسيان تحرير المتغيرات أو استخدام مصفوفات عامة.
  • \n
  • مكتبات معالجة الصور — GD أو Imagick عند العمل مع صور عالية الدقة.
  • \n
  • الدوال التكرارية — بدون شرط أساسي، تصبح لا نهائية وتستهلك المكدس.
  • \n
  • ORM والتخزين المؤقت — بعض ORM (مثل Doctrine) قد تحمل الجدول بأكمله في الذاكرة.
  • \n
\n\n

كيفية إصلاح الخطأ: 3 طرق مجربة

\n\n

1. زيادة الحد مؤقتًا عبر ini_set()

\n\n

أسرع طريقة هي زيادة الحد مباشرة في السكريبت:

\n\n
<?php\nini_set('memory_limit', '256M');\n// الآن يمكن للسكريبت استخدام حتى 256 MB\n?>
\n\n

مهم: هذا يعمل فقط إذا كانت استضافتك تسمح بإعادة تعريف التوجيه. في بعض الاستضافات، يكون ini_set() لـ memory_limit محظورًا.

\n\n

2. تعديل php.ini أو .htaccess

\n\n

إذا كان لديك وصول إلى الخادم، قم بتحرير php.ini:

\n\n
memory_limit = 256M
\n\n

أو عبر .htaccess (على Apache):

\n\n
php_value memory_limit 256M
\n\n

بعد التغييرات، أعد تشغيل خادم الويب أو PHP-FPM.

\n\n

3. تحسين الكود — أفضل طريقة

\n\n

زيادة الحد هو حل مؤقت. الحل الحقيقي هو كتابة كود فعال. دعنا نستعرض أمثلة.

\n\n

مثال واقعي: معالجة ملف CSV كبير

\n\n

لنفترض أن لديك ملف CSV يحتوي على 500,000 سطر. الكود الساذج قد يبدو هكذا:

\n\n
<?php\n$rows = file('data.csv'); // يحمل الملف بأكمله في الذاكرة!\nforeach ($rows as $row) {\n    // معالجة\n}\n?>
\n\n

عند حجم ملف 200 MB، سيتعطل السكريبت بخطأ ذاكرة.

\n\n

التحسين: القراءة سطرًا سطرًا

\n\n
<?php\n$handle = fopen('data.csv', 'r');\nif ($handle) {\n    while (($row = fgetcsv($handle)) !== false) {\n        // معالجة سطر واحد في كل مرة\n        // الذاكرة لا تزيد تقريبًا\n    }\n    fclose($handle);\n}\n?>
\n\n

الآن يستخدم السكريبت بضعة ميغابايت فقط، بغض النظر عن حجم الملف.

\n\n<

المدونات

توصيات الكتب