لماذا جلسة PHP الخاصة بك تعيش أطول من اللازم؟
\n\nهل تساءلت يومًا لماذا بعد 30 دقيقة من عدم النشاط، لا يزال موقعك يتذكر أنك مسجل الدخول؟ أو على العكس، يشكو المستخدمون من طردهم من النظام مبكرًا جدًا؟ مشكلة إدارة وقت حياة الجلسة في PHP هي واحدة من أكثر الصداعات شيوعًا للمطورين المبتدئين (وحتى المحترفين). سؤال "How do I expire a PHP session after 30 minutes?" حصد آلاف المشاهدات على Stack Overflow، وهذا ليس من قبيل الصدفة.
\n\nدعنا نفهم كيف نجعل جلسة PHP تنتهي بالضبط بعد 30 دقيقة. سنستعرض ثلاث طرق: من البسيطة (لكنها خادعة) إلى الاحترافية. ستتعرف لماذا session.gc_maxlifetime غالبًا لا يعمل كما تتوقع، وكيف تكتب كودًا موثوقًا لا يخذلك.
المشكلة: ما هو "وقت حياة الجلسة" حقًا؟
\n\nقبل أن نغوص في الكود، دعنا نفهم الأساسيات. جلسة PHP ليست مجرد مؤقت يعمل في المتصفح. إنها ملف على الخادم (عادة في /tmp/) يخزن بيانات المستخدم. "انتهاء" الجلسة يعني حذف هذا الملف أو جعله غير صالح.
هناك ثلاث نقاط رئيسية تؤثر على وقت الحياة:
\n\n- \n
- كوكي الجلسة: المتصفح يخزن معرف الجلسة (عادة في كوكي
PHPSESSID). لهذا الكوكي وقت حياة خاص به. \n - ملف الجلسة على الخادم: له وقت آخر تعديل (mtime). \n
- جامع القمامة (GC): PHP ينظف ملفات الجلسات القديمة بشكل دوري، لكن ليس وفق جدول زمني، بل بشكل عشوائي. \n
بسبب هذه البنية "ثلاثية المستويات" ينشأ الارتباك. ضبط معامل واحد فقط غالبًا لا يعطي التأثير المطلوب.
\n\nالطريقة 1: الساذجة — فقط session.gc_maxlifetime
\n\nالطريقة الأكثر وضوحًا التي تقترحها الوثائق هي تعيين session.gc_maxlifetime. يبدو أن هذا هو الجواب على سؤال "How do I expire a PHP session after 30 minutes?". لكن الأمور ليست بهذه البساطة.
<?php\n// بدء الجلسة\nsession_start();\n\n// ضبط وقت حياة الجلسة بالثواني (30 دقيقة = 1800 ثانية)\nini_set('session.gc_maxlifetime', 1800);\n\n// ضبط وقت حياة كوكي الجلسة أيضًا على 30 دقيقة\nsession_set_cookie_params(1800);\n\n// هل انتهينا؟ لا.\n?>\n\nلماذا قد لا يعمل هذا؟
\n- \n
- جامع القمامة (GC) كسول. يتم تشغيله باحتمال
session.gc_probability/session.gc_divisor(افتراضيًا 1/100). أي حتى لو كان عمر ملف الجلسة ساعة، قد لا يتم حذفه في الطلب التالي إذا لم يعمل GC. \n - تطبيقات أخرى. إذا كان هناك عدة مواقع على الخادم، فقد تنظف جلسات بعضها البعض أو لا تنظف جلساتك. \n
- التخزين المؤقت. في بعض الاستضافات (خاصة المشتركة) قد يتم تجاهل إعدادات
ini_set. \n
الحكم: هذه الطريقة هي الأساس، لكنها ليست حلاً سحريًا. تعمل فقط في الظروف المثالية. للإنتاج تحتاج إلى التعمق أكثر.
\n\nالطريقة 2: مؤقت يدوي داخل الجلسة (موصى به)
\n\nهذا النهج هو الحل الوسط المثالي. بدلاً من الاعتماد على جامع القمامة، نتحكم بأنفسنا في وقت آخر نشاط للمستخدم. هذا هو الإجابة الأكثر شيوعًا على Stack Overflow حول موضوع جلسة PHP تنتهي بعد 30 دقيقة.
\n\nالفكرة بسيطة: مع كل طلب، نتحقق من وقت آخر نشاط للمستخدم. إذا مر أكثر من 30 دقيقة، ندمر الجلسة.
\n\n<?php\nsession_start();\n\n// وقت حياة الجلسة بالثواني\n$session_lifetime = 1800; // 30 دقيقة\n\n// التحقق مما إذا كان قد تم تعيين طابع زمني لآخر نشاط\nif (isset($_SESSION['LAST_ACTIVITY'])) {\n // حساب الفرق بين الوقت الحالي