نسخه:

جلسه HTTP

معرفی

از آنجایی که برنامه های مبتنی بر HTTP بدون حالت هستند، جلسات راهی برای ذخیره اطلاعات کاربر در چندین درخواست ارائه می دهد. این اطلاعات کاربر معمولاً در یک فروشگاه / پشتیبان دائمی قرار می گیرد که از درخواست های بعدی قابل دسترسی است.

لاراول با انواع بک‌اندهای جلسه عرضه می‌شود که از طریق یک API بیانگر و یکپارچه قابل دسترسی هستند. پشتیبانی از باطن های محبوب مانند Memcached ، Redis ، و پایگاه داده گنجانده شده است.

پیکربندی

فایل پیکربندی جلسه برنامه شما در ذخیره می شود config/session.php . گزینه های موجود در این فایل را حتما بررسی کنید. به طور پیش فرض، لاراول برای استفاده از database درایور جلسه پیکربندی شده است.

گزینه پیکربندی جلسه driver تعیین می کند که داده های جلسه برای هر درخواست کجا ذخیره شوند. لاراول شامل درایورهای مختلفی است:

  • file - جلسات در ذخیره می شود storage/framework/sessions .
  • cookie - جلسات در کوکی های امن و رمزگذاری شده ذخیره می شوند.
  • database - جلسات در یک پایگاه داده رابطه ای ذخیره می شوند.
  • memcached / redis - جلسات در یکی از این فروشگاه های سریع و مبتنی بر حافظه پنهان ذخیره می شوند.
  • dynamodb - جلسات در AWS DynamoDB ذخیره می شوند.
  • array - جلسات در یک آرایه PHP ذخیره می شوند و ادامه نخواهند داشت.

درایور آرایه در درجه اول در طول آزمایش استفاده می شود و از ماندگاری داده های ذخیره شده در جلسه جلوگیری می کند.

پیش نیاز راننده

پایگاه داده

هنگام استفاده از database درایور جلسه، باید مطمئن شوید که یک جدول پایگاه داده حاوی داده های جلسه دارید. به طور معمول، این در 0001_01_01_000000_create_users_table.php انتقال پایگاه داده پیش فرض لاراول گنجانده شده است . با این حال، اگر به هر دلیلی جدول ندارید sessions ، می توانید از make:session-table دستور Artisan برای ایجاد این مهاجرت استفاده کنید:

php artisan make:session-table
 
php artisan migrate

ردیس

قبل از استفاده از جلسات Redis با لاراول، باید افزونه PhpRedis PHP را از طریق PECL نصب کنید یا predis/predis بسته (~1.0) را از طریق Composer نصب کنید. برای اطلاعات بیشتر در مورد پیکربندی Redis، به اسناد Laravel's Redis مراجعه کنید .

متغیر محیطی SESSION_CONNECTION یا connection گزینه موجود در session.php فایل پیکربندی، ممکن است برای تعیین اینکه کدام اتصال Redis برای ذخیره سازی جلسه استفاده می شود، استفاده شود.

تعامل با جلسه

بازیابی داده ها

دو روش اصلی برای کار با داده های جلسه در لاراول وجود دارد: session کمک کننده جهانی و از طریق یک Request نمونه. ابتدا، اجازه دهید دسترسی به جلسه از طریق یک Request نمونه را بررسی کنیم، که می تواند در روش بسته شدن مسیر یا کنترلر به صورت تایپ اشاره شود. به یاد داشته باشید که وابستگی های متد کنترلر به طور خودکار از طریق ظرف سرویس لاراول تزریق می شوند :

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Illuminate\View\View;
 
class UserController extends Controller
{
/**
* Show the profile for the given user.
*/
public function show(Request $request, string $id): View
{
$value = $request->session()->get('key');
 
// ...
 
$user = $this->users->find($id);
 
return view('user.profile', ['user' => $user]);
}
}

هنگامی که یک آیتم را از جلسه بازیابی می کنید، می توانید یک مقدار پیش فرض را نیز به عنوان آرگومان دوم به get متد ارسال کنید. اگر کلید مشخص شده در جلسه وجود نداشته باشد، این مقدار پیش فرض برگردانده می شود. اگر یک بسته را به عنوان مقدار پیش فرض به get متد ارسال کنید و کلید درخواستی وجود نداشته باشد، بسته شدن اجرا شده و نتیجه آن برگردانده می شود:

