جلسه 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