الجلسات ونظام تسجيل الدخول

تُخزّن ملفات الكوكيز البيانات في متصفح المستخدم؛ بينما تُخزّن الجلسات هذه البيانات على الخادم. حالة تسجيل الدخول، وعربات التسوق، وعلامات الأذونات — أي بيانات لا تريد أن يلمسها المستخدم يجب أن تُخزَّن في جلسة. وبحلول نهاية هذا الدرس، ستكون قد أنشأت نظام تسجيل الدخول الأول الخاص بك.

1. ما هي الجلسة؟

الجلسة هي مساحة تخزين خاصة على الخادم يتم إنشاؤها لكل مستخدم. لا يحتفظ المتصفح سوى بملف تعريف ارتباط يحتوي على معرّف الجلسة؛ أما جميع البيانات الفعلية فتبقى على جانب الخادم:

TEXT
Cookie:                          Session:
Only holds the Session ID        Stores the actual data (username, role, cart...)
┌──────────────┐                ┌──────────────────────┐
│ PHPSESSID    │  ──match──→   │ user: John            │
│ abc123       │                │ login: true           │
└──────────────┘                │ cart: [3 items]       │
   In the browser               │ role: admin           │
                                └──────────────────────┘
                                     On the server
💡 نصيحة: الجلسة مقابل ملفات تعريف الارتباط: تُخزَّن ملفات تعريف الارتباط في المتصفح (حيث يمكن للمستخدم رؤيتها وتعديلها)؛ بينما تُخزَّن الجلسات على الخادم (وهي آمنة). لكن الجلسات تعتمد على ملفات تعريف الارتباط لنقل معرّف الجلسة — فإذا قام المستخدم بحظر ملفات تعريف الارتباط، تنقطع الجلسات.


2. session_start() — بدء جلسة

يجب عليك استدعاء session_start() قبل استخدام أي وظيفة متعلقة بالجلسة. ويقوم هذا الاستدعاء بأمرين:

  1. إذا أرسل المتصفح ملف تعريف ارتباط معرّف الجلسة → قم بتحميل البيانات المقابلة من الخادم
  2. إذا لم يتم العثور على ملف تعريف ارتباط → إنشاء جلسة جديدة، وإنشاء معرّف جديد، وإرسال ملف تعريف ارتباط
PHP
<?php
// session_start() must come before any HTML output
session_start();

// Store data
$_SESSION['username'] = "John";
$_SESSION['login_time'] = date("Y-m-d H:i:s");

// Read data
echo "Welcome, {$_SESSION['username']}!";
echo "Logged in at: {$_SESSION['login_time']}";
?>
🔥 خطأ شائع: يجب استدعاء session_start() قبل أي إخراج — سواء كان ذلك عبر الأمر echo أو كود HTML الخام، أو حتى مسافة زائدة قبل علامة <?php. وإلا فستواجه الخطأ المزعج headers already sent. ضعه في أعلى الملف مباشرةً.


3. $_SESSION — استخدمه كأي مصفوفة

PHP
<?php
session_start();

// Store any PHP data type
$_SESSION['user'] = [
    'id'   => 101,
    'name' => 'John',
    'role' => 'member'
];
$_SESSION['cart'] = [
    ['name' => 'PHP Tutorial', 'price' => 39.90, 'qty' => 2],
    ['name' => 'MySQL Basics', 'price' => 29.90, 'qty' => 1],
];

// Read
echo $_SESSION['user']['name'];  // John

// Remove a single session variable
unset($_SESSION['cart']);

// Update
$_SESSION['user']['role'] = 'admin';
?>

▶ مثال: عربة التسوق التي تعمل على أساس الجلسة

PHP
<?php
session_start();

// Initialize the cart
if (!isset($_SESSION['cart'])) {
    $_SESSION['cart'] = [];
}

// Add an item
if (isset($_POST['add'])) {
    $item = $_POST['add'];
    $_SESSION['cart'][$item] = ($_SESSION['cart'][$item] ?? 0) + 1;
}

echo "<h3>Your Cart</h3>";
foreach ($_SESSION['cart'] as $item => $qty) {
    echo "{$item} × {$qty}<br>";
}
?>
<form method='POST'>
    <button name='add' value='PHP Tutorial'>Add PHP Tutorial</button>
    <button name='add' value='MySQL Basics'>Add MySQL Basics</button>
</form>
▶ جرّب الكود

4. إنشاء نظام تسجيل الدخول

▶ مثال: نظام تسجيل دخول كامل

PHP
<?php
// login.php — Login System
session_start();

// Predefined test users (in a real project, these live in a database)
$users = [
    'admin' => '123456',
    'john' => 'password123',
];

$error = '';

// Already logged in? Redirect to profile
if (isset($_SESSION['user'])) {
    header("Location: profile.php");
    exit;
}

// Handle login request
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = trim($_POST['username'] ?? '');
    $password = $_POST['password'] ?? '';

    if (isset($users[$username]) && $users[$username] === $password) {
        // Credentials verified — store user in session
        $_SESSION['user'] = [
            'username'    => $username,
            'login_time'  => date("Y-m-d H:i:s"),
            'last_active' => time(),
        ];
        
        // Redirect to profile page
        header("Location: profile.php");
        exit;
    } else {
        $error = "Invalid username or password";
    }
}
?>

<h3>Login</h3>
<?php if ($error): ?>
    <p style="color:red"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>

<form method="POST" action="">
    <p>
        <label>Username:</label>
        <input type="text" name="username" required>
    </p>
    <p>
        <label>Password:</label>
        <input type="password" name="password" required>
    </p>
    <button type="submit">Log In</button>
</form>
<p style="color:#888">Test account: admin / 123456</p>
▶ جرّب الكود
PHP
<?php
// profile.php — Profile Page (requires login)
session_start();

