الفرق بين المراجعتين ل"Laravel/session"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
ط (استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}')
 
(5 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
سطر 1: سطر 1:
 
+
<noinclude>{{DISPLAYTITLE:الجلسات HTTP في Laravel}}</noinclude>
<noinclude>{{DISPLAYTITLE:الجلسات HTTP}}</noinclude>
 
 
 
 
== مقدّمة ==
 
== مقدّمة ==
توفر الجلسات طريقة لتخزين المعلومات حول المستخدم على عدّة طلبات نظرًا لأن التطبيقات المُعتمدة على HTTP بدون حالة. يأتي Laravel مع مجموعة متنوعة من الخلفيّات (backends) التي يمكن الوصول إليها عبر واجهة برمجية API تعبيرية موحّدة. كما يتضمّن دعم خلفيات شائعة مثل Memcached وRedis وقواعد البيانات خارج الأطر المألوفة.
+
توفر الجلسات طريقة لتخزين المعلومات حول المستخدم على عدّة طلبات نظرًا لأن التطبيقات المُعتمدة على HTTP بدون حالة. يأتي [[Laravel]] مع مجموعة متنوعة من الخلفيّات (backends) التي يمكن الوصول إليها عبر واجهة برمجية API تعبيرية موحّدة. كما يتضمّن دعم خلفيات شائعة مثل [[Memcached]] و<nowiki/>[[Redis]] وقواعد البيانات خارج الأطر المألوفة.
  
 
=== الضبط ===
 
=== الضبط ===
يُخزّن ملف إعدادات الجلسة في config/session.php. تأكد من مراجعة خياراتك المتاحة في هذا الملف. Laravel مُعد افتراضيًّا لاستخدام برنامج تشغيل (driver) الجلسة file الذي يعمل جيّدًا في العديد من التطبيقات. قد تفكر في تطبيقات الإنتاج في استخدام برامج التشغيل memcached أو redis للحصول على أداء جلسة أسرع.
+
يُخزّن ملف إعدادات الجلسة في <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:
  
 
==== مساعد الجلسة العام ====
 
==== مساعد الجلسة العام ====
تستطيع أيضًا استخدام الدالّة PHP session العامّة لاسترداد البيانات وتخزينها في الجلسة. سيرد المساعد session، عند مناداته بمتغيّر سلسلة نصيّة وسيط واحد، قيمة مفتاح تلك جلسة. عند مناداة المساعد مع مصفوفة من أزواج المفاتيح / القيم ستُخزّن تلك القيم في الجلسة:<syntaxhighlight lang="php">
+
تستطيع أيضًا استخدام الدالّة العامّة <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) إن كنت تستخدم LoginController؛ ولكن إن احتجت لإعادة إنشاء معرّف الجلسة يدويًا تستطيع استخدام التابع regenerate.<syntaxhighlight lang="php">
+
يعيد [[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، تستطيع استخدام التابع extend على الواجهة الساكنة Session. عليك بمناداة التابع extend من تابع موفّر الخدمات boot. تستطيع فعل بذلك من AppServiceProvider الموجود أو إنشاء موفّر خدمات جديد:<syntaxhighlight lang="php">
+
تستطيع تسجيل  برنامج تشغيلك في إطار العمل بمجرد تعريف استخدامه. لإضافة برامج تشغيل أخرى لخلفيّة جلسة [[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 بمجرد تسجيل برنامج تشغيل الجلسة.

مصادر