Laravel應用

CLI

參考: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, ServiceProvider, Facades關係

  • 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);
}

總的來講,自定義了一個類,爲了方便在其餘別處使用,即可以使用服務提供者和門面

相關文章
相關標籤/搜索