🦄 2024 独立开发者训练营,一起创业!(早鸟优惠在1天后结束)查看介绍 / 立即报名 →

Laravel 5 中文手册(十二):外观 Facades

介绍

Facades 为应用的 IoC container 的类提供了一个静态的接口。Laravel 里面自带了一些 Facades,其实你应该已经用到它们了,不过可能还不知道它们是什么。Laravel 的 Facades 像是 Ioc container 类的静态代理,比起传统的静态方法(Static methods),Facades 更简洁,也更容易表达,更具可测性(Testability)与灵活性(Flexibility)。

有时候你可能需要为你的应用跟包去创建自己的 Facades,下面我们就一起去看一下相关的概念,开发,还有这些类的用法。

注意:在了解 Facades 之前,你最好先了解一下 Laravel 里的 Ioc Container

解释

在 Laravel 应用这个上下文里面,一个 Facade 就是一个类,使用这个类可以访问到来自容器里的一个对象,这个功能就是在 Facade 类里面定义的。Laravel 的 Facades 还有任何你自己定义的 Facades,都会去继承 Facade 这个类。

你的 Facade 类只需要实施一个的方法:getFacadeAccessor。要在容器里 resolve 什么出来,都是在这个方法里去做的。Facade 这个基类里面使用了 __callStatic() 魔术方法,可以延迟到 resolved 对象上的,来自 Facade 的调用。

所以,当你使用 Facade 调用的时候,比如像这样:Cache:get,laravel 会从 Ioc container 里面 resolves 缓存管理类,然后再去调用这个类上面的 get 方法。Laravel 的 Facades 可以去定位服务,它是一种使用 Laravel 的 Ioc container 的更方便的语法。

实际应用

下面的例子,去调用了一下 Laravel 的缓存系统。先看一下下面这行代码,你可能会觉得,这是直接去调用 Cache 这个类上面的一个叫 get 的静态的方法。

$value = Cache::get('key');

不过,如果你查看 Illuminate\Support\Facades\Cache 这个类,你会发现这里根本就没有 get 这个静态方法:

class Cache extends Facade {

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'cache'; }

}

Cache 这个类继承了 Facade 这个基类,它里面定义了一个叫 getFacadeAccessor() 的方法。注意,这个方法的干的事就是去返回一个 Ioc 绑定的名字,这里就是 cache。

当用户在引用任何在 Cache 这个 Facade 上的静态方法的时候,Laravel 就会从 Ioc container 里面去 resolves cache 这个绑定,并且会去执行在对象上的这个所请求的方法(这里就是 get 这个方法)。

所以,我们在调用 Cache::get 的时候,它的真正的意思是这样的:

$value = $app->make('cache')->get('key');

导入 Facades

注意,在使用 facade 的时候,如果控制器里面用到了命名空间,你需要把 Facade 类导入到这个命名空间里。所有的 Facades 都是在全局命名空间下:

<?php namespace App\Http\Controllers;

use Cache;

class PhotosController extends Controller {

    /**
     * Get all of the application photos.
     *
     * @return Response
     */
    public function index()
    {
        $photos = Cache::get('photos');

        //
    }

}

创建 Facades

为自己的应用或者包去创建 Facade 只需要三个东西:

  • 一个 IoC 绑定。
  • 一个 Facade 类。
  • 一个 Facade 别名的配置。

下面来看一下例子。在下面我们定义了一个类:PaymentGateway\Payment 。

namespace PaymentGateway;

class Payment {

    public function process()
    {
        //
    }

}

我们需要能在 Ioc container 里面去 resolve 这个类。所以,先要去添加一个 Service Provider 绑定:

App::bind('payment', function()
{
    return new \PaymentGateway\Payment;
});

去注册这个绑定最好的方法就是去创建一个新的 Service Provider ,把它命名为 PaymentServiceProvider ,然后把它绑定到 register 方法上。再去配置 laravel 在 config/app.php 这个配置文件里加载你的 Service Provider 。

下一步就是去创建自己的 Facade 类:

use Illuminate\Support\Facades\Facade;

class Payment extends Facade {

    protected static function getFacadeAccessor() { return 'payment'; }

}

最后,如果你愿意,可以去给 Facade 添加一个别名,放到 config/app.php 配置文件里的 aliases 数组里。现在,我们就可以去调用 Payment 类的一个实例上的 process 这个方法了。像这样:

Payment::process();

自动加载别名

在 aliases 数组里的类,在有些实例上是不可用的,这是因为 PHP 不会试图去自动加载未定义的 type-hint 的类。如果ApiTimeoutException 是 \ServiceWrapper\ApiTimeoutException 的别名,有个 catch(ApiTimeoutException $e) 在 \ServiceWrapper 这个命名空间以外,这就永远不会收到异常,甚至是抛出来的异常也不会接收到。类似的问题还出现在 type hint 到有别名的类里面。解决的办法只有放弃别名,并且在需要它们的每个文件的顶部, use 你想 type hint 的类。

Mocking Facades

单元测试是 Facades 为什么会存在的一个很主要的原因。了解更多,可以查看文档里的 mocking facades (英文文档)这个单元。

Facade 类参考

在下面你可以找到所有的 Facade ,还有在它下面表示的类。

Facade Class IoC Binding
App Illuminate\Foundation\Application app
Artisan Illuminate\Console\Application artisan
Auth Illuminate\Auth\AuthManager auth
Auth (Instance) Illuminate\Auth\Guard
Blade Illuminate\View\Compilers\BladeCompiler blade.compiler
Cache Illuminate\Cache\Repository cache
Config Illuminate\Config\Repository config
Cookie Illuminate\Cookie\CookieJar cookie
Crypt Illuminate\Encryption\Encrypter encrypter
DB Illuminate\Database\DatabaseManager db
DB (Instance) Illuminate\Database\Connection
Event Illuminate\Events\Dispatcher events
File Illuminate\Filesystem\Filesystem files
Form Illuminate\Html\FormBuilder form
Hash Illuminate\Hashing\HasherInterface hash
HTML Illuminate\Html\HtmlBuilder html
Input Illuminate\Http\Request request
Lang Illuminate\Translation\Translator translator
Log Illuminate\Log\Writer log
Mail Illuminate\Mail\Mailer mailer
Paginator Illuminate\Pagination\Factory paginator
Paginator (Instance) Illuminate\Pagination\Paginator
Password Illuminate\Auth\Passwords\PasswordBroker auth.reminder
Queue Illuminate\Queue\QueueManager queue
Queue (Instance) Illuminate\Queue\QueueInterface
Queue (Base Class) Illuminate\Queue\Queue
Redirect Illuminate\Routing\Redirector redirect
Redis Illuminate\Redis\Database redis
Request Illuminate\Http\Request request
Response Illuminate\Support\Facades\Response
Route Illuminate\Routing\Router router
Schema Illuminate\Database\Schema\Blueprint
Session Illuminate\Session\SessionManager session
Session (Instance) Illuminate\Session\Store
SSH Illuminate\Remote\RemoteManager remote
SSH (Instance) Illuminate\Remote\Connection
URL Illuminate\Routing\UrlGenerator url
Validator Illuminate\Validation\Factory validator
Validator (Instance) Illuminate\Validation\Validator
View Illuminate\View\Factory view
View (Instance) Illuminate\View\View
Laravel Laravel5 中文手册 Facade

评论

你在百度竞价的lavarel课程,着陆页提示网站遇到不可知的错误!我就是一个无聊胡乱逛网站的人,不是我故意点的链接,我只是好奇!!!希望你修改下,要不然就白白浪费钱了!!!

谢了 :)

哈哈,应该是我谢你。我从你这里学到很多东西!!!

微信好友

用微信扫描二维码,
加我好友。

微信公众号

用微信扫描二维码,
订阅宁皓网公众号。

240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

14696
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点