جلسة PHP تنتهي بعد 30 دقيقة: 4 طرق عملية

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

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

ابدأ الدورة

مقدمة: "لماذا لا تنتهي جلستي؟"

\n\n

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

\n\n

سؤال "How do I expire a PHP session after 30 minutes?" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow (عشرات الآلاف من المشاهدات). وليس من المستغرب: غالبًا ما يعتقد المطورون المبتدئون أن مجرد ضبط session.gc_maxlifetime سيجعل كل شيء يعمل. ثم يتفاجأون لماذا تعيش الجلسة لساعات.

\n\n

في هذه المقالة، سنستعرض 4 طرق حقيقية لجعل جلسة PHP تنتهي تمامًا بعد 30 دقيقة. ستتعرف على سبب فشل الإعدادات الافتراضية، وأي طريقة تختار لمهمتك. هيا بنا!

\n\n

القليل من النظرية: كيف تدير PHP وقت الجلسة

\n\n

قبل كتابة الكود، من المهم فهم آليتين تؤثران على "موت" الجلسة:

\n\n
    \n
  • عمر ملف تعريف الارتباط للجلسة - المدة التي يخزن فيها المتصفح معرف الجلسة (PHPSESSID). يتم التحكم فيه بواسطة session.cookie_lifetime.
  • \n
  • عمر البيانات على الخادم - المدة التي يبقى فيها ملف الجلسة في مجلد /tmp. يتم التحكم فيه بواسطة session.gc_maxlifetime.
  • \n
\n\n

المشكلة هي أن جامع القمامة (GC) يعمل بشكل احتمالي. افتراضيًا، يعمل في 1% من الطلبات. هذا يعني أنه حتى لو كان gc_maxlifetime = 1800 (30 دقيقة)، قد تظل الجلسة معلقة لمدة ساعة أخرى حتى يصل إليها GC.

\n\n

لذلك، الاعتماد فقط على إعداد الخادم فكرة سيئة. تحتاج إلى التحقق من الوقت "يدويًا".

\n\n

الطريقة رقم 1. الكلاسيكية: التحقق من الوقت في الجلسة (موصى به)

\n\n

هذه هي الطريقة الأكثر موثوقية ووضوحًا. أنت بنفسك تخزن في الجلسة طابعًا زمنيًا لآخر نشاط، وعند كل طلب تتحقق مما إذا كانت 30 دقيقة قد مضت أم لا.

\n\n
<?php\nsession_start();\n\n// ضبط مدة صلاحية الجلسة - 30 دقيقة (1800 ثانية)\n$timeout_duration = 1800;\n\n// إذا كان هناك طابع زمني في الجلسة وقد انتهت صلاحيته\nif (isset($_SESSION['LAST_ACTIVITY']) && \n    (time() - $_SESSION['LAST_ACTIVITY']) > $timeout_duration) {\n    // تدمير الجلسة\n    session_unset();\n    session_destroy();\n    // إعادة التوجيه إلى صفحة تسجيل الدخول\n    header("Location: login.php?timeout=1");\n    exit;\n}\n\n// تحديث الطابع الزمني (إذا كان المستخدم نشطًا)\n$_SESSION['LAST_ACTIVITY'] = time();\n?>
\n\n

المزايا:

\n
    \n
  • تحكم مطلق: ستنتهي الجلسة تمامًا بعد 30 دقيقة من عدم النشاط.
  • \n
  • لا تعتمد على إعدادات PHP وجامع القمامة.
  • \n
  • سهولة تغيير الوقت لأقسام مختلفة من الموقع (مثلًا، لوحة التحكم - 15 دقيقة، المستخدم - 60).
  • \n
\n\n

العيوب:

\n
    \n
  • تحتاج إلى إضافة التحقق في كل صفحة (أو وضعه في ملف تهيئة مشترك).
  • \n
  • إذا أبقى المستخدم الصفحة مفتوحة دون نقر، ستنتهي الجلسة. بالنسبة لبعض السيناريوهات (نموذج طويل)، هذا عيب.
  • \n
\n\n

الطريقة رقم 2. المدمجة: gc_maxlifetime + cookie_lifetime

\n\n

إذا كنت لا تريد كتابة تحقق يدوي، يمكنك محاولة ضبط PHP "خارج الصندوق". لكن تذكر الفروق الدقيقة.

\n\n
// في بداية السكريبت، قبل session_start()\n$lifetime = 1800; // 30 دقيقة\n\n// ضبط عمر ملف تعريف الارتباط للجلسة\nsession_set_cookie_params($lifetime);\n\n// ضبط أقصى عمر للبيانات على الخادم\nini_set('session.gc_maxlifetime', $lifetime);\n\n// الآن ابدأ الجلسة\nsession_start();
\n\n

بالإضافة - لجعل GC يعمل بشكل متكرر، يمكنك تقليل احتمالية التشغيل:

\n\n
ini_set('session.gc_probability', 1);\nini_set('session.gc_divisor', 1); // سيعمل GC مع كل طلب                

المدونات

توصيات الكتب