// Not logged in? Redirect to login
if (!isset($_SESSION['user'])) {
    header("Location: login.php");
    exit;
}

$user = $_SESSION['user'];
?>

<h2>Profile</h2>
<p>Username: <?= htmlspecialchars($user['username']) ?></p>
<p>Logged in at: <?= $user['login_time'] ?></p>

<a href="logout.php">Log Out</a>

(1) تسجيل الخروج

PHP
<?php
// logout.php
session_start();

// Option 1: Clear only the user data
unset($_SESSION['user']);

// Option 2: Wipe the entire session
session_unset();    // Clear the $_SESSION array
session_destroy();  // Delete the server-side session file

// Redirect to login
header("Location: login.php");
exit;
?>
العملية الوظيفة ما الذي تفعله
إزالة عنصر واحد unset($_SESSION['key']) حذف مفتاح معين
مسح جميع المتغيرات session_unset() إفراغ $_SESSION
حذف ملف الجلسة session_destroy() يزيل بيانات الجلسة من جانب الخادم
حذف ملف تعريف الارتباط setcookie(session_name(), '', time()-3600, '/') يزيل ملف تعريف الارتباط PHPSESSID من المتصفح
💡 نصيحة: التسلسل القياسي لتسجيل الخروج: session_unset()session_destroy() → حذف ملف تعريف الارتباط PHPSESSID → إعادة التوجيه إلى صفحة تسجيل الدخول.


5. دورة حياة الجلسة

TEXT
User visits for the first time → PHP creates a session file (e.g., sess_abc123)
                ↓
          Data is written to $_SESSION
                ↓
          Cookie sent: PHPSESSID=abc123 to the browser
                ↓
Next visit → Browser sends PHPSESSID=abc123
                ↓
          PHP finds sess_abc123, loads data into $_SESSION
                ↓
... User leaves (closes browser or is idle for a long time) ...
                ↓
Garbage collection → Expired session files are deleted

تنتهي صلاحية الجلسات افتراضيًا بعد 24 دقيقة (session.gc_maxlifetime = 1440 ثانية في php.ini). ويبدأ العد من تاريخ آخر تعديل للملف، وليس من آخر نشاط للمستخدم.


6. تكوين أمان الجلسة

PHP
<?php
// Configure before session_start()
ini_set('session.cookie_httponly', 1);    // JS can't read the session cookie (XSS protection)
ini_set('session.cookie_secure', 1);      // HTTPS only (required for production)
ini_set('session.cookie_samesite', 'Lax'); // CSRF mitigation
ini_set('session.use_strict_mode', 1);    // Reject uninitialized session IDs

session_start();
?>
💡 نصيحة: يمنع session.use_strict_mode = 1 المهاجمين من اختلاق معرّف جلسة. فإذا اختلق المهاجم معرّفًا غير موجود، فإن PHP ترفضه وتقوم بإنشاء جلسة جديدة بدلاً من ذلك.


7. نظرة عامة على ملفات تعريف الارتباط مقابل جلسات التصفح

ملف تعريف الارتباط جلسة العمل
موقع البيانات متصفح المستخدم الخادم
الأمان منخفض (يمكن للمستخدم عرض البيانات وتعديلها) عالٍ (لا يرى المستخدم البيانات أبدًا)
السعة 4 كيلوبايت غير محدودة (تقتصر فقط على سعة قرص الخادم)
الأداء يتم إرساله مع كل طلب لا تتكبد تكلفة النطاق الترددي (البحث من جانب الخادم)
التبعية مستقل يعتمد على ملفات تعريف الارتباط (لمعرف الجلسة)
الأفضل لـ الإعدادات، الحالة الخفيفة تسجيل الدخول، الأذونات، عربات التسوق

❓ أسئلة شائعة

س هل تختفي الجلسة عند إغلاق المتصفح؟
ج تظل بيانات الجلسة موجودة على الخادم (في انتظار عملية إزالة البيانات غير الضرورية)، لكن ملف تعريف الارتباط PHPSESSID في المتصفح يختفي عادةً عند إغلاق المتصفح. وعند فتح المتصفح في المرة التالية، لن يكون هناك معرّف جلسة، لذا يقوم PHP بإنشاء جلسة جديدة تمامًا.
س إذا قام عدة مستخدمين بتسجيل الدخول في نفس الوقت، فهل تتداخل جلسات عملهم؟
ج لا. يحصل كل مستخدم على جلسة عمل خاصة به مع معرّف جلسة فريد. $_SESSION ينتمي دائمًا إلى المستخدم الحالي — ولا يحدث أي تداخل بين الجلسات.
س هل يمكن أن تعمل الجلسات إذا قام المستخدم بتعطيل ملفات تعريف الارتباط؟
ج لا، بشكل افتراضي، لأن معرّف الجلسة ينتقل عبر ملف تعريف الارتباط. يمكنك تمريره عبر عنوان URL (PHPSESSID=abc123)، لكن هذا غير آمن على الإطلاق — حيث ينتهي الأمر بمعرّف الجلسة في سجل المتصفح والإشارات المرجعية وسجلات الخادم.

📖 ملخص

📝 تمارين

  1. قم بنشر نظام تسجيل الدخول الكامل الوارد في الأمثلة أعلاه (login.php → profile.php → logout.php).
  2. إضافة ميزة «تغيير كلمة المرور» إلى صفحة الملف الشخصي (مع التحقق من صحة البيانات مقابل مصفوفة المستخدمين المحددة مسبقًا).
  3. تطبيق نظام وصول بسيط قائم على الأدوار: لا يمكن إلا للمستخدمين الذين يحملون role === 'admin' رؤية رابط «لوحة الإدارة» على الصفحة.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%