boot()方法这都是社么意思?

public function boot()
    {
        $this->registerPolicies();
        // 修改策略自动发现的逻辑
        Gate::guessPolicyNamesUsing(function ($modelClass) {
            // 动态返回模型对应的策略名称,如:// 'App\Model\User' => 'App\Policies\UserPolicy',
            return 'App\Policies\\'.class_basename($modelClass).'Policy';
        });
    }

1、$this->registerPolicies(); 不知道registerPolicies()是干啥的,怎么来的?
2、不知道Gate::guessPolicyNamesUsing();是干啥的,怎么来的?
3、basename()方法知道,但是class_basename()中class是怎么回事?

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

boot() 函数多用于自启动,自加载 看一下registerPolicies()方法的源码

 public function registerPolicies()
    {
        foreach ($this->policies() as $key => $value) {
            Gate::policy($key, $value);
        }
    }

是个foreach循环,再看一下Gate接口中对policy静态方法的定义

public function policy($class, $policy);

    /**
     * Register a callback to run before all Gate checks.
     *
     * @param  callable  $callback
     * @return $this
     */

接口中注释写道Register a callback to run before all Gate checks. 翻译为 注册一个回调以在所有Gate检查之前运行。 再看一下这个静态方法接受的两个变量 $class, $policy,是将策略相绑定。


了解了两个基础方法后最后再回到 $this->registeryPolicies() 就很好理解了,注册并关联所有策略。 那么Laravel是怎么知道哪个类对应哪个策略呢? 来看一下guessPolicyNamesUsing()静态方法的定义,在Gate门面类中使用了授权访问类中的guessPolicyNamesUsing方法

/**
     * Specify a callback to be used to guess policy names.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function guessPolicyNamesUsing(callable $callback)
    {
        $this->guessPolicyNamesUsingCallback = $callback;

        return $this;
    }

具体怎么实现先不用管,来看这句注释 Specify a callback to be used to guess policy names. 翻译为 指定用于猜测策略名称的回调。 然后它接收的是一个$callback方法。


举例: 我们通过UserController控制器更新数据时,调用了授权方法,此时需要一个策略来配合User模型验证当前操作是否有权限,那么User模型应该用哪个策略呢?这时需要在guessPolicyNamesUsing()方法中写一个回调来告诉它怎么去发现与User模型匹配的策略,于是就有了下面这段代码

Gate::guessPolicyNamesUsing(function ($modelClass) {
//          动态返回模型的应对策略,如:// 'App\Models\User ==  'App\Policies\UserPolicy'
            return 'App\\Policies\\'. class_basename($modelClass).'Policy';
});

guessPolicyNamesUsing方法已经帮我们锁定了当前要通过哪个模型来提交数据,并把它传入了$modelClass中,此时我们使用dd($modelClass)打印这个变量看看它的值

Gate::guessPolicyNamesUsing(function ($modelClass) {
            dd($modelClass); 
        });

返回值是

"App\Models\User"

后面的代码就很好理解了,返回的是我们用字符串拼接好的策略名。

那么最后一个问题,class_basename()方法的作用是干嘛的呢?

再来打印一下

Gate::guessPolicyNamesUsing(function ($modelClass) {
            dd(class_basename($modelClass));
});

返回值

"User"

这只是一个辅助函数,用于去掉类名前面的路径App\Models,保留类名而已。

6个月前 评论
kakaxi 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!