首先翻看手册上的例子

<?php
namespace app\facade;

use think\Facade;

class Test extends Facade
{
    protected static function getFacadeClass()
    {
        return 'app\common\Test';
    }
}

getFacedeClass方法用来指定Facade类映射的实际执行类,那是否可以动态指定自定义门面类呢?答案是可以的。

实现思路是创建一个trait类用于Facade类的继承,然后在该类中完善getFacadeClass方法,指定动态的类映射,代码如下:

<?php
namespace app\facade;

/**
 * Facade门面基类
 * @package app\facade
 */
trait FacadeDefind
{
    /**
     * 加上str_replace是为了适配basename函数
     * 在Linux中的目录字符不识别\,需要替换为/
     * @return string
     */
    protected static function getFacadeClass()
    {
        return basename(str_replace('\\', '/', static::class));
    }
}

然后在自定义的Facade类中use FacadeDefind;即可,不过需保证Facade类跟实际执行类的名称要相同(不同亦可,但为了方便定义跟调用最好还是相同比较好)。

同时Facade类的底层是使用容器去进行加载的,这里设置了映射之后,因为容器已经找不到定义的实际执行类了,所以需要在自定义容器绑定配置中定义好容器映射,找到app目录中的provider.php,然后每增加一个Facade类就新加一条容器映射定义,比如:

<?php
use app\ExceptionHandle;
use app\Request;
use app\service\DingHandle;

// 容器Provider定义文件
return [
    'think\Request'          => Request::class,
    'think\exception\Handle' => ExceptionHandle::class,
    // 自定义容器映射
    'DingHandle'             => DingHandle::class,
];

然后就可以使用了。