在 Laravel 5.2 的控制器内使用服务提供商

Use of service providers within controllers in Laravel 5.2

至于标题,我花了大约两个小时寻找一个有效的答案,并反复阅读了官方文档,但考虑到我对这个框架还比较陌生,所以没有进一步的步骤。在寻找在控制器之间共享一些代码的正确方法时出现了疑问,我偶然发现了服务提供商,所以:

  1. 我创建了一个 MyCustomServiceProvider;
  2. 我已将它添加到 app.php 文件中的 providersaliases 数组;
  3. 最后我创建了一个自定义助手 class 并将其注册为:

    class MyCustomServiceProvider extends ServiceProvider
    {
        public function boot()
        {
            //
        }
    
        public function register()
        {
            $this->app->bind('App\Helpers\Commander', function(){
    
                return new Commander();
    
            });
        }
    }
    

然而,到目前为止,如果我在控制器中使用自定义 class,我必须通过 use 语句添加路径:

use App\Helpers\Commander;

否则我会得到一个不错的 class 未找到异常,显然我的控制器没有他的工作。
我怀疑服务提供商有什么东西让我逃避了! :-)

So far, however, if I use that custom class within a controller I necessarily need to add the path to it through the use statement:

`use App\Helpers\Commander;`

otherwise I get a nice class not found exception and obviously my controller does not his job.

是的,这就是它的工作原理。如果您不想使用全名,可以使用 Facade 代替。

像这样创建 Facade class:

class Commander extends Facade
{
    protected static function getFacadeAccessor() { return 'commander'; }
}

注册服务:

$this->app->singleton('commander', function ($app) {
    return new Commander();
});

将别名添加到您的 config/app.php:

'aliases' => [
    //...
    'Commander' => Path\To\Facades\Commander::class,
    //...
],

并像 Facade:

一样使用它
\Commander::doStuff();

为什么你的代码仍然有效,即使你删除了绑定:

当您对函数的参数进行类型提示时,Laravel 不知道您想要的类型(通过绑定),Laravel 将尽最大努力创建 class 给你,如果可能的话。因此,即使您没有绑定 class,Laravel 也会很乐意为您创建 class 的实例。当您使用 interfaces 时,您真正需要绑定的地方。通常,您不会键入特定于 class 的类型提示,而是一个接口。但是Laravel不能创建一个接口的实例并传递给你,所以Laravel需要知道它如何构造一个class实现你需要的接口。在这种情况下,您会将 class(或创建 class 的闭包)绑定到接口。