說明:本文主要講述Laravel容器事件,並更根據容器事件做一個簡單demo供加深理解容器事件。同時,作者會將開發過程中的一些和代碼黏上去,提高閱讀效率。
Container是Laravel架構的核心,Container中儲存著各種各樣的Service,並且每一個Service通過Service Provider註冊在Container裡,通過Facade模式幫我們從容器裡去解析需要的Service對象。而這個過程中,容器每一次從容器中解析對象時是會觸發一個事件的,可以通過 resolving 方法監聽到。實際上在Laravel架構中表單請求驗證就用到這個好工具,通過一個表單請求類來實現表單內容驗證,以免把邏輯放在控制器裡弄亂控制器,具體可以看中文文檔: 表單請求驗證 。關於Container Event可以看文檔: 容器事件 。
Container Event在表單請求中的應用
先寫路由:
Route::post('containerevent', 'ContainerEventController@containerEvent');Route::post('formrequest', 'ContainerEventController@formRequest');Route::get('container', 'ContainerEventController@profile');
再建個控制器:
php artisan make:controller ContainerEventController
寫上方法:
public function containerEvent() { } public function formRequest() { } public function profile() { return view('profile'); }
寫上view:
Bootstrap Template
寫個表單請求類:先輸入命令產生表單請求類
php artisan make:request ContainerFormRequest
再給出驗證規則
class ContainerFormRequest extends Request{ /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true;//改為true,這裡一般用作使用者驗證,這裡全部通過驗證 } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ 'name' => 'required', 'age' => 'required|numeric|min:18', ]; }}
修改ContainerEventController:
public function formRequest(ContainerFormRequest $containerFormRequest){ dd('This is a From Request Container Event. It is working!!!');}
同時把app/Http/Kernel.php檔案中\App\Http\Middleware\VerifyCsrfToken::class登出掉,否則提交表單TokenMismatchException錯誤。
好,輸入路由(修改為你的路由): http://laravelcontainerevent.app:8888/container ,則輸入錯誤表單會返回到當前表單頁面,正確提交輸入表單後會列印:
說明fromRequest已經工作了,ContainerFormRequest這個對象從容器中解析的時候,會先工作 authorize 和 rules 方法。而控制器中只需要注入ContainerFormRequest這個對象就行了。
Demo
實現一個自訂的類,實現表單提交相同的功能。在app/Contracts檔案夾中建立EventBeforeResolving.php檔案:
namespace App\Contracts;interface EventBeforeResolving{ public function isAdult();}
並在一個service provider註冊下:
//AppServiceProvider.php/** * Register any application services. * * @return void */ public function register() { //當從容器中解析注入到控制器中前,會先調用實現EventBeforeResolving介面對象的isAdult()方法 $this->app->resolving(EventBeforeResolving::class,function($obj, $app){ $obj->isAdult(); }); }
寫一個service實現這個介面:
//app/Services/Authorize.phpnamespace App\Services;use App\Contracts\EventBeforeResolving;use Illuminate\Http\Request;class Authorize implements EventBeforeResolving{ private $request; public function __construct(Request $request) { $this->request = $request; } public function isAdult() { $name = $this->request->input('name'); $age = $this->request->input('age'); if(empty($name) || empty($age) || ($age < 18)){ dd('Name and Age must be required. And Age must be above 18'); } }}
修改下ContainerEventController:
public function containerEvent(Authorize $authorize) { dd('This is a Demo Container Event. It is working!!!'); }
同時別忘了修改下profile.blade.php檔案中表單提交action='/containerevent'。
當輸入錯誤時會提示錯誤資訊:
Container Event就是在Service對象從容器中解析注入前觸發事件,可以利用這個功能做一些有趣又好用的好東西呢,比如Laravel架構的表單請求驗證就是這麼做的,這樣不會把驗證邏輯代碼放在控制器中,以免弄亂控制器。
總結:本節主要講述Laravel的容器事件,並以Form Requet為例說明它的用途,同時以一個小demo講述怎麼一步步建立並監聽容器事件。嘛,過兩天還想結合Laravel的Task Schedual任務調度新開篇章,到時見。