نسخه:

جلسه 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 فایل پیکربندی خود استفاده کنید.