جلسه HTTP
معرفی
از آنجایی که برنامه های مبتنی بر HTTP بدون حالت هستند، جلسات راهی برای ذخیره اطلاعات کاربر در چندین درخواست ارائه می دهد. لاراول با انواع بکاندهای جلسه عرضه میشود که از طریق یک API بیانگر و یکپارچه قابل دسترسی هستند. پشتیبانی از بکاندهای محبوب مانند Memcached ، Redis ، و پایگاههای داده خارج از جعبه گنجانده شده است.
پیکربندی
فایل پیکربندی جلسه در ذخیره می شود
config/session.php
.
گزینه های موجود در این فایل را حتما بررسی کنید.
به طور پیش فرض، لاراول برای استفاده از
file
درایور جلسه پیکربندی شده است که برای بسیاری از برنامه ها به خوبی کار می
کند.
گزینه پیکربندی جلسه
driver
تعیین می کند که داده های جلسه برای هر درخواست کجا ذخیره شوند.
لاراول با چندین راننده بزرگ خارج از جعبه ارسال می شود:
-
file
- جلسات در ذخیره می شودstorage/framework/sessions
. -
cookie
- جلسات در کوکی های امن و رمزگذاری شده ذخیره می شوند. -
database
- جلسات در یک پایگاه داده رابطه ای ذخیره می شوند. -
memcached
/redis
- جلسات در یکی از این فروشگاه های سریع و مبتنی بر حافظه پنهان ذخیره می شوند. -
array
- جلسات در یک آرایه PHP ذخیره می شوند و ادامه نخواهند داشت.
درایور آرایه در طول تست استفاده می شود و از ماندگاری داده های ذخیره شده در جلسه جلوگیری می کند.
پیش نیاز راننده
پایگاه داده
هنگام استفاده از
database
درایور جلسه، باید جدولی ایجاد کنید که حاوی موارد جلسه باشد.
در زیر یک مثال
Schema
برای جدول آمده است:
Schema::create('sessions', function ($table) { $table->string('id')->unique(); $table->foreignId('user_id')->nullable(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->text('payload'); $table->integer('last_activity');});
می توانید از
session:table
دستور Artisan برای ایجاد این مهاجرت استفاده کنید:
php artisan session:table php artisan migrate
ردیس
قبل از استفاده از جلسات Redis با لاراول، باید افزونه PhpRedis PHP را از
طریق PECL نصب کنید یا
predis/predis
بسته (~1.0) را از طریق Composer نصب کنید.
برای اطلاعات بیشتر در مورد پیکربندی Redis، به
صفحه اسناد لاراول
آن مراجعه کنید .
در
session
فایل پیکربندی،connection
ممکن است از این گزینه برای تعیین اینکه کدام اتصال Redis توسط جلسه استفاده می شود استفاده شود.
با استفاده از The Session
بازیابی داده ها
دو روش اصلی برای کار با داده های جلسه در لاراول وجود دارد:
session
کمک کننده جهانی و از طریق یک
Request
نمونه.
ابتدا، اجازه دهید دسترسی به جلسه از طریق یک
Request
نمونه را بررسی کنیم، که میتوان آن را در روش کنترلکننده تایپ کرد.
به یاد داشته باشید که وابستگی های متد کنترلر به طور خودکار از طریق
ظرف سرویس
لاراول تزریق می شوند :
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use Illuminate\Http\Request; class UserController extends Controller{ /** * Show the profile for the given user. * * @param Request $request * @param int $id * @return Response */ public function show(Request $request, $id) { $value = $request->session()->get('key'); // }}
هنگامی که یک آیتم را از جلسه بازیابی می کنید، می توانید یک مقدار پیش فرض
را نیز به عنوان آرگومان دوم به
get
متد ارسال کنید.
اگر کلید مشخص شده در جلسه وجود نداشته باشد، این مقدار پیش فرض برگردانده
می شود.
Closure
اگر a را به عنوان مقدار پیش فرض به متد
ارسال کنید
get
و کلید درخواستی وجود نداشته باشد،
Closure
اجرا می شود و نتیجه آن برگردانده می شود:
$value = $request->session()->get('key', 'default'); $value = $request->session()->get('key', function () { return 'default';});
یاور جلسه جهانی
همچنین می توانید از
session
تابع جهانی PHP برای بازیابی و ذخیره داده ها در جلسه استفاده کنید.
هنگامی که
session
کمک کننده با یک آرگومان رشته ای فراخوانی می شود، مقدار آن کلید جلسه را
برمی گرداند.
هنگامی که کمک کننده با آرایه ای از جفت کلید / مقدار فراخوانی می شود، آن
مقادیر در جلسه ذخیره می شوند:
Route::get('home', function () { // Retrieve a piece of data from the session... $value = session('key'); // Specifying a default value... $value = session('key', 'default'); // Store a piece of data in the session... session(['key' => 'value']);});
تفاوت عملی کمی بین استفاده از جلسه از طریق یک نمونه درخواست HTTP در مقابل استفاده از
session
کمک کننده جهانی وجود دارد. هر دو روش از طریق روشی که در همه موارد آزمایشی شما موجود است قابل آزمایش هستند.assertSessionHas
بازیابی همه داده های جلسه
اگر می خواهید تمام داده های جلسه را بازیابی کنید، می توانید از
all
روش زیر استفاده کنید:
$data = $request->session()->all();
تعیین اینکه آیا یک مورد در جلسه وجود دارد یا خیر
برای تعیین اینکه آیا یک مورد در جلسه وجود دارد یا خیر، می توانید از
has
روش استفاده کنید.
اگر آیتم موجود باشد و نباشد،
متد
has
برمی گردد
:
true
null
if ($request->session()->has('users')) { //}
برای تعیین اینکه آیا یک آیتم در جلسه وجود دارد، حتی اگر مقدار آن باشد
null
، می توانید از
exists
روش استفاده کنید.
متد
در صورت وجود آیتم
exists
برمی گردد :
true
if ($request->session()->exists('users')) { //}
ذخیره سازی داده ها
برای ذخیره داده ها در جلسه، معمولاً از
put
روش یا
session
کمک کننده استفاده می کنید:
// Via a request instance...$request->session()->put('key', 'value'); // Via the global helper...session(['key' => 'value']);
فشار دادن به مقادیر جلسه آرایه
این
push
روش ممکن است برای فشار دادن یک مقدار جدید به یک مقدار جلسه که یک آرایه
است استفاده شود.
به عنوان مثال، اگر
user.teams
کلید حاوی آرایهای از نام تیمها باشد، میتوانید مقدار جدیدی را روی آرایه
فشار دهید مانند:
$request->session()->push('user.teams', 'developers');
بازیابی و حذف یک مورد
این
pull
متد یک مورد را از جلسه در یک عبارت واحد بازیابی و حذف می کند:
$value = $request->session()->pull('key', 'default');
داده های فلش
گاهی اوقات ممکن است بخواهید موارد را فقط برای درخواست بعدی در جلسه ذخیره
کنید.
شما می توانید این کار را با استفاده از
flash
روش انجام دهید.
داده های ذخیره شده در جلسه با استفاده از این روش بلافاصله و در طول
درخواست HTTP بعدی در دسترس خواهند بود.
پس از درخواست HTTP بعدی، داده های فلش شده حذف خواهند شد.
داده های فلش در درجه اول برای پیام های وضعیت کوتاه مدت مفید است:
$request->session()->flash('status', 'Task was successful!');
اگر نیاز دارید که داده های فلش خود را برای چندین درخواست نگه دارید، می
توانید از روشی استفاده کنید
reflash
که تمام داده های فلش را برای یک درخواست اضافی نگه می دارد.
اگر فقط نیاز به نگهداری داده های فلش خاصی دارید، می توانید از
keep
روش زیر استفاده کنید:
$request->session()->reflash(); $request->session()->keep(['username', 'email']);
حذف داده ها
این
forget
روش بخشی از داده را از جلسه حذف می کند.
اگر می خواهید تمام داده ها را از جلسه حذف کنید، می توانید از
flush
روش زیر استفاده کنید:
// Forget a single key...$request->session()->forget('key'); // Forget multiple keys...$request->session()->forget(['key1', 'key2']); $request->session()->flush();
بازسازی Session ID
ایجاد مجدد شناسه جلسه اغلب به منظور جلوگیری از سوء استفاده کاربران مخرب از حمله تثبیت جلسه بر روی برنامه شما انجام می شود.
لاراول به طور خودکار شناسه جلسه را در حین احراز هویت، در صورت استفاده از
داخلی، بازسازی می کند
LoginController
.
با این حال، اگر نیاز دارید که شناسه جلسه را به صورت دستی بازسازی کنید، می
توانید از این
regenerate
روش استفاده کنید.
$request->session()->regenerate();
مسدود کردن جلسه
برای استفاده از مسدود کردن جلسه، برنامه شما باید از یک درایور حافظه پنهان استفاده کند که از قفل اتمی پشتیبانی می کند . در حال حاضر، این درایورهای حافظه نهان شامل درایورها
memcached
،، و . علاوه بر این، ممکن است از درایور نشست استفاده نکنید .dynamodb
redis
database
cookie
بهطور پیشفرض، لاراول به درخواستهایی که از همان جلسه استفاده میکنند اجازه میدهد به صورت همزمان اجرا شوند. بنابراین، برای مثال، اگر از یک کتابخانه HTTP جاوا اسکریپت برای ایجاد دو درخواست HTTP برای برنامه خود استفاده کنید، هر دو به طور همزمان اجرا می شوند. برای بسیاری از برنامه ها، این یک مشکل نیست. با این حال، از دست دادن دادههای جلسه میتواند در زیرمجموعهای کوچک از برنامهها رخ دهد که درخواستهای همزمان را به دو نقطه پایانی برنامه متفاوت میدهند که هر دو دادهها را در جلسه مینویسند.
برای کاهش این امر، لاراول عملکردی را ارائه می دهد که به شما امکان می دهد
درخواست های همزمان را برای یک جلسه معین محدود کنید.
برای شروع، می توانید به سادگی
block
روش را به تعریف مسیر خود زنجیره بزنید.
در این مثال، یک درخواست ورودی به
/profile
نقطه پایانی یک قفل جلسه را به دست می آورد.
در حالی که این قفل نگه داشته میشود، هر درخواست ورودی به
/profile
یا
/order
نقاط پایانی که شناسه جلسه یکسانی دارند، قبل از ادامه اجرای خود منتظر
میمانند تا اجرای اولین درخواست به پایان برسد:
Route::post('/profile', function () { //})->block($lockSeconds = 10, $waitSeconds = 10) Route::post('/order', function () { //})->block($lockSeconds = 10, $waitSeconds = 10)
متد
block
دو آرگومان اختیاری را می پذیرد.
اولین آرگومان پذیرفته شده توسط
block
روش، حداکثر تعداد ثانیه هایی است که قفل جلسه قبل از آزاد شدن باید نگه
داشته شود.
البته اگر اجرای درخواست قبل از این زمان تمام شود، قفل زودتر آزاد می شود.
دومین آرگومان پذیرفته شده توسط
block
روش، تعداد ثانیه هایی است که یک درخواست باید در حین تلاش برای به دست
آوردن قفل جلسه منتظر بماند.
Illuminate\Contracts\Cache\LockTimeoutException
اگر درخواست نتواند قفل جلسه را در مدت زمان معین شده دریافت کند،
A پرتاب می شود.
اگر هیچ یک از این آرگومانها تصویب نشود، قفل حداکثر برای 10 ثانیه به دست میآید و درخواستها در حین تلاش برای به دست آوردن قفل حداکثر 10 ثانیه منتظر میمانند:
Route::post('/profile', function () { //})->block()
اضافه کردن درایورهای جلسه سفارشی
پیاده سازی درایور
درایور جلسه سفارشی شما باید اجرا شود
SessionHandlerInterface
.
این رابط فقط شامل چند روش ساده است که باید پیاده سازی کنیم.
یک پیاده سازی Stubbed 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) {}}
لاراول همراه با دایرکتوری حاوی پسوندهای شما ارسال نمی کند. شما آزاد هستید که آنها را در هر جایی که دوست دارید قرار دهید. در این مثال، ما یک
Extensions
دایرکتوری برای قرار دادنMongoSessionHandler
.
از آنجایی که هدف این روش ها به راحتی قابل درک نیست، بیایید به سرعت کارهای هر یک از روش ها را پوشش دهیم:
-
این
open
روش معمولاً در سیستمهای ذخیرهسازی جلسه مبتنی بر فایل استفاده میشود. از آنجایی که لاراول با یکfile
درایور جلسه ارائه می شود، تقریباً هرگز نیازی به قرار دادن چیزی در این روش نخواهید داشت. می توانید آن را به عنوان یک خرد خالی بگذارید. این یک واقعیت طراحی رابط ضعیف است (که بعداً در مورد آن صحبت خواهیم کرد) که PHP ما را ملزم به پیاده سازی این روش می کند. -
روش
close
، مانندopen
روش، معمولاً می تواند نادیده گرفته شود. برای اکثر رانندگان، به آن نیازی نیست. -
متد
read
باید نسخه رشته ای داده های جلسه مرتبط با داده شده را برگرداند$sessionId
. هنگام بازیابی یا ذخیره داده های نشست در درایور خود نیازی به انجام سریال سازی یا رمزگذاری دیگری نیست، زیرا لاراول سریال سازی را برای شما انجام می دهد. -
این
write
روش باید رشته داده شده$data
مرتبط با$sessionId
سیستم ذخیره سازی دائمی مانند MongoDB، Dynamo و غیره را بنویسد. باز هم، شما نباید هیچ سریال سازی را انجام دهید - لاراول قبلاً آن را برای شما مدیریت کرده است. -
این
destroy
روش باید داده های مرتبط با آن را$sessionId
از ذخیره سازی دائمی حذف کند. -
این
gc
روش باید تمام دادههای جلسهای را که قدیمیتر از دادهشده است$lifetime
، که یک مهر زمانی یونیکس است، از بین ببرد. برای سیستم های خود انقضا مانند Memcached و Redis، این روش ممکن است خالی بماند.
ثبت نام درایور
هنگامی که درایور شما پیاده سازی شد، آماده ثبت آن با فریم ورک هستید.
برای افزودن درایورهای اضافی به باطن جلسه لاراول، می توانید از
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{ /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { Session::extend('mongo', function ($app) { // Return implementation of SessionHandlerInterface... return new MongoSessionHandler; }); }}
هنگامی که درایور جلسه ثبت شد، می توانید از
mongo
درایور در
config/session.php
فایل پیکربندی خود استفاده کنید.