门面(Facade)
门面为容器中的类提供了个静态调用接口 相比于传统的静态方法调用 更好的可测试性和扩展性,可以为任何的非静态类库定义个facade类。
系统已经为大部分核心类库定义了
Facade所以你可以通过Facade来访问这些系统类 当然也可以为你的应用类库添加静态代理。
下面是个示例 假如 定义了个appcommonTest类 里面有个hello动态方法。
<?phpnamespace appcommon;class Test{public function hello($name){return 'hello,' . $name;
}
}调用hello方法的代码应该类似于:
$test = new appcommonTest;echo $test->hello('thinkphp'); // 输出 hello thinkphp接下来 给这个类定义个静态代理类appfacadeTest(这个类名不一定要和Test类一致 但通常为了便于管理 建议保持名称统一)。
<?phpnamespace appfacade;use thinkFacade;class Test extends Facade{protected static function getFacadeClass(){return 'appcommonTest';
}
}只要这个类库继承thinkFacade 就可以使用静态方式调用动态类appcommonTest的动态方法 例如上面的代码就可以改成:
// 无需进行实例化 直接以静态方法方式调用helloecho appfacadeTest::hello('thinkphp');结果也会输出 hello thinkphp。
说的直白一点 Facade功能可以让类无需实例化而直接进行静态方式调用。
如果没有通过getFacadeClass方法显式指定要静态代理的类 可以在调用的时候进行动态绑定:
<?php
namespace appfacade;
use thinkFacade;class Test extends Facade{
}use appfacadeTest;use thinkFacade;
Facade::bind('appfacadeTest', 'appcommonTest');echo Test::hello('thinkphp');bind方法支持批量绑定 因此你可以在应用的公共函数文件中统一进行绑定操作 例如:
Facade::bind([ 'appfacadeTest' => 'appcommonTest', 'appfacadeInfo' => 'appcommonInfo', ]);
核心Facade类库
系统给内置的常用类库定义了Facade类库 包括:
| (动态)类库 | Facade类 |
|---|---|
| thinkApp | thinkfacadeApp |
| thinkBuild | thinkfacadeBuild |
| thinkCache | thinkfacadeCache |
| thinkConfig | thinkfacadeConfig |
| thinkCookie | thinkfacadeCookie |
| thinkDebug | thinkfacadeDebug |
| thinkEnv | thinkfacadeEnv |
| thinkHook | thinkfacadeHook |
| thinkLang | thinkfacadeLang |
| thinkLog | thinkfacadeLog |
| thinkMiddleware | thinkfacadeMiddleware |
| thinkRequest | thinkfacadeRequest |
| thinkResponse | thinkfacadeResponse |
| thinkRoute | thinkfacadeRoute |
| thinkession | thinkfacadeession |
| thinkUrl | thinkfacadeUrl |
| thinkValidate | thinkfacadeValidate |
| thinkView | thinkfacadeView |
所以你无需进行实例化就可以很方便的进行方法调用 例如:
use thinkfacadeCache;Cache::set('name','value');
echo Cache::get('name');
thinkDb类的实现本来就类似于Facade机制 所以不需要再进行静态代理就可以使用静态方法调用(确切的说Db类是没有方法的 都是调用的Query类的方法)。
在进行依赖注入的时候 请不要使用Facade类作为类型约束 而是建议使用原来的动态类 下面是错误的用法:
<?phpnamespace appindexcontroller;use thinkfacadeApp;class Index{public function index(App $app){
}
}应当使用下面的方式:
<?phpnamespace appindexcontroller;use thinkApp;class Index{public function index(App $app){
}
}为了更加方便的使用系统类库 系统还给这些常用的核心类库的Facade类注册了类库别名 当进行静态调用的时候可以直接使用简化的别名进行调用。
| 别名类 | 对应Facade类 |
|---|---|
| App | thinkfacadeApp |
| Build | thinkfacadeBuild |
| Cache | thinkfacadeCache |
| Config | thinkfacadeConfig |
| Cookie | thinkfacadeCookie |
| Db | thinkDb |
| Debug | thinkfacadeDebug |
| Env | thinkfacadeEnv |
| Hook | thinkfacadeHook |
| Lang | thinkfacadeLang |
| Log | thinkfacadeLog |
| Middleware | thinkfacadeMiddleware |
| Request | thinkfacadeRequest |
| Response | thinkfacadeResponse |
| Route | thinkfacadeRoute |
| Session | thinkfacadeession |
| Url | thinkfacadeUrl |
| Validate | thinkfacadeValidate |
| View | thinkfacadeView |
因此前面的代码可以改成
Cache::set('name','value');
echo Cache::get('name');Facade类定义了个实例化的
instance方法 如果你的类也有定义的话将会失效。

尊贵的董事大人
英文标题不为空时 视为本栏投稿
需要关键字 描述 英文标题