參考:http://laravel-china.org/docs/5.1/artisan
cli處理業務,把業務封裝成一個命令,用php artisan來調用
自定義的命令放在App/Console/Commands下
建立方式
php artisan make:console 命令名 —command=調用時名字
php artisan make:console SendEmails --command=emails:send
會在App/Console/Commands下生成SendEmails文件
命令生成之後,須要填寫該類的signature和description屬性,signature用來指定調用時的名字,desc是描述,這兩個屬性在調用list顯示命令的時候會被用到。
handle方法在命令執行時被調用,能夠將全部命令邏輯都放在這個方法裏面,咱們能夠在命令控制器的構造函數中注入任何依賴.php
最後須要把命令注入到app/Console/Kernel.php文件中,不然這個命令artisan是找不到的laravel
protected $commands = [ 'App\Console\Commands\AnalyzeLog' ];
<?php namespace App\Console\Commands; use App\Helper\Ip; use Illuminate\Console\Command; class AnalyzeLog extends Command { protected $signature = 'AnalyzeLog'; //調用時的名字 protected $description = '分析咪咕請求日誌'; public function __construct(Ip $ip) //自動注入 { parent::__construct(); $this->ip = $ip; } public function handle() { echo $this->ip->getName(); } }
調用:php artisan AnalyzeLog
事件的原理就是 觀察者模式 的實現;
新建一個事件類(被觀察者)
能夠創建多個監聽類(觀察者)
而後標記觀察者和被觀察者的關係,當被觀察者變化時,通知觀察者
(在appprovicderseventServiceProviders中標記事件類下的監聽類)redis
創建事件類
php artisan make:event DelMsgEvent
會在appenents目錄下建立數據庫
<?php namespace App\Events; use App\Events\Event; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class DelMsgEvent extends Event { use SerializesModels; /** * 被外部調用該事件時,能夠傳值 * DelMsgEvent constructor. * @param $data */ public function __construct($data) { $this->data(); }
創建監聽者
在applisteners目錄下建立數組
<?php namespace App\Listeners; use App\Events\SomeEvent; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class EventListener { public function __construct() { } /** * 事件觸發後,監聽者的handle方法會被調用用來處理 * @param SomeEvent $event */ public function handle(SomeEvent $event) { echo "this is enentlisten"; } }
創建事件和監聽者的關係
在appprovidersEventServiceProviders.php中的app
protected $listen = [ //事件 'App\Events\SomeEvent' => [ //事件的監聽者 'App\Listeners\EventListener', 'App\Listeners\SomeEventListener', ], ];
在控制器中觸發事件框架
//Event事件的支持,Event::fire所在的類 use Illuminate\Support\Facades\Event; //要用到的事件 use App\Events\SomeEvent; public function getShow() { $find = array( "uid" => 55, "msg.women" => false //搜索,根據msg字段中的women字段 ); $list = $this->collec->find($find); foreach($list as $document) //是個對象,須要迭代遍歷 { var_dump($document); } //觸發事件 Event::fire(new SomeEvent($list)); }
隊列任務能夠放到redis中,redis的配置是config/databases.php裏的
會把任務放到redis中的queues:default隊列中
把失敗的任務放到queues:default:reserved有序集合中
建立一個隊列任務ide
php artisan make:job SendReminderEmail
運行成功後會在app/Jobs目錄下生成一個SendReminderEmail.php函數
class SendReminderEmail extends Job implements ShouldQueue { use InteractsWithQueue, SerializesModels; public $name; //調用隊列時,初始化的參數 public function __construct($name) { $this->name = $name; } //隊列默認執行此方法 public function handle() { Log::info("this is queue send to ".$this->name); } //隊列任務失敗執行此方法 public function failed() { Log::error("fail send to ".$this->name); } }
插入隊列任務,能夠使用控制器中的DispatchesJobs trait(該trait在控制器基類Controller.php中引入)提供的dispatch方法手動分發任務
固然也能夠在控制器以外的其它地方使用dispatch分發任務,固然在此以前須要在該類中使用use DispatchesJobs。測試
public function getShow() { //生成一個隊列任務,並傳入參數 $this->dispatch(new SendReminderEmail(time())); }
處理任務
Laravel爲此提供了三種Artisan命令:
queue:work 默認只執行一次隊列請求, 當請求執行完成後就終止;
queue:listen 監聽隊列請求,只要運行着,就能一直接受請求,除非手動終止;
queue:work --daemon 同 listen 同樣, 只要運行着,就能一直接受請求,不同的地方是在這個運行模式下,當新的請求到來的時候,不從新加載整個框架,而是直接 fire 動做。能看出來, queue:work --daemon 是最高級的,通常推薦使用這個來處理隊列監聽。
注:使用 queue:work --daemon ,當更新代碼的時候,須要中止,而後從新啓動,這樣才能把修改的代碼應用上。
上述操做將隊列推送到默認隊列,即配置文件中的default,固然你還能夠將任務推送到指定隊列:
public function sendReminderEmail(Request $request,$id){ $user = App\User::findOrFail($id); $job = (new SendReminderEmail($user))->onQueue('emails'); $this->dispatch($job); }
由於默認監聽的 default 隊列,因此須要指定監聽隊列
php artisan queue:listen --queue=syncOrder
除此以外,Laravel還支持延遲任務執行時間,這裏咱們指定延遲1分鐘執行任務:
public function sendReminderEmail(Request $request,$id){ $user = User::findOrFail($id); $job = (new SendReminderEmail($user))->delay(60); $this->dispatch($job); }
目前,Log門面支持八種日誌級別(使用RFC 5424標準):
Log::emergency($error); //緊急情況,好比系統掛掉 Log::alert($error); //須要當即採起行動的問題,好比數據庫異常等,這種情況應該經過短信提醒 Log::critical($error); //嚴重問題,好比:應用組件無效,意料以外的異常 Log::error($error); //運行時錯誤,不須要當即處理但須要被記錄和監控 Log::warning($error); //警告但不是錯誤,好比使用了被廢棄的API Log::notice($error); //普通但值得注意的事件 Log::info($error); //感興趣的事件,好比登陸、退出 Log::debug($error); //詳細的調試信息
下面咱們就來分別演示下這幾種日誌級別的日誌記錄,咱們將在TestController的log方法中進行測試:
public function log(){ Log::emergency("系統掛掉了"); Log::alert("數據庫訪問異常"); Log::critical("系統出現未知錯誤"); Log::error("指定變量不存在"); Log::warning("該方法已經被廢棄"); Log::notice("用戶在異地登陸"); Log::info("用戶xxx登陸成功"); Log::debug("調試信息"); }
Contracts 合同,契約,也就是接口,定義一些規則,每一個實現此接口的都要實現裏面的方法
ServiceContainer 實現Contracts,具體的邏輯實現
ServiceProvider ServiceContainer的服務提供者,返回ServiceContainer的實例化,供其餘地方使用,能夠把它加入到app/config的provider中,會被自動註冊到容器中
Facades 簡化ServiceProvider的調用方式,並且能夠靜態調用ServiceContainer中的方法
實現
Contracts接口能夠寫或不寫,這裏就不定義了
定義一個ServiceContainer,實現具體的功能
namespace App\Helper; class MyFoo { public function add($a, $b) { return $a+$b; } }
定義一個ServiceProvider供其餘地方使用ServiceContain
<?php namespace App\Providers; use App\Helper\MyFoo; //要服務的Container use Illuminate\Support\ServiceProvider; use App; class MyFooServiceProvider extends ServiceProvider { public function boot(){} //註冊到容器中 public function register() { //能夠這麼綁定,這須要use App; App::bind("myfoo",function(){ return new MyFoo(); }); //也能夠這麼綁定 $this->app->bind("myfoo", function(){ return new MyFoo(); }); } }
在app/config.php中的providers數組中加入ServiceProvider,讓系統自動註冊
App\Providers\MyFooServiceProvider::class,
這時候就能夠使用了,假設在控制器中使用
public function two($id=null) { //從系統容器中獲取實例化對象 $myfoo = App::make("myfoo"); echo $myfoo->add(1,2); }
這樣太麻煩,還須要用make來獲取對象,爲了簡便,就能夠使用門面功能,定義門面MyFooFacade
namespace App\Facades; use Illuminate\Support\Facades\Facade; class MyFooFacade extends Facade { protected static function getFacadeAccessor() { //這裏返回的是ServiceProvider中註冊時,定義的字符串 return 'myfoo'; } }
在控制器裏就能夠直接調用了
use App\Facades\MyFooFacade; public function two($id=null) { //從系統容器中獲取實例化對象 $myfoo = App::make("myfoo"); echo $myfoo->add(1,2); //使用門面 echo MyFooFacade::add(4,5); }
總的來講,自定義了一個類,爲了方便在其餘別處使用,即可以使用服務提供者和門面