گسترش چارچوب
مدیران و کارخانه ها
لاراول چندین
Manager
کلاس دارد که ایجاد کامپوننت های مبتنی بر درایور را مدیریت می کنند.
این شامل اجزای کش، جلسه، احراز هویت و صف است.
کلاس manager مسئول ایجاد یک پیاده سازی درایور خاص بر اساس پیکربندی برنامه است.
به عنوان مثال،
CacheManager
کلاس می تواند APC، Memcached، File، و پیاده سازی های مختلف دیگر از درایورهای کش را ایجاد کند.
هر یک از این مدیران شامل
extend
روشی است که ممکن است برای تزریق آسان قابلیت وضوح درایور جدید به مدیر استفاده شود.
ما هر یک از این مدیران را در زیر با مثال هایی از نحوه تزریق پشتیبانی درایور سفارشی به هر یک از آنها پوشش خواهیم داد.
توجه: چند لحظه وقت بگذارید و کلاسهای مختلفی
Manager
را که با لاراول ارائه میشوند، مانندCacheManager
و کاوش کنیدSessionManager
. خواندن این کلاس ها به شما درک کامل تری از نحوه عملکرد لاراول در زیر کاپوت می دهد. همه کلاسهای مدیرIlluminate\Support\Manager
کلاس پایه را گسترش میدهند، که برخی از عملکردهای مفید و مشترک را برای هر مدیر فراهم میکند.
حافظه پنهان
برای گسترش تسهیلات کش لاراول، از روشی
extend
در . استفاده می کنیم
CacheManager
که برای اتصال یک درایور حل کننده سفارشی به مدیر استفاده می شود و در همه کلاس های مدیر رایج است.
به عنوان مثال، برای ثبت یک درایور کش جدید به نام "mongo"، باید موارد زیر را انجام دهیم:
Cache::extend('mongo', function($app){ return Cache::repository(new MongoStore);});
اولین آرگومان ارسال شده به
extend
متد، نام درایور است.
driver
این با گزینه شما در فایل پیکربندی
مطابقت دارد
config/cache.php
.
آرگومان دوم یک Closure است که باید یک
Illuminate\Cache\Repository
نمونه را برگرداند.
بسته شدن به یک نمونه ارسال میشود
$app
، که یک نمونه از
Illuminate\Foundation\Application
و یک کانتینر خدماتی است.
فراخوانی میتواند به
روش پیشفرض
Cache::extend
انجام شود
که با برنامههای جدید لاراول ارسال میشود، یا میتوانید ارائهدهنده خدمات خود را برای نگهداری برنامه افزودنی ایجاد کنید - فقط فراموش نکنید که ارائهدهنده را در
آرایه ارائهدهنده ثبت کنید.
boot
App\Providers\AppServiceProvider
config/app.php
برای ایجاد درایور کش سفارشی خود، ابتدا باید
Illuminate\Contracts\Cache\Store
قرارداد را پیاده سازی کنیم.
بنابراین، پیاده سازی کش MongoDB ما چیزی شبیه به این خواهد بود:
class MongoStore implements Illuminate\Contracts\Cache\Store { public function get($key) {} public function put($key, $value, $minutes) {} public function increment($key, $value = 1) {} public function decrement($key, $value = 1) {} public function forever($key, $value) {} public function forget($key) {} public function flush() {} }
ما فقط باید هر یک از این روش ها را با استفاده از اتصال MongoDB پیاده سازی کنیم. هنگامی که پیاده سازی ما کامل شد، می توانیم ثبت نام درایور سفارشی خود را به پایان برسانیم:
Cache::extend('mongo', function($app){ return Cache::repository(new MongoStore);});
اگر نمیخواهید کد درایور کش سفارشی خود را کجا قرار دهید، آن را در Packagist در دسترس قرار دهید!
یا، می توانید یک
Extensions
فضای نام در دایرکتوری خود ایجاد کنید
app
.
با این حال، به خاطر داشته باشید که لاراول ساختار نرم افزاری سفت و سختی ندارد و شما آزاد هستید که برنامه خود را بر اساس ترجیحات خود سازماندهی کنید.
جلسه
گسترش لاراول با یک درایور نشست سفارشی به آسانی گسترش سیستم کش است.
extend
مجدداً از این روش برای ثبت کد سفارشی خود
استفاده خواهیم کرد :
Session::extend('mongo', function($app){ // Return implementation of SessionHandlerInterface});
محل تمدید جلسه
شما باید کد پسوند جلسه خود را در
boot
متد خود قرار دهید
AppServiceProvider
.
نوشتن پسوند جلسه
توجه داشته باشید که درایور جلسه سفارشی ما باید
SessionHandlerInterface
.
این رابط فقط شامل چند روش ساده است که باید پیاده سازی کنیم.
یک پیاده سازی Stubbed MongoDB چیزی شبیه به این خواهد بود:
class MongoHandler 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) {} }
از آنجایی که این روش ها به آسانی حافظه پنهان قابل درک نیستند
StoreInterface
، اجازه دهید به سرعت کارهایی که هر یک از روش ها انجام می دهند را پوشش دهیم:
-
این
open
روش معمولاً در سیستمهای ذخیرهسازی جلسه مبتنی بر فایل استفاده میشود. از آنجایی که لاراول با یکfile
درایور جلسه ارائه می شود، تقریباً هرگز نیازی به قرار دادن چیزی در این روش نخواهید داشت. می توانید آن را به عنوان یک خرد خالی بگذارید. این به سادگی یک واقعیت طراحی رابط ضعیف است (که بعداً در مورد آن صحبت خواهیم کرد) که PHP ما را ملزم به پیاده سازی این روش می کند. -
روش
close
، مانندopen
روش، معمولاً می تواند نادیده گرفته شود. برای اکثر رانندگان، به آن نیازی نیست. -
متد
read
باید نسخه رشته ای داده های جلسه مرتبط با داده شده را برگرداند$sessionId
. هنگام بازیابی یا ذخیره داده های نشست در درایور خود نیازی به انجام سریال سازی یا رمزگذاری دیگری نیست، زیرا لاراول سریال سازی را برای شما انجام می دهد. -
این
write
روش باید$data
رشته داده شده مرتبط با$sessionId
سیستم ذخیره سازی پایدار مانند MongoDB، Dynamo و غیره را بنویسد. -
این
destroy
روش باید داده های مرتبط با آن را$sessionId
از ذخیره سازی دائمی حذف کند. -
این
gc
روش باید تمام دادههای جلسهای را که قدیمیتر از دادهشده است$lifetime
، که یک مهر زمانی یونیکس است، از بین ببرد. برای سیستم های خود انقضا مانند Memcached و Redis، این روش ممکن است خالی بماند.
پس از
SessionHandlerInterface
پیاده سازی، ما آماده هستیم تا آن را در Session manager ثبت کنیم:
Session::extend('mongo', function($app){ return new MongoHandler;});
هنگامی که درایور جلسه ثبت شد، ممکن است از
mongo
درایور در
config/session.php
فایل پیکربندی خود استفاده کنیم.
توجه: به یاد داشته باشید، اگر یک کنترل کننده جلسه سفارشی می نویسید، آن را در Packagist به اشتراک بگذارید!
احراز هویت
احراز هویت ممکن است به همان روشی که حافظه پنهان و امکانات جلسه گسترش یابد.
extend
مجدداً از روشی که با آن آشنا شده ایم
استفاده خواهیم کرد :
Auth::extend('riak', function($app){ // Return implementation of Illuminate\Contracts\Auth\UserProvider});
پیادهسازیها
UserProvider
فقط مسئول واکشی یک
Illuminate\Contracts\Auth\Authenticatable
پیادهسازی از یک سیستم ذخیرهسازی دائمی مانند MySQL، Riak و غیره هستند. این دو رابط به مکانیسمهای احراز هویت لاراول اجازه میدهند بدون توجه به نحوه ذخیره دادههای کاربر یا نوع کلاس استفاده شده، به عملکرد خود ادامه دهند. برای نمایندگی آن
بیایید نگاهی به
UserProvider
قرارداد بیندازیم:
interface UserProvider { public function retrieveById($identifier); public function retrieveByToken($identifier, $token); public function updateRememberToken(Authenticatable $user, $token); public function retrieveByCredentials(array $credentials); public function validateCredentials(Authenticatable $user, array $credentials); }
تابع
retrieveById
معمولاً یک کلید عددی که کاربر را نشان می دهد، مانند یک شناسه افزایش خودکار از پایگاه داده MySQL دریافت می کند.
پیاده
Authenticatable
سازی منطبق با شناسه باید با روش بازیابی و برگردانده شود.
این
retrieveByToken
تابع یک کاربر را با استفاده از
$identifier
"مرا به خاطر بسپار" را
$token
که در یک فیلد ذخیره شده است، بازیابی می کند
remember_token
.
همانند روش قبلی،
Authenticatable
پیاده سازی باید برگردانده شود.
این
updateRememberToken
روش
$user
فیلد را
remember_token
با جدید به روز می کند
$token
.
توکن جدید میتواند یک توکن تازه باشد که در تلاش موفق برای ورود به سیستم "مرا به خاطر بسپار" یا زمانی که کاربر از سیستم خارج میشود، تهی باشد.
این روش
هنگام تلاش برای ورود به یک برنامه،
retrieveByCredentials
آرایه ای از اعتبارنامه ها را دریافت می کند .
Auth::attempt
سپس این روش باید برای کاربر مطابق با آن اعتبارنامه ها، فضای ذخیره سازی دائمی زیرین را "پرس و جو" کند.
به طور معمول، این روش یک پرس و جو را با شرط "where" در
$credentials['username']
.
سپس متد باید پیاده سازی را برگرداند
UserInterface
.
این روش نباید هیچ گونه اعتبارسنجی یا احراز هویت رمز عبور را انجام دهد.
این روش باید
برای احراز هویت کاربر،
validateCredentials
داده های داده شده را
$user
با آن مقایسه کند.
$credentials
به عنوان مثال، این روش ممکن است
$user->getAuthPassword()
رشته را با یک
Hash::make
از مقایسه کند
$credentials['password']
.
این روش فقط باید اعتبار کاربر را تأیید کند و بولی را برگرداند.
اکنون که هر یک از روش ها را بررسی کردیم
UserProvider
، بیایید نگاهی به
Authenticatable
.
به یاد داشته باشید، ارائهدهنده باید پیادهسازیهای این رابط را از
retrieveById
و
retrieveByCredentials
متدهای زیر برگرداند:
interface Authenticatable { public function getAuthIdentifier(); public function getAuthPassword(); public function getRememberToken(); public function setRememberToken($value); public function getRememberTokenName(); }
این رابط کاربری ساده است.
روش
getAuthIdentifier
باید «کلید اصلی» کاربر را برگرداند.
در یک بکاند MySQL، دوباره، این کلید اصلی افزایش خودکار است.
باید
getAuthPassword
رمز عبور هش شده کاربر را برگرداند.
این رابط به سیستم احراز هویت اجازه می دهد تا با هر کلاس کاربری، صرف نظر از اینکه از چه ORM یا لایه انتزاعی ذخیره سازی استفاده می کنید، کار کند.
بهطور پیشفرض، لاراول شامل یک
User
کلاس در
app
دایرکتوری است که این رابط را پیادهسازی میکند، بنابراین میتوانید برای مثال پیادهسازی با این کلاس مشورت کنید.
در نهایت، پس از پیاده سازی
UserProvider
، آماده هستیم تا پسوند خود را با
Auth
نما ثبت کنیم:
Auth::extend('riak', function($app){ return new RiakUserProvider($app['riak.connection']);});
بعد از اینکه درایور را با متد ثبت کردید ، در
فایل پیکربندی
extend
خود به درایور جدید سوئیچ می کنید .
config/auth.php
برنامه افزودنی مبتنی بر کانتینر خدمات
تقریباً هر ارائه دهنده خدماتی که در چارچوب لاراول گنجانده شده است، اشیاء را به کانتینر سرویس متصل می کند.
می توانید لیستی از ارائه دهندگان خدمات برنامه خود را در
config/app.php
فایل پیکربندی پیدا کنید.
همانطور که زمان دارید، باید کد منبع هر یک از این ارائه دهندگان را مرور کنید.
با انجام این کار، درک بسیار بهتری از آنچه که هر ارائه دهنده به چارچوب اضافه می کند و همچنین از چه کلیدهایی برای اتصال سرویس های مختلف به کانتینر سرویس استفاده می شود، به دست خواهید آورد.
به عنوان مثال،
کلیدی را به کانتینر سرویس
HashServiceProvider
متصل می کند که در یک
نمونه حل می شود.
شما به راحتی می توانید این کلاس را در برنامه خود با نادیده گرفتن این binding گسترش دهید و لغو کنید.
مثلا:
hash
Illuminate\Hashing\BcryptHasher
<?php namespace App\Providers; class SnappyHashProvider extends \Illuminate\Hashing\HashServiceProvider { public function boot() { parent::boot(); $this->app->bindShared('hash', function() { return new \Snappy\Hashing\ScryptHasher; }); } }
توجه داشته باشید که این کلاس
HashServiceProvider
نه
ServiceProvider
کلاس پایه پیش فرض را گسترش می دهد.
هنگامی که ارائه دهنده سرویس را گسترش دادید، فایل پیکربندی
HashServiceProvider
خود
config/app.php
را با نام ارائه دهنده توسعه یافته خود تعویض کنید.
این روش کلی برای گسترش هر کلاس هسته ای است که در ظرف محدود شده است. اساساً هر کلاس اصلی به این شکل در ظرف محدود می شود و می توان آن را نادیده گرفت. مجدداً، خواندن ارائهدهندگان خدمات فریمورک ارائهشده، شما را با مکانهایی که کلاسهای مختلف به کانتینر متصل شدهاند و با چه کلیدهایی متصل میشوند، آشنا میکند. این یک راه عالی برای یادگیری بیشتر در مورد نحوه چیدمان لاراول است.