الجلسات والكوكيز في PHP: كيف يتذكر الموقع زائره
تسجّل دخولك في موقع، ثم تنتقل بين عشر صفحات وهو ما زال يعرف من أنت. تضيف منتجاً إلى السلة، فتجده فيها بعد ساعة. كيف يتذكرك الموقع؟ في هذا الدرس ستتعلم الأداتين اللتين يقوم عليهما ذلك: الكوكيز (Cookies) والجلسات (Sessions)، وستبني بهما نظام تسجيل دخول بسيطاً.
المشكلة: الخادم ينسى
Section titled “المشكلة: الخادم ينسى”بروتوكول الويب HTTP بلا ذاكرة: كل طلب يصل إلى الخادم يُعامل كأنه من زائر جديد تماماً. تخيّل موظف استقبال يفقد ذاكرته كل دقيقة: في كل مرة تكلّمه يسألك «من أنت؟».
هناك حلان، وكلاهما يشبه شيئاً تعرفه:
- الكوكيز مثل ورقة صغيرة يعطيها لك الموظف وتحتفظ بها أنت، وتريها له في كل زيارة.
- الجلسة مثل خزانة الأمانات: أغراضك محفوظة عند الموظف، ومعك أنت رقم الخزانة فقط.
الكوكيز: بيانات عند الزائر
Section titled “الكوكيز: بيانات عند الزائر”الكوكي قيمة نصية صغيرة يحفظها المتصفح، ويرسلها تلقائياً مع كل طلب للموقع نفسه. ننشئها بالدالة setcookie، ونقرؤها من المصفوفة $_COOKIE:
<?php$visits = (int) ($_COOKIE["visits"] ?? 0);$visits++;
setcookie("visits", (string) $visits, time() + 60 * 60 * 24 * 30);
echo "هذه زيارتك رقم $visits";افتح الصفحة ثم حدّثها عدة مرات:
هذه زيارتك رقم 1هذه زيارتك رقم 2هذه زيارتك رقم 3- في أول زيارة لا توجد كوكي بعد، فأعطى المعامل
??القيمة صفر. - المعامل الثالث هو وقت الانتهاء: الوقت الحالي
time()زائد عدد الثواني في ثلاثين يوماً. بدونه تُحذف الكوكي عند إغلاق المتصفح. - القيمة المقروءة نص دائماً، فحوّلناها بـ
(int).
الكوكيز مناسبة للتفضيلات البسيطة: اللغة، والوضع الليلي، وآخر صفحة زارها المستخدم. لكنها غير آمنة للبيانات المهمة: الزائر يستطيع أن يراها ويعدّلها من أدوات المتصفح. لا تكتب فيها أبداً شيئاً مثل is_admin=1.
الجلسات: بيانات عند الخادم
Section titled “الجلسات: بيانات عند الخادم”في الجلسة تبقى البيانات على الخادم، ولا يصل إلى المتصفح إلا كوكي واحدة فيها رقم عشوائي طويل يسمى معرّف الجلسة. لا يستطيع الزائر أن يغيّر ما في خزانته.
استخدامها سهل: استدعِ session_start() في أول الصفحة، ثم تعامل مع $_SESSION كأي مصفوفة:
<?phpsession_start();
$_SESSION["cart"] ??= [];
if (isset($_GET["add"])) { $_SESSION["cart"][] = $_GET["add"];}
echo "في السلة: " . count($_SESSION["cart"]) . " منتجات";افتح cart.php ثم cart.php?add=pen ثم cart.php?add=bag، وبعدها cart.php وحدها:
في السلة: 0 منتجاتفي السلة: 1 منتجاتفي السلة: 2 منتجاتفي السلة: 2 منتجاتالسلة احتفظت بمحتواها بين الطلبات. والمعامل ??= ينشئ السلة فارغة في أول مرة فقط.
| الكوكيز | الجلسات | |
|---|---|---|
| مكان التخزين | متصفح الزائر | الخادم |
| هل يستطيع الزائر تعديلها؟ | نعم | لا |
| مدة البقاء | حتى التاريخ الذي تحدده | حتى إغلاق المتصفح غالباً |
| مناسبة لـ | التفضيلات البسيطة | تسجيل الدخول والسلة |
مشروع: تسجيل الدخول والخروج
Section titled “مشروع: تسجيل الدخول والخروج”سنبني ثلاث صفحات. الأولى نموذج الدخول:
<?phpsession_start();
$error = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") { $username = trim($_POST["username"] ?? ""); $password = $_POST["password"] ?? "";
if ($username === "sara" && $password === "secret123") { session_regenerate_id(true); $_SESSION["user"] = $username; header("Location: dashboard.php"); exit; } $error = "اسم المستخدم أو كلمة السر غير صحيحة";}?><form method="post"> <input name="username" placeholder="اسم المستخدم"> <input name="password" type="password" placeholder="كلمة السر"> <button>دخول</button></form><p><?= htmlspecialchars($error) ?></p>إذا صحّت البيانات نحفظ اسم المستخدم في الجلسة، ثم نحوّله إلى الصفحة الخاصة بالدالة header، ونكتب بعدها exit حتى لا يكمل الكود تنفيذه. والدالة session_regenerate_id تغيّر معرّف الجلسة عند الدخول، وهذه حماية من نوع من الهجمات يسمى «تثبيت الجلسة».
الصفحة الثانية خاصة، لا يراها إلا من سجّل دخوله:
<?phpsession_start();
if (!isset($_SESSION["user"])) { header("Location: login.php"); exit;}
echo "أهلاً " . htmlspecialchars($_SESSION["user"]) . "! هذه صفحة خاصة.";هذه الأسطر في أعلى الصفحة هي الحارس: من ليس في جلسته مستخدم يُعاد إلى صفحة الدخول. ضعها في كل صفحة تريد حمايتها.
والثالثة للخروج:
<?phpsession_start();$_SESSION = [];session_destroy();
header("Location: login.php");exit;عند التجربة: فتح dashboard.php مباشرة يعيدك إلى صفحة الدخول. وكلمة سر خاطئة تعرض رسالة الخطأ. والبيانات الصحيحة تعرض:
أهلاً sara! هذه صفحة خاصة.وبعد زيارة logout.php تعود dashboard.php مغلقة من جديد.
جرّب بنفسك
Section titled “جرّب بنفسك”أنشئ صفحة theme.php فيها رابطان: «الوضع الليلي» و«الوضع الفاتح». عند الضغط على أحدهما احفظ الاختيار في كوكي اسمها theme لمدة سنة، واجعل لون خلفية الصفحة يتغير حسب قيمتها. أغلق المتصفح وافتحه من جديد، وتأكد أن الموقع ما زال يتذكر اختيارك.
تلميح: الرابطان يكونان theme.php?set=dark و theme.php?set=light، واقبل هاتين القيمتين فقط.
أخطاء شائعة
Section titled “أخطاء شائعة”- نسيان
session_start(): بدونها تكون$_SESSIONمصفوفة عادية تُنسى بنهاية الصفحة. استدعها في أول كل صفحة تستخدم الجلسة. - مخرجات قبل الترويسات: أي
echoأو حتى سطر فارغ قبل<?phpيمنعsetcookieوheaderوsession_startمن العمل. - نسيان
exitبعد التحويل:header("Location: ...")لا توقف الكود، فيكمل تنفيذ الصفحة الخاصة ويرسلها! - الثقة في الكوكيز: أي قيمة في
$_COOKIEكتبها المتصفح، وقد يكون الزائر عدّلها. عاملها مثل مدخلات النماذج.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
أين تُحفظ بيانات $_SESSION؟
بيانات الجلسة على الخادم، ولا يحمل المتصفح إلا كوكي فيها معرّف عشوائي يدل على جلسته.
سؤال
لماذا نكتب exit بعد header('Location: login.php')؟
الترويسة تطلب من المتصفح الانتقال، لكن PHP تكمل تنفيذ الملف ما لم توقفها بـ exit.
الخلاصة
Section titled “الخلاصة”- HTTP بلا ذاكرة، والكوكيز والجلسات تجعلان الموقع يتذكر زائره.
setcookieتحفظ قيمة عند الزائر، وتُقرأ من$_COOKIE، وهي للتفضيلات البسيطة.session_start()ثم$_SESSIONتحفظان البيانات على الخادم، وهي للبيانات المهمة.- حارس الصفحة: إذا لم يكن في الجلسة مستخدم، حوّله بـ
headerثمexit. - كلمات السر تُحفظ بـ
password_hashوتُفحص بـpassword_verify.