使用场景:当需要处理复杂逻辑时,可将处理逻辑写入命令类中。
使用方法:
建立命令——php artisan make:command CommandTest 执行成功后会生成文件——app/Commands/CommandTest.php
调用命令——controller内调用dispatch方法,
1)$this->dispatch(new CommandTest());
2)使用Bus facade来快速派发命令,Bus::dispatch(new CommandTest());
深入理解:
Controller基类中有use DispatchesCommands,DispatchesCommands trait允许在控制器内调用dispatch方法。方法主体:
return app(' Illuminate\Contracts\Bus\Dispatcher')->dispatch($command);
从服务提供者v5.0.14/vendor/laravel/framework/src/Illuminate/Bus/BusServiceProvider.php的register()方法中可以看到,绑定了服务到服务容器中。实际调用的是\Illuminate\Bus\Dispatcher的dispatch()方法。最终的实现是通过如下方法:
public function dispatchNow($command, Closure $afterResolving = null) { return $this->pipeline->send($command)->through($this->pipes)->then(function($command) use ($afterResolving) { if ($command instanceof SelfHandling) return $this->container->call([$command, 'handle']); $handler = $this->resolveHandler($command); if ($afterResolving) call_user_func($afterResolving, $handler); return call_user_func( [$handler, $this->getHandlerMethod($command)], $command ); }); }
使用Bus facade快速派发命令,三要素:
1)facade别名配置:app.php文件中有"aliases'=>['Bus' => 'Illuminate\Support\Facades\Bus']
2)facade类:\Illuminate\Support\Facades\Bus.php,getFacadeAccessor()返回服务容器绑定的对象名称,基类Facade
利用__callStatic()魔术方法调用从Facade类中解析出来的对象,执行被请求的方法。
3)服务容器绑定:Illuminate/Bus/BusServiceProvider.php
ps:
trait——和类相似,但不能通过它自身来实例化;从基类继承的成员会被trait插入的成员覆盖;trait的方法会被来自当前类的成员覆盖。