推荐网站https://www.codecasts.com/
具体哪个视频我忘了,视频是收费的
- 1.先写一个类
<?php
namespace App;
class Billing{
public function test()
{
return 'test';
}
}
- 2.然后写一个服务提供者
php artisan make:provider BillingProvider
会在生成app/Providers/BillingProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class BillingProvider extends ServiceProvider
{
public function boot()
{
//
}
// 此处我们绑定Billing 函数
public function register()
{
$this->app->bind('billing',function (){
return new \App\Billing();
});
// 框架中很多时候,都会使用 Billing::class 作为 bind()的第一个参数,比如最常用的 Request ,
// 此处我们为了直观演示,使用一个不一样的别名。
}
}
-
3.注册服务提供者
在config/app.php
的providers
数组里面添加\App\Providers\BillingProvider::class,
-
4 .以下三种方式都可以取值
// $res = app('billing')->test();
// $res = app()['billing']->test();
$res = app()->make('billing')->test();
dd($res);
- 5.实现
Facade
<?php
namespace App;
use Illuminate\Support\Facades\Facade;
class Bill extends Facade {
protected static function getFacadeAccessor()
{
return 'billing'; // TODO: Change the autogenerated stub
}
}
- 6.在
config/app.php
的aliases
数组里面添加'Bill' => \App\Bill::class,
dd(Bill::test())
Facade 工作原理
Facade 基类使用了 __callStatic() 魔术方法,直到对象从容器中被解析出来后,才会进行调用。比如以上的例子,
public static function __callStatic($method, $args)
{
// $instance 得到的其实是 BillingProvider中register方法里绑定的 new \App\Billing() 实例
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
public static function getFacadeRoot()
{
return static::resolveFacadeInstance(static::getFacadeAccessor());
}
/**
* Get the registered name of the component.
*
* @return string
*
* @throws \RuntimeException
*/
protected static function getFacadeAccessor()
{
throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
}
注意,因为我们在实例的类中直接重写了方法,所以执行的将会是以下代码
protected static function getFacadeAccessor()
{
return 'billing';
}
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) {
return $name;
}
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
}
/**
* Resolve the facade root instance from the container.
*
* @param string|object $name
* @return mixed
*/
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) {
return $name;
}
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
}
/**
* The resolved object instances.
*
* @var array
*/
protected static $resolvedInstance;
- 此处讲解下上面4中
app()
函数的三种用法,我们来看app()
全局函数可能就理解了
if (! function_exists('app')) {
/**
* Get the available container instance.
*
* @param string $abstract
* @param array $parameters
* @return mixed|\Illuminate\Foundation\Application
*/
function app($abstract = null, array $parameters = [])
{
if (is_null($abstract)) {
return Container::getInstance();
}
return Container::getInstance()->make($abstract, $parameters);
}
}
public function make($abstract, array $parameters = [])
{
return $this->resolve($abstract, $parameters);
}
protected function resolve($abstract, $parameters = [])
{
$abstract = $this->getAlias($abstract);
....
return $object;
}
所以app()的第一个参数其实是抽象类
还有一种实现实时 Facade 的简单方式,就是直接在将要实现的类的原命名空间前,加上Facades
,直接使用手册里的例子吧
<?php
namespace App;
use Facades\App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;
class Podcast extends Model
{
/**
* 发布 Podcast.
*
* @return void
*/
public function publish()
{
$this->update(['publishing' => now()]);
Publisher::publish($this);
}
}
网友评论