$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();

بازیابی بخشی از داده های جلسه

متدهای only و except ممکن است برای بازیابی زیرمجموعه ای از داده های جلسه استفاده شوند:

$data = $request->session()->only(['username', 'email']);
 
$data = $request->session()->except(['username', 'email']);

تعیین اینکه آیا یک آیتم در جلسه وجود دارد یا خیر

برای تعیین اینکه آیا یک مورد در جلسه وجود دارد یا خیر، می توانید از has روش استفاده کنید. اگر آیتم موجود باشد و نباشد، متد has برمی گردد : true null

if ($request->session()->has('users')) {
// ...
}

برای تعیین اینکه آیا یک آیتم در جلسه وجود دارد، حتی اگر مقدار آن باشد null ، می توانید از exists روش استفاده کنید:

if ($request->session()->exists('users')) {
// ...
}

برای تعیین اینکه آیا موردی در جلسه وجود ندارد، می توانید از missing روش استفاده کنید. اگر مورد موجود نباشد، متد missing برمی گردد : true

if ($request->session()->missing('users')) {
// ...
}

ذخیره سازی داده ها

برای ذخیره داده ها در جلسه، معمولاً از put روش نمونه درخواست یا کمک کننده جهانی استفاده می کنید session :

// Via a request instance...
$request->session()->put('key', 'value');
 
// Via the global "session" helper...
session(['key' => 'value']);

فشار دادن به مقادیر جلسه آرایه

این push روش ممکن است برای فشار دادن یک مقدار جدید به یک مقدار جلسه که یک آرایه است استفاده شود. به عنوان مثال، اگر user.teams کلید حاوی آرایه‌ای از نام تیم‌ها باشد، می‌توانید مقدار جدیدی را روی آرایه فشار دهید مانند:

$request->session()->push('user.teams', 'developers');

بازیابی و حذف یک مورد

این pull متد یک مورد را از جلسه در یک عبارت واحد بازیابی و حذف می کند:

$value = $request->session()->pull('key', 'default');

افزایش و کاهش ارزش جلسات

اگر داده‌های جلسه شما حاوی یک عدد صحیح است که می‌خواهید آن را افزایش یا کاهش دهید، می‌توانید از روش‌های increment و استفاده کنید decrement :

$request->session()->increment('count');
 
$request->session()->increment('count', $incrementBy = 2);
 
$request->session()->decrement('count');
 
$request->session()->decrement('count', $decrementBy = 2);

داده های فلش

گاهی اوقات ممکن است بخواهید مواردی را در جلسه برای درخواست بعدی ذخیره کنید. شما می توانید این کار را با استفاده از flash روش انجام دهید. داده های ذخیره شده در جلسه با استفاده از این روش بلافاصله و در طول درخواست HTTP بعدی در دسترس خواهند بود. پس از درخواست HTTP بعدی، داده های فلش شده حذف خواهند شد. داده های فلش در درجه اول برای پیام های وضعیت کوتاه مدت مفید است:

$request->session()->flash('status', 'Task was successful!');

اگر نیاز دارید که داده های فلش خود را برای چندین درخواست حفظ کنید، می توانید از روشی استفاده کنید reflash که تمام داده های فلش را برای یک درخواست اضافی نگه می دارد. اگر فقط نیاز به نگهداری داده های فلش خاصی دارید، می توانید از keep روش زیر استفاده کنید:

$request->session()->reflash();
 
$request->session()->keep(['username', 'email']);

برای اینکه داده های فلش خود را فقط برای درخواست فعلی حفظ کنید، می توانید از now روش زیر استفاده کنید:

$request->session()->now('status', 'Task was successful!');

حذف داده ها

این forget روش بخشی از داده را از جلسه حذف می کند. اگر می خواهید تمام داده ها را از جلسه حذف کنید، می توانید از flush روش زیر استفاده کنید:

// Forget a single key...
$request->session()->forget('name');
 
// Forget multiple keys...
$request->session()->forget(['name', 'status']);
 
$request->session()->flush();

بازسازی Session ID

ایجاد مجدد شناسه جلسه اغلب به منظور جلوگیری از سوء استفاده کاربران مخرب از حمله تثبیت جلسه بر روی برنامه شما انجام می شود.

اگر از یکی از کیت های شروع برنامه لاراول یا Laravel Fortify استفاده می کنید، لاراول به طور خودکار شناسه جلسه را در حین احراز هویت بازسازی می کند . با این حال، اگر شما نیاز به بازسازی دستی شناسه جلسه دارید، می توانید از regenerate روش زیر استفاده کنید:

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

اگر می‌خواهید شناسه جلسه را دوباره تولید کنید و تمام داده‌ها را در یک دستور از جلسه حذف کنید، می‌توانید از invalidate روش زیر استفاده کنید:

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

مسدود کردن جلسه

برای استفاده از مسدود کردن جلسه، برنامه شما باید از یک درایور حافظه پنهان استفاده کند که از قفل اتمی پشتیبانی می کند . در حال حاضر ، این درایورهای کش شامل درایورهای memcached ،،،،، و . علاوه بر این، ممکن است از درایور نشست استفاده نکنید . dynamodb redis database file array 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 اگر درخواست نتواند قفل جلسه را در مدت زمان معین شده دریافت کند، یک علامت پرتاب می شود.

اگر هیچ یک از این آرگومان‌ها تصویب نشود، قفل حداکثر برای 10 ثانیه به دست می‌آید و درخواست‌ها در حین تلاش برای به دست آوردن قفل حداکثر 10 ثانیه منتظر می‌مانند:

Route::post('/profile', function () {
// ...
})->block()

اضافه کردن درایورهای جلسه سفارشی

پیاده سازی درایور

اگر هیچ یک از درایورهای جلسه موجود با نیازهای برنامه شما مطابقت نداشته باشد، لاراول این امکان را فراهم می کند تا Session handler خود را بنویسید. درایور جلسه سفارشی شما باید PHP داخلی را پیاده سازی کند 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 درایور جلسه ارائه می شود، به ندرت نیاز به قرار دادن چیزی در این روش خواهید داشت. به سادگی می توانید این روش را خالی بگذارید.
  • روش close ، مانند open روش، معمولاً می تواند نادیده گرفته شود. برای اکثر رانندگان، به آن نیازی نیست.
  • متد read باید نسخه رشته ای داده های جلسه مرتبط با داده شده را برگرداند $sessionId . هنگام بازیابی یا ذخیره داده های نشست در درایور خود نیازی به انجام سریال سازی یا رمزگذاری دیگری نیست، زیرا لاراول سریال سازی را برای شما انجام می دهد.
  • این روش باید رشته داده شده مرتبط با یک سیستم ذخیره سازی پایدار، مانند MongoDB یا سیستم ذخیره سازی دیگری را که انتخاب می کنید، write بنویسد . باز هم، شما نباید هیچ سریال سازی را انجام دهید - لاراول قبلاً آن را برای شما انجام داده است. $data $sessionId
  • این destroy روش باید داده های مرتبط با آن را $sessionId از ذخیره سازی دائمی حذف کند.
  • این gc روش باید تمام داده‌های جلسه‌ای را که قدیمی‌تر از داده‌شده است $lifetime ، که یک مهر زمانی یونیکس است، از بین ببرد. برای سیستم های خود انقضا مانند Memcached و Redis، این روش ممکن است خالی بماند.

ثبت درایور

پس از پیاده سازی درایور شما، آماده ثبت آن در لاراول هستید. برای افزودن درایورهای اضافی به باطن جلسه لاراول، می توانید از extend روش ارائه شده توسط Session نما استفاده کنید . شما باید extend روش را از boot روش ارائه دهنده خدمات فراخوانی کنید . می توانید این کار را از طریق ارائه دهنده موجود انجام دهید App\Providers\AppServiceProvider یا یک ارائه دهنده کاملاً جدید ایجاد کنید:

<?php
 
namespace App\Providers;
 
use App\Extensions\MongoSessionHandler;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
 
class SessionServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Session::extend('mongo', function (Application $app) {
// Return an implementation of SessionHandlerInterface...
return new MongoSessionHandler;
});
}
}

هنگامی که درایور جلسه ثبت شد، می توانید با استفاده از متغیر محیطی یا در فایل پیکربندی برنامه، mongo درایور را به عنوان درایور جلسه برنامه خود تعیین کنید . SESSION_DRIVER config/session.php