الفرق بين المراجعتين لصفحة: «Laravel/session»
تسنيم-ولهازي (نقاش | مساهمات) أنشأ الصفحة ب' == الجلسات HTTP == == مقدّمة == توفر الجلسات طريقة لتخزين المعلومات حول المستخدم على عدّة طلبات نظ...' |
رؤيا-بنعطية (نقاش | مساهمات) ط استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}' |
||
(6 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:الجلسات HTTP في Laravel}}</noinclude> | |||
== مقدّمة == | == مقدّمة == | ||
توفر الجلسات طريقة لتخزين المعلومات حول المستخدم على عدّة طلبات نظرًا لأن التطبيقات المُعتمدة على HTTP بدون حالة. يأتي Laravel مع مجموعة متنوعة من الخلفيّات (backends) التي يمكن الوصول إليها عبر واجهة برمجية API تعبيرية موحّدة. كما يتضمّن دعم خلفيات شائعة مثل Memcached | توفر الجلسات طريقة لتخزين المعلومات حول المستخدم على عدّة طلبات نظرًا لأن التطبيقات المُعتمدة على HTTP بدون حالة. يأتي [[Laravel]] مع مجموعة متنوعة من الخلفيّات (backends) التي يمكن الوصول إليها عبر واجهة برمجية API تعبيرية موحّدة. كما يتضمّن دعم خلفيات شائعة مثل [[Memcached]] و<nowiki/>[[Redis]] وقواعد البيانات خارج الأطر المألوفة. | ||
=== الضبط === | === الضبط === | ||
يُخزّن ملف إعدادات الجلسة في config/session.php. تأكد من مراجعة خياراتك المتاحة في هذا الملف. Laravel مُعد افتراضيًّا لاستخدام برنامج تشغيل (driver) الجلسة file الذي يعمل جيّدًا في العديد من التطبيقات. قد تفكر في تطبيقات الإنتاج في استخدام برامج التشغيل | يُخزّن ملف إعدادات الجلسة في <code>config/session.php</code>. تأكد من مراجعة خياراتك المتاحة في هذا الملف. [[Laravel]] مُعد افتراضيًّا لاستخدام برنامج تشغيل (driver) الجلسة file الذي يعمل جيّدًا في العديد من التطبيقات. قد تفكر في تطبيقات الإنتاج في استخدام برامج التشغيل [[Memcached]] أو [[Redis]] للحصول على أداء جلسة أسرع. | ||
يُعرّف خيار إعداد الجلسة driver مكان تخزين بيانات الجلسة لكل طلب. يأتي Laravel مع عدّة برامج تشغيل ممتازة خارج الأطر المألوفة: | يُعرّف خيار إعداد الجلسة driver مكان تخزين بيانات الجلسة لكل طلب. يأتي [[Laravel]] مع عدّة برامج تشغيل ممتازة خارج الأطر المألوفة: | ||
* file - تُخزّن الجلسات في storage/framework/sessions . | * file - تُخزّن الجلسات في storage/framework/sessions . | ||
* cookie - تُخزّن الجلسات في ملفات تعريف الارتباط آمنة ومشفّرة. | * cookie - تُخزّن الجلسات في ملفات تعريف الارتباط آمنة ومشفّرة. | ||
سطر 28: | سطر 26: | ||
}); | }); | ||
</syntaxhighlight>تستطيع استخدام الأمر session:table Artisan لتوليد هذا التهجير (migration):<syntaxhighlight lang="php"> | </syntaxhighlight>تستطيع استخدام الأمر <code>session:table Artisan</code> لتوليد هذا التهجير (migration):<syntaxhighlight lang="php"> | ||
php artisan session:table | php artisan session:table | ||
سطر 35: | سطر 33: | ||
==== Redis ==== | ==== Redis ==== | ||
ستحتاج إلى تثبيت الحزمة predis/predis (~ 1.0) عبر Composer قبل استخدام جلسات Redis مع Laravel. تستطيع إعداد اتصالات Redis في ملف الإعداد database. يمكن استخدام الخيار connection لتحديد أي اتصال Redis تستخدمه الجلسة في ملف الإعداد session. | ستحتاج إلى تثبيت الحزمة predis/predis (~ 1.0) عبر Composer قبل استخدام جلسات [[Redis]] مع [[Laravel]]. تستطيع إعداد اتصالات Redis في ملف الإعداد database. يمكن استخدام الخيار <code>connection</code> لتحديد أي اتصال Redis تستخدمه الجلسة في ملف الإعداد session. | ||
== استخدام الجلسة == | == استخدام الجلسة == | ||
=== استرداد البيانات === | === استرداد البيانات === | ||
توجد طريقتان أساسيّتان للعمل ببيانات الجلسات في Laravel: عبر المساعد session العام وعبر نسخة Request . فلنلقي نظرة أولًا على الوصول للجلسة عبر نسخة Request والتي يمكن التلميح على نوعها على تابع وحدة التحكّم. تذكر أنّ اعتماديّات تابع وحدة التحكّم تُضاف تلقائيًا عبر حاوي خدمات Laravel:<syntaxhighlight lang="php"> | توجد طريقتان أساسيّتان للعمل ببيانات الجلسات في [[Laravel]]: عبر المساعد <code>session</code> العام وعبر نسخة <code>Request</code> . فلنلقي نظرة أولًا على الوصول للجلسة عبر نسخة <code>Request</code> والتي يمكن التلميح على نوعها على تابع وحدة التحكّم. تذكر أنّ اعتماديّات تابع وحدة التحكّم تُضاف تلقائيًا عبر [[Laravel/container|حاوي خدمات]] Laravel:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 65: | سطر 63: | ||
} | } | ||
</syntaxhighlight>تستطيع عندما تسترد عنصرًا من الجلسة تمرير قيمة افتراضية كالمتغيّر الوسيط الثاني للتابع get. ستُرد هذه القيمة الافتراضية إن لم يوجد المفتاح المحدّد في الجلسة. إن مرّرت Closure كقيمة افتراضية للتابع get ولم يُعثر على المفتاح المطلوب سيُنفّذ Closure وترد نتيجته:<syntaxhighlight lang="php"> | </syntaxhighlight>تستطيع عندما تسترد عنصرًا من الجلسة تمرير قيمة افتراضية كالمتغيّر الوسيط الثاني للتابع <code>get</code>. ستُرد هذه القيمة الافتراضية إن لم يوجد المفتاح المحدّد في الجلسة. إن مرّرت Closure كقيمة افتراضية للتابع <code>get</code> ولم يُعثر على المفتاح المطلوب سيُنفّذ Closure وترد نتيجته:<syntaxhighlight lang="php"> | ||
$value = $request->session()->get('key', 'default'); | $value = $request->session()->get('key', 'default'); | ||
سطر 75: | سطر 73: | ||
==== مساعد الجلسة العام ==== | ==== مساعد الجلسة العام ==== | ||
تستطيع أيضًا استخدام الدالّة | تستطيع أيضًا استخدام الدالّة العامّة <code>session</code> لاسترداد البيانات وتخزينها في الجلسة. سيرد المساعد <code>session</code>، عند مناداته بمتغيّر سلسلة نصيّة وسيط واحد، قيمة مفتاح تلك جلسة. عند مناداة المساعد مع مصفوفة من أزواج المفاتيح / القيم ستُخزّن تلك القيم في الجلسة:<syntaxhighlight lang="php"> | ||
Route::get('home', function () { | Route::get('home', function () { | ||
// جلب قطعة بيانات من الجلسة... | // جلب قطعة بيانات من الجلسة... | ||
سطر 87: | سطر 85: | ||
}); | }); | ||
</syntaxhighlight>'''ملاحظة''': بالكاد يوجد أي اختلاف عملي بين استخدام الجلسة عبر نسخة طلب HTTP مقابل استخدام المساعد العام session. كلتا الطريقتين قابلتان للاختبار عبر التابع assertSessionHas المتوفر في جميع حالات اختبارك. | </syntaxhighlight>'''ملاحظة''': بالكاد يوجد أي اختلاف عملي بين استخدام الجلسة عبر نسخة طلب HTTP مقابل استخدام المساعد العام <code>session</code>. كلتا الطريقتين قابلتان للاختبار عبر التابع <code>assertSessionHas</code> المتوفر في جميع حالات اختبارك. | ||
==== استرداد جميع بيانات الجلسة ==== | ==== استرداد جميع بيانات الجلسة ==== | ||
إن رغبت في استرداد جميع بيانات الجلسة تستطيع استخدام التابع all:<syntaxhighlight lang="php"> | إن رغبت في استرداد جميع بيانات الجلسة تستطيع استخدام التابع <code>all</code>:<syntaxhighlight lang="php"> | ||
$data = $request->session()->all(); | $data = $request->session()->all(); | ||
سطر 96: | سطر 94: | ||
==== تحديد وجود عنصر في الجلسة ==== | ==== تحديد وجود عنصر في الجلسة ==== | ||
تستطيع استخدام التابع has لتحديد وجود عنصر في الجلسة. يرد التابع has القيمة true إن وجد العنصر ولم يكن فارغًا (null):<syntaxhighlight lang="php"> | تستطيع استخدام التابع <code>has</code> لتحديد وجود عنصر في الجلسة. يرد التابع <code>has</code> القيمة <code>true</code> إن وجد العنصر ولم يكن فارغًا (null):<syntaxhighlight lang="php"> | ||
if ($request->session()->has('users')) { | if ($request->session()->has('users')) { | ||
// | // | ||
} | } | ||
</syntaxhighlight>تستطيع استخدام التابع exists للتأكد من وجود العنصر في الجلسة حتى إن كانت قيمته null. يعيد التابع exists القيمة true إذا كان العنصر موجودًا:<syntaxhighlight lang="php"> | </syntaxhighlight>تستطيع استخدام التابع <code>exists</code> للتأكد من وجود العنصر في الجلسة حتى إن كانت قيمته <code>null</code>. يعيد التابع <code>exists</code> القيمة <code>true</code> إذا كان العنصر موجودًا:<syntaxhighlight lang="php"> | ||
if ($request->session()->exists('users')) { | if ($request->session()->exists('users')) { | ||
// | // | ||
سطر 108: | سطر 106: | ||
=== تخزين البيانات === | === تخزين البيانات === | ||
ستستخدم عادةً التابع put أو المساعد session لتخزين البيانات في الجلسة:<syntaxhighlight lang="php"> | ستستخدم عادةً التابع <code>put</code> أو المساعد session لتخزين البيانات في الجلسة:<syntaxhighlight lang="php"> | ||
// عبر نسخة طلب... | // عبر نسخة طلب... | ||
$request->session()->put('key', 'value'); | $request->session()->put('key', 'value'); | ||
سطر 118: | سطر 116: | ||
==== إضافة العناصر إلى مصفوفة الجلسة (Pushing To Array Session Values) ==== | ==== إضافة العناصر إلى مصفوفة الجلسة (Pushing To Array Session Values) ==== | ||
يمكن استخدام التابع push لدفع قيمة جديدة على قيمة جلسة مصفوفة. إن احتوى المفتاح user.teams مثلًا مصفوفة من أسماء الفرق تستطيع دفع قيمة جديدة لداخل المصفوفة كما يلي:<syntaxhighlight lang="php"> | يمكن استخدام التابع <code>push</code> لدفع قيمة جديدة على قيمة جلسة مصفوفة. إن احتوى المفتاح <code>user.teams</code> مثلًا مصفوفة من أسماء الفرق تستطيع دفع قيمة جديدة لداخل المصفوفة كما يلي:<syntaxhighlight lang="php"> | ||
$request->session()->push('user.teams', 'developers'); | $request->session()->push('user.teams', 'developers'); | ||
سطر 125: | سطر 123: | ||
==== استرداد وحذف عنصر ==== | ==== استرداد وحذف عنصر ==== | ||
سيستردَ التابع pull ويحذف العنصر من الجلسة بسطر برمجي واحد:<syntaxhighlight lang="php"> | سيستردَ التابع <code>pull</code> ويحذف العنصر من الجلسة بسطر برمجي واحد:<syntaxhighlight lang="php"> | ||
$value = $request->session()->pull('key', 'default'); | $value = $request->session()->pull('key', 'default'); | ||
سطر 131: | سطر 129: | ||
=== تمويض البيانات (Flash Data) === | === تمويض البيانات (Flash Data) === | ||
قد ترغب أحيانًا في تخزين العناصر في الجلسة لكن للطلب التالي فقط. يمكنك ذلك باستخدام التابع flash . ستُتاح البيانات المخزنة في الجلسة باستخدام هذا التابع فقط أثناء الطلب HTTP التالي وتُحذف بعد ذلك. تفيدنا بيانات Flash بصفة عامّة برسائل الحالة قصيرة الأمد:<syntaxhighlight lang="php"> | قد ترغب أحيانًا في تخزين العناصر في الجلسة لكن للطلب التالي فقط. يمكنك ذلك باستخدام التابع <code>flash</code> . ستُتاح البيانات المخزنة في الجلسة باستخدام هذا التابع فقط أثناء الطلب HTTP التالي وتُحذف بعد ذلك. تفيدنا بيانات <code>Flash</code> بصفة عامّة برسائل الحالة قصيرة الأمد:<syntaxhighlight lang="php"> | ||
$request->session()->flash('status', 'Task was successful!'); | $request->session()->flash('status', 'Task was successful!'); | ||
</syntaxhighlight>إن احتجت للاحتفاظ ببياناتك المموّضة (Flash) لعدة طلبات، تستطيع استخدام التابع reflash الذي سيحتفظ بجميع بيانات Flash لطلب إضافي. إذا احتجت فقط للاحتفاظ ببيانات Flash محددة، تستطيع استخدام التابع keep:<syntaxhighlight lang="php"> | </syntaxhighlight>إن احتجت للاحتفاظ ببياناتك المموّضة (Flash) لعدة طلبات، تستطيع استخدام التابع <code>reflash</code> الذي سيحتفظ بجميع بيانات Flash لطلب إضافي. إذا احتجت فقط للاحتفاظ ببيانات Flash محددة، تستطيع استخدام التابع <code>keep</code>:<syntaxhighlight lang="php"> | ||
$request->session()->reflash(); | $request->session()->reflash(); | ||
سطر 142: | سطر 140: | ||
=== حذف البيانات === | === حذف البيانات === | ||
سيحذف التابع forget جزءًا من البيانات من الجلسة. تستطيع استخدام التابع flush إن رغبت في إزالة جميع البيانات من الجلسة:<syntaxhighlight lang="php"> | سيحذف التابع <code>forget</code> جزءًا من البيانات من الجلسة. تستطيع استخدام التابع <code>flush</code> إن رغبت في إزالة جميع البيانات من الجلسة:<syntaxhighlight lang="php"> | ||
$request->session()->forget('key'); | $request->session()->forget('key'); | ||
سطر 151: | سطر 149: | ||
=== تجديد مُعرّف الجلسة (Regenerating The Session ID) === | === تجديد مُعرّف الجلسة (Regenerating The Session ID) === | ||
غالبًا ما يُجدّد مُعرّف الجلسة لمنع المستخدمين الخبثاء من استغلال هجوم تثبيت جلسة (session fixation) ضد تطبيقك. | غالبًا ما يُجدّد مُعرّف الجلسة لمنع المستخدمين الخبثاء من استغلال هجوم تثبيت جلسة (session fixation) ضد تطبيقك. | ||
يعيد Laravel إنشاء معرّف الجلسة تلقائيًا أثناء الاستيثاق (authentication) إن كنت تستخدم | يعيد [[Laravel]] إنشاء معرّف الجلسة تلقائيًا أثناء الاستيثاق (authentication) إن كنت تستخدم <code>LoginController</code>؛ ولكن إن احتجت لإعادة إنشاء معرّف الجلسة يدويًا تستطيع استخدام التابع <code>regenerate</code>.<syntaxhighlight lang="php"> | ||
$request->session()->regenerate(); | $request->session()->regenerate(); | ||
سطر 159: | سطر 157: | ||
=== تعريف استخدام برنامج تشغيل === | === تعريف استخدام برنامج تشغيل === | ||
يجب أن يُعرّف برنامج تشغيل جلستك المخصّص استخدام SessionHandlerInterface . تحتوي هذه الواجهة على بعض التوابع البسيطة التي نحتاج لتعريف استخدامها. تبدو بذرة تطبيق MongoDB هكذا:<syntaxhighlight lang="php"> | يجب أن يُعرّف برنامج تشغيل جلستك المخصّص استخدام <code>SessionHandlerInterface</code> . تحتوي هذه الواجهة على بعض التوابع البسيطة التي نحتاج لتعريف استخدامها. تبدو بذرة تطبيق [[MongoDB]] هكذا:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 174: | سطر 172: | ||
} | } | ||
</syntaxhighlight>'''ملاحظة''': لا يأتي Laravel مصحوبًا بمجلّد يحتوي على إضافاتك. أنت حر في وضعها في أي مكان تريده. أنشأنا في هذا المثال مجلّد Extensions لإيواء MongoSessionHandler. | </syntaxhighlight>'''ملاحظة''': لا يأتي [[Laravel]] مصحوبًا بمجلّد يحتوي على إضافاتك. أنت حر في وضعها في أي مكان تريده. أنشأنا في هذا المثال مجلّد Extensions لإيواء MongoSessionHandler. | ||
بما أنّ الغرض من هذه التوابع ليس بديهيَّ الفهم، دعنا نغطي بسرعة ما يفعله كل تابع منها: | بما أنّ الغرض من هذه التوابع ليس بديهيَّ الفهم، دعنا نغطي بسرعة ما يفعله كل تابع منها: | ||
* عادةً ما يُستخدم التابع open في أنظمة تخزين الجلسات القائمة على الملفات. لن تحتاج أبدًا تقريبًا لوضع أي شيء في هذا التابع نظرًا لأن Laravel يُشحن مع برنامج تشغيل جلسة file. تستطيع تركها كبذرة فارغة. في الواقع اشتراط تعريف استخدام هذا التابع نابع من ضعف تصميم واجهة PHP (الذي سنناقشه لاحقًا) | * عادةً ما يُستخدم التابع <code>open</code> في أنظمة تخزين الجلسات القائمة على الملفات. لن تحتاج أبدًا تقريبًا لوضع أي شيء في هذا التابع نظرًا لأن Laravel يُشحن مع برنامج تشغيل جلسة file. تستطيع تركها كبذرة فارغة. في الواقع اشتراط تعريف استخدام هذا التابع نابع من ضعف تصميم واجهة PHP (الذي سنناقشه لاحقًا) | ||
* يمكن عادةً تجاهل التابع close مثل التابع open. فلا حاجة إليه بالنسبة لمعظم برامج التشغيل. | * يمكن عادةً تجاهل التابع <code>close</code> مثل التابع <code>open</code>. فلا حاجة إليه بالنسبة لمعظم برامج التشغيل. | ||
* يجب أن يرد التابع read نسخة السلسلة نصيّة لبيانات الجلسة المرتبطة بالمتغيّر $sessionId. لا داعي لأي سَلسَلة (serialization) أو ترميز (encoding) عند استرداد أو تخزين بيانات الجلسات في برنامج تشغيلك بما أنّ Laravel سيهتّم بالسلسلة مكانك. | * يجب أن يرد التابع <code>read</code> نسخة السلسلة نصيّة لبيانات الجلسة المرتبطة بالمتغيّر <code>$sessionId</code>. لا داعي لأي سَلسَلة (serialization) أو ترميز (encoding) عند استرداد أو تخزين بيانات الجلسات في برنامج تشغيلك بما أنّ [[Laravel]] سيهتّم بالسلسلة مكانك. | ||
* يجب أن يكتب التابع write السلسلة النصيّة $data المحدّدة المرتبطة بـالمتغيّر $sessionId بنظام تخزين مستمر (persistent storage) مثل MongoDB أو Dynamo إلخ. للتذكير مجددًّا لا ينبغي أن تُسلسل أي شيء - بما أن Laravel يهتم بذلك بدلًا منك. | * يجب أن يكتب التابع write السلسلة النصيّة $data المحدّدة المرتبطة بـالمتغيّر <code>$sessionId</code> بنظام تخزين مستمر (persistent storage) مثل [[MongoDB]] أو [[Dynamo]] إلخ. للتذكير مجددًّا لا ينبغي أن تُسلسل أي شيء - بما أن [[Laravel]] يهتم بذلك بدلًا منك. | ||
* يجب أن يحذف التابع destroy البيانات المرتبطة بـالمتغيّر $sessionId من التخزين الدائم. | * يجب أن يحذف التابع <code>destroy</code> البيانات المرتبطة بـالمتغيّر <code>$sessionId</code> من التخزين الدائم. | ||
* يجب أن يدمّر التابع gc كافة بيانات الجلسة الأقدم من المدّة $lifetime المحدّدة وهي طابع زمني UNIX. بالنسبة للأنظمة التي تُنهي صلاحيتها (self-expiring) مثل Memcached و Redis ، يمكن ترك هذا التابع فارغًا. | * يجب أن يدمّر التابع gc كافة بيانات الجلسة الأقدم من المدّة <code>$lifetime</code> المحدّدة وهي طابع زمني UNIX. بالنسبة للأنظمة التي تُنهي صلاحيتها (self-expiring) مثل [[Memcached]] و [[Redis]] ، يمكن ترك هذا التابع فارغًا. | ||
==== تسجيل برنامج التشغيل ==== | ==== تسجيل برنامج التشغيل ==== | ||
تستطيع تسجيل برنامج تشغيلك في إطار العمل بمجرد تعريف استخدامه. لإضافة برامج تشغيل أخرى لخلفيّة جلسة | تستطيع تسجيل برنامج تشغيلك في إطار العمل بمجرد تعريف استخدامه. لإضافة برامج تشغيل أخرى لخلفيّة جلسة [[Laravel]]، تستطيع استخدام التابع <code>extend</code> على الواجهة الساكنة Session. عليك بمناداة التابع <code>extend</code> من تابع موفّر الخدمات <code>boot</code>. تستطيع فعل بذلك من <code>AppServiceProvider</code> الموجود أو إنشاء موفّر خدمات جديد:<syntaxhighlight lang="php"> | ||
<?php | <?php | ||
سطر 220: | سطر 218: | ||
} | } | ||
</syntaxhighlight>تستطيع استخدام برنامج التشغيل mongo بملف إعدادك config/session.php بمجرد تسجيل برنامج تشغيل الجلسة. | </syntaxhighlight>تستطيع استخدام برنامج التشغيل mongo بملف إعدادك <code>config/session.php</code> بمجرد تسجيل برنامج تشغيل الجلسة. | ||
== مصادر == | == مصادر == | ||
* [https://laravel.com/docs/5.6/session صفحة HTTP session في توثيق Laravel الرسمي.] | * [https://laravel.com/docs/5.6/session صفحة HTTP session في توثيق Laravel الرسمي.] | ||
[[تصنيف:Laravel|{{SUBPAGENAME}}]] | |||
[[تصنيف:Laravel Basics|{{SUBPAGENAME}}]] |
المراجعة الحالية بتاريخ 13:22، 23 أكتوبر 2018
مقدّمة
توفر الجلسات طريقة لتخزين المعلومات حول المستخدم على عدّة طلبات نظرًا لأن التطبيقات المُعتمدة على HTTP بدون حالة. يأتي Laravel مع مجموعة متنوعة من الخلفيّات (backends) التي يمكن الوصول إليها عبر واجهة برمجية API تعبيرية موحّدة. كما يتضمّن دعم خلفيات شائعة مثل Memcached وRedis وقواعد البيانات خارج الأطر المألوفة.
الضبط
يُخزّن ملف إعدادات الجلسة في config/session.php
. تأكد من مراجعة خياراتك المتاحة في هذا الملف. Laravel مُعد افتراضيًّا لاستخدام برنامج تشغيل (driver) الجلسة file الذي يعمل جيّدًا في العديد من التطبيقات. قد تفكر في تطبيقات الإنتاج في استخدام برامج التشغيل Memcached أو Redis للحصول على أداء جلسة أسرع.
يُعرّف خيار إعداد الجلسة driver مكان تخزين بيانات الجلسة لكل طلب. يأتي Laravel مع عدّة برامج تشغيل ممتازة خارج الأطر المألوفة:
- file - تُخزّن الجلسات في storage/framework/sessions .
- cookie - تُخزّن الجلسات في ملفات تعريف الارتباط آمنة ومشفّرة.
- database - تُخزّن الجلسات في قاعدة بيانات علائقية.
- memcached / redis - تُخزّن الجلسات في إحدى هذه المخازن السريعة القائمة على ذاكرة التخزين المؤقت.
- array - تُخزّن الجلسات في مصفوفة PHP ولن تستمر.
يُستخدم برنامج تشغيل المصفوفة أثناء الاختبار ويمنع استمرار تخزين البيانات المخزّنة في الجلسة.
متطلبات المُشغّل
قاعدة البيانات
ستحتاج لإنشاء جدول لاحتواء عناصر الجلسة عند استخدام برنامج تشغيل قاعدة بيانات الجلسة. في ما يلي مثال عن تصريح Schema للجدول:
Schema::create('sessions', function ($table) {
$table->string('id')->unique();
$table->unsignedInteger('user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('payload');
$table->integer('last_activity');
});
تستطيع استخدام الأمر session:table Artisan
لتوليد هذا التهجير (migration):
php artisan session:table
php artisan migrate
Redis
ستحتاج إلى تثبيت الحزمة predis/predis (~ 1.0) عبر Composer قبل استخدام جلسات Redis مع Laravel. تستطيع إعداد اتصالات Redis في ملف الإعداد database. يمكن استخدام الخيار connection
لتحديد أي اتصال Redis تستخدمه الجلسة في ملف الإعداد session.
استخدام الجلسة
استرداد البيانات
توجد طريقتان أساسيّتان للعمل ببيانات الجلسات في Laravel: عبر المساعد session
العام وعبر نسخة Request
. فلنلقي نظرة أولًا على الوصول للجلسة عبر نسخة Request
والتي يمكن التلميح على نوعها على تابع وحدة التحكّم. تذكر أنّ اعتماديّات تابع وحدة التحكّم تُضاف تلقائيًا عبر حاوي خدمات Laravel:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* عرض ملف المستخدم المحدّد الشخصي .
*
* @param Request $request
* @param int $id
* @return Response
*/
public function show(Request $request, $id)
{
$value = $request->session()->get('key');
//
}
}
تستطيع عندما تسترد عنصرًا من الجلسة تمرير قيمة افتراضية كالمتغيّر الوسيط الثاني للتابع get
. ستُرد هذه القيمة الافتراضية إن لم يوجد المفتاح المحدّد في الجلسة. إن مرّرت Closure كقيمة افتراضية للتابع get
ولم يُعثر على المفتاح المطلوب سيُنفّذ Closure وترد نتيجته:
$value = $request->session()->get('key', 'default');
$value = $request->session()->get('key', function () {
return 'default';
});
مساعد الجلسة العام
تستطيع أيضًا استخدام الدالّة العامّة session
لاسترداد البيانات وتخزينها في الجلسة. سيرد المساعد session
، عند مناداته بمتغيّر سلسلة نصيّة وسيط واحد، قيمة مفتاح تلك جلسة. عند مناداة المساعد مع مصفوفة من أزواج المفاتيح / القيم ستُخزّن تلك القيم في الجلسة:
Route::get('home', function () {
// جلب قطعة بيانات من الجلسة...
$value = session('key');
//تحديد قيمة افتراضيّة...
$value = session('key', 'default');
// تخزين جزء البيانات في الجلسة...
session(['key' => 'value']);
});
ملاحظة: بالكاد يوجد أي اختلاف عملي بين استخدام الجلسة عبر نسخة طلب HTTP مقابل استخدام المساعد العام session
. كلتا الطريقتين قابلتان للاختبار عبر التابع assertSessionHas
المتوفر في جميع حالات اختبارك.
استرداد جميع بيانات الجلسة
إن رغبت في استرداد جميع بيانات الجلسة تستطيع استخدام التابع all
:
$data = $request->session()->all();
تحديد وجود عنصر في الجلسة
تستطيع استخدام التابع has
لتحديد وجود عنصر في الجلسة. يرد التابع has
القيمة true
إن وجد العنصر ولم يكن فارغًا (null):
if ($request->session()->has('users')) {
//
}
تستطيع استخدام التابع exists
للتأكد من وجود العنصر في الجلسة حتى إن كانت قيمته null
. يعيد التابع exists
القيمة true
إذا كان العنصر موجودًا:
if ($request->session()->exists('users')) {
//
}
تخزين البيانات
ستستخدم عادةً التابع put
أو المساعد session لتخزين البيانات في الجلسة:
// عبر نسخة طلب...
$request->session()->put('key', 'value');
//عبر مساعد عام...
session(['key' => 'value']);
إضافة العناصر إلى مصفوفة الجلسة (Pushing To Array Session Values)
يمكن استخدام التابع push
لدفع قيمة جديدة على قيمة جلسة مصفوفة. إن احتوى المفتاح user.teams
مثلًا مصفوفة من أسماء الفرق تستطيع دفع قيمة جديدة لداخل المصفوفة كما يلي:
$request->session()->push('user.teams', 'developers');
استرداد وحذف عنصر
سيستردَ التابع pull
ويحذف العنصر من الجلسة بسطر برمجي واحد:
$value = $request->session()->pull('key', 'default');
تمويض البيانات (Flash Data)
قد ترغب أحيانًا في تخزين العناصر في الجلسة لكن للطلب التالي فقط. يمكنك ذلك باستخدام التابع flash
. ستُتاح البيانات المخزنة في الجلسة باستخدام هذا التابع فقط أثناء الطلب HTTP التالي وتُحذف بعد ذلك. تفيدنا بيانات Flash
بصفة عامّة برسائل الحالة قصيرة الأمد:
$request->session()->flash('status', 'Task was successful!');
إن احتجت للاحتفاظ ببياناتك المموّضة (Flash) لعدة طلبات، تستطيع استخدام التابع reflash
الذي سيحتفظ بجميع بيانات Flash لطلب إضافي. إذا احتجت فقط للاحتفاظ ببيانات Flash محددة، تستطيع استخدام التابع keep
:
$request->session()->reflash();
$request->session()->keep(['username', 'email']);
حذف البيانات
سيحذف التابع forget
جزءًا من البيانات من الجلسة. تستطيع استخدام التابع flush
إن رغبت في إزالة جميع البيانات من الجلسة:
$request->session()->forget('key');
$request->session()->flush();
تجديد مُعرّف الجلسة (Regenerating The Session ID)
غالبًا ما يُجدّد مُعرّف الجلسة لمنع المستخدمين الخبثاء من استغلال هجوم تثبيت جلسة (session fixation) ضد تطبيقك.
يعيد Laravel إنشاء معرّف الجلسة تلقائيًا أثناء الاستيثاق (authentication) إن كنت تستخدم LoginController
؛ ولكن إن احتجت لإعادة إنشاء معرّف الجلسة يدويًا تستطيع استخدام التابع regenerate
.
$request->session()->regenerate();
إضافة برامج تشغيل جلسة مخصّصة
تعريف استخدام برنامج تشغيل
يجب أن يُعرّف برنامج تشغيل جلستك المخصّص استخدام SessionHandlerInterface
. تحتوي هذه الواجهة على بعض التوابع البسيطة التي نحتاج لتعريف استخدامها. تبدو بذرة تطبيق MongoDB هكذا:
<?php
namespace App\Extensions;
class MongoSessionHandler implements \SessionHandlerInterface
{
public function open($savePath, $sessionName) {}
public function close() {}
public function read($sessionId) {}
public function write($sessionId, $data) {}
public function destroy($sessionId) {}
public function gc($lifetime) {}
}
ملاحظة: لا يأتي Laravel مصحوبًا بمجلّد يحتوي على إضافاتك. أنت حر في وضعها في أي مكان تريده. أنشأنا في هذا المثال مجلّد Extensions لإيواء MongoSessionHandler.
بما أنّ الغرض من هذه التوابع ليس بديهيَّ الفهم، دعنا نغطي بسرعة ما يفعله كل تابع منها:
- عادةً ما يُستخدم التابع
open
في أنظمة تخزين الجلسات القائمة على الملفات. لن تحتاج أبدًا تقريبًا لوضع أي شيء في هذا التابع نظرًا لأن Laravel يُشحن مع برنامج تشغيل جلسة file. تستطيع تركها كبذرة فارغة. في الواقع اشتراط تعريف استخدام هذا التابع نابع من ضعف تصميم واجهة PHP (الذي سنناقشه لاحقًا) - يمكن عادةً تجاهل التابع
close
مثل التابعopen
. فلا حاجة إليه بالنسبة لمعظم برامج التشغيل. - يجب أن يرد التابع
read
نسخة السلسلة نصيّة لبيانات الجلسة المرتبطة بالمتغيّر $sessionId
. لا داعي لأي سَلسَلة (serialization) أو ترميز (encoding) عند استرداد أو تخزين بيانات الجلسات في برنامج تشغيلك بما أنّ Laravel سيهتّم بالسلسلة مكانك. - يجب أن يكتب التابع write السلسلة النصيّة $data المحدّدة المرتبطة بـالمتغيّر
$sessionId
بنظام تخزين مستمر (persistent storage) مثل MongoDB أو Dynamo إلخ. للتذكير مجددًّا لا ينبغي أن تُسلسل أي شيء - بما أن Laravel يهتم بذلك بدلًا منك. - يجب أن يحذف التابع
destroy
البيانات المرتبطة بـالمتغيّر $sessionId
من التخزين الدائم. - يجب أن يدمّر التابع gc كافة بيانات الجلسة الأقدم من المدّة
$lifetime
المحدّدة وهي طابع زمني UNIX. بالنسبة للأنظمة التي تُنهي صلاحيتها (self-expiring) مثل Memcached و Redis ، يمكن ترك هذا التابع فارغًا.
تسجيل برنامج التشغيل
تستطيع تسجيل برنامج تشغيلك في إطار العمل بمجرد تعريف استخدامه. لإضافة برامج تشغيل أخرى لخلفيّة جلسة Laravel، تستطيع استخدام التابع extend
على الواجهة الساكنة Session. عليك بمناداة التابع extend
من تابع موفّر الخدمات boot
. تستطيع فعل بذلك من AppServiceProvider
الموجود أو إنشاء موفّر خدمات جديد:
<?php
namespace App\Providers;
use App\Extensions\MongoSessionHandler;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
/**
* إجراء تمهيد الخدمات ما بعد التسجيل.
*
* @return void
*/
public function boot()
{
Session::extend('mongo', function ($app) {
// Return implementation of SessionHandlerInterface...
return new MongoSessionHandler;
});
}
/**
* تسجيل الارتباطات في موفّر الخدمات.
*
* @return void
*/
public function register()
{
//
}
}
تستطيع استخدام برنامج التشغيل mongo بملف إعدادك config/session.php
بمجرد تسجيل برنامج تشغيل الجلسة.