نسخه:

گسترش چارچوب

مدیران و کارخانه ها

لاراول چندین 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 را با نام ارائه دهنده توسعه یافته خود تعویض کنید.

این روش کلی برای گسترش هر کلاس هسته ای است که در ظرف محدود شده است. اساساً هر کلاس اصلی به این شکل در ظرف محدود می شود و می توان آن را نادیده گرفت. مجدداً، خواندن ارائه‌دهندگان خدمات فریمورک ارائه‌شده، شما را با مکان‌هایی که کلاس‌های مختلف به کانتینر متصل شده‌اند و با چه کلیدهایی متصل می‌شوند، آشنا می‌کند. این یک راه عالی برای یادگیری بیشتر در مورد نحوه چیدمان لاراول است.