إدارة جلسات Webman

مثال

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        $name = $request->get('name');
        $session = $request->session();
        $session->set('name', $name);
        return response('hello ' . $session->get('name'));
    }
}

من خلال $request->session(); يمكنك الحصول على مثيل Workerman\Protocols\Http\Session، من خلال طرق المثيل يمكنك إضافة أو تعديل أو حذف بيانات الجلسة.

ملاحظة: سيتم حفظ بيانات الجلسة تلقائيًا عند تدمير كائن الجلسة، لذا لا تحتفظ بالكائن المعاد من $request->session() في مصفوفة عامة أو عضو في الصف مما يؤدي إلى عدم حفظ الجلسة.

الحصول على جميع بيانات الجلسة

$session = $request->session();
$all = $session->all();

تُرجع بيانات كمصفوفة. إذا لم تكن هناك أي بيانات جلسة، فستُرجع مصفوفة فارغة.

الحصول على قيمة معينة من الجلسة

$session = $request->session();
$name = $session->get('name');

إذا لم توجد البيانات، تُرجع القيمة null.

يمكنك أيضًا تمرير قيمة افتراضية كمعامل ثانٍ لطريقة get، إذا لم يتم العثور على القيمة المقابلة في مصفوفة الجلسة ستحصل على القيمة الافتراضية. على سبيل المثال:

$session = $request->session();
$name = $session->get('name', 'tom');

تخزين الجلسة

عند تخزين عنصر بيانات معين، استخدم طريقة set.

$session = $request->session();
$session->set('name', 'tom');

لا تُرجع set قيمة، وعند تدمير كائن الجلسة سيتم حفظ الجلسة تلقائيًا.

عند تخزين قيم متعددة، استخدم طريقة put.

$session = $request->session();
$session->put(['name' => 'tom', 'age' => 12]);

وبالمثل، لا تُرجع put أيضًا قيمة.

حذف بيانات الجلسة

لحذف قيمة أو أكثر من بيانات الجلسة، استخدم طريقة forget.

$session = $request->session();
// حذف عنصر واحد
$session->forget('name');
// حذف عناصر متعددة
$session->forget(['name', 'age']);

بالإضافة إلى ذلك، يوفر النظام طريقة delete، والفرق بينها وبين طريقة forget هو أن delete يمكن أن تحذف عنصرًا واحدًا فقط.

$session = $request->session();
// تعادل $session->forget('name');
$session->delete('name');

الحصول على قيمة معينة من الجلسة وحذفها

$session = $request->session();
$name = $session->pull('name');

هذا له نفس تأثير الكود أدناه

$session = $request->session();
$value = $session->get($name);
$session->delete($name);

إذا لم تكن الجلسة المقابلة موجودة، تُرجع القيمة null.

حذف جميع بيانات الجلسة

$request->session()->flush();

لا تُرجع قيمة، وعند تدمير كائن الجلسة ستُحذف الجلسة تلقائيًا من التخزين.

التحقق من وجود بيانات جلسة معينة

$session = $request->session();
$has = $session->has('name');

يرجع أعلاه false إذا كانت الجلسة المقابلة غير موجودة أو كانت قيمة الجلسة المقابلة null، وإلا فإنه يرجع true.

$session = $request->session();
$has = $session->exists('name');

الكود أعلاه يُستخدم أيضًا للتحقق مما إذا كانت بيانات الجلسة موجودة، والفرق هو أنه عندما تكون قيمة العنصر في الجلسة null، فإنه يرجع true أيضًا.

دالة المساعد session()

يوفر Webman دالة مساعد session() لإنجاز نفس الوظيفة.

// الحصول على مثيل الجلسة
$session = session();
// تعادل
$session = $request->session();

// الحصول على قيمة معينة
$value = session('key', 'default');
// تعادل
$value = session()->get('key', 'default');
// تعادل
$value = $request->session()->get('key', 'default');

// إعطاء القيمة للجلسة
session(['key1'=>'value1', 'key2' => 'value2']);
// تعادل
session()->put(['key1'=>'value1', 'key2' => 'value2']);
// تعادل
$request->session()->put(['key1'=>'value1', 'key2' => 'value2']);

ملف التكوين

ملف تكوين الجلسة موجود في config/session.php، والمحتوى يشبه ما يلي:

use Webman\Session\FileSessionHandler;
use Webman\Session\RedisSessionHandler;
use Webman\Session\RedisClusterSessionHandler;

return [
    // FileSessionHandler::class أو RedisSessionHandler::class أو RedisClusterSessionHandler::class 
    'handler' => FileSessionHandler::class,

    // عندما تكون handler FileSessionHandler::class القيمة file،
    // عندما تكون handler RedisSessionHandler::class القيمة redis
    // عندما تكون handler RedisClusterSessionHandler::class القيمة redis_cluster أي مجموعة Redis
    'type'    => 'file',

    // كل معالج يستخدم تكوين مختلف
    'config' => [
        // تكوين type file
        'file' => [
            'save_path' => runtime_path() . '/sessions',
        ],
        // تكوين type redis
        'redis' => [
            'host'      => '127.0.0.1',
            'port'      => 6379,
            'auth'      => '',
            'timeout'   => 2,
            'database'  => '',
            'prefix'    => 'redis_session_',
        ],
        'redis_cluster' => [
            'host'    => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'],
            'timeout' => 2,
            'auth'    => '',
            'prefix'  => 'redis_session_',
        ]

    ],

    'session_name' => 'PHPSID', // اسم الكوكي الذي يخزن session_id
    'auto_update_timestamp' => false,  // هل يتم تحديث الجلسة تلقائيًا، افتراضيًا مغلقة
    'lifetime' => 7*24*60*60,          // مدة انتهاء الجلسة
    'cookie_lifetime' => 365*24*60*60, // مدة انتهاء الكوكي الذي يخزن session_id
    'cookie_path' => '/',              // مسار الكوكي الذي يخزن session_id
    'domain' => '',                    // اسم المجال الذي يخزن session_id
    'http_only' => true,               // هل يتم تفعيل httpOnly، افتراضيًا مفعلة
    'secure' => false,                 // تفعيل الجلسة فقط عبر https، افتراضيًا مغلقة
    'same_site' => '',                 // لمنع هجمات CSRF وتتبع المستخدمين، القيم الاختيارية strict/lax/none
    'gc_probability' => [1, 1000],     // احتمال استرجاع الجلسة
];

الاعتبارات الأمنية

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