Laravel 门面实例教程 —— 创建自定义 Facades 类

使用Laravel框架必不可少的会用到它很多强大的门面类(Facades),门面提供了一个“静态”接口到服务容器中绑定的类,官方文档阐述了如何使用系统自带的缓存门面,我们这里演示如何创建并使用一个自定义的门面类。

注:本教程基于上一节服务提供者做部分代码修改,不熟悉的请参阅。

我们首先创建一个需要绑定到服务容器的Test类:

<?php

namespace App\Facades;

class Test
{
    public function doSomething()
    {
        echo 'This is TestClass\'s method doSomething';
    }
}

然后创建一个静态指向Test类的门面类TestClass:

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class TestClass extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'test';
    }
}

接下来我们要在服务提供者中绑定Test类到服务容器,修改TestServiceProvider类如下:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\TestService;
use App\Facades\Test;

class TestServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {

    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('test',function(){
            //return new TestService();
            return new Test;
        });

        $this->app->bind('App\Contracts\TestContract',function(){
            return new TestService();
        });
    }
}

再然后需要到配置文件config/app.php中注册门面类别名:

'aliases' => [

    ...//其他门面类别名映射

    'TestClass' => App\Facades\TestClass::class,
],

最后修改TestController代码如下:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use App;
use TestClass;
use App\Contracts\TestContract;

class TestController extends Controller
{

    public function __construct(TestContract $test){
        $this->test = $test;
    }

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        // $test = App::make('test');
        // $test->callMe('TestController');
        //$this->test->callMe('TestController');

       TestClass::doSomething();
    }

    ...//其他方法
}

注意:不要忘了在调用门面类TestClass的文件顶部使用use TestClass;引入TestClass,否则将不能正确调用。

好了,我们可以去浏览器中测试了,访问http://laravel.app:8000/test,页面将会输出:

This is TestClass's method doSomething

学院君 has written 883 articles

Laravel学院院长,终身学习者

积分:100062 等级:P12 职业:码农 城市:杭州

26 条回复

  1. SilenMark SilenMark says:
    学院君 ,您这段代码是不是注册了两个对象,一个是test静态代理Test单例,另一个是需要实现TestContract接口的对象时返回上一章服务提供者教程中的TestService实例?
  2. Yang-Liu2015 Yang-Liu2015 says:
    看了半天,没怎么懂,看懂评论里说是外观模式,秒懂,我还是复习下设计模式吧
  3. 白猪 白猪 says:
    @ 学院君 表面上看就是config/app.php aliases数组中指定了门面类 TestClass ,它的方法返回了 test , 这个test就是在服务提供者中向服务容器注册的
  4. 白猪 白猪 says:
    @ 董博 这个例子是上一节写下来的,有多余的namespace是因为是上一节的例子。
  5. nikcy nikcy says:
    @ 行陌路 看到学院君第三段代码 有写TestService 但是上文并没有这个代码,所以我有这个疑问,请问我那个疑问对吗?谢谢
  6. nikcy nikcy says:
    @ 行陌路 我是按照学院君 这个案例说的,因为如果不这样写 是不是下面那段代码 就有错误啊?
  7. nikcy nikcy says:
    @学院君 第一段代码 namespace AppFacades 这个是不是应该是 namespace AppServices ?然后类名 Test 应该是TestService 呢? 初学者 不对支持还望指正 谢谢
  8. 疯狂的Camaro 疯狂的Camaro says:
    @ 💪🏻💪🏻 我在app/Facades目录下建TestClass就报错,所以我就建到IlluminateSupportFacades目录下了

登录后才能进行评论,立即登录?