主页/PHP笔记/PHP问答/框架Laravel/如何在 Laravel 中向控制器注入依赖

如何在 Laravel 中向控制器注入依赖

Bug编译狮

Bug编译狮

在 Laravel 中,向控制器注入依赖可以通过多种方式实现。以下是几种常见的方法:

方法一:使用构造函数注入

  1. 创建服务提供者: 首先,你需要创建一个服务提供者来注册你的依赖。

    // app/Providers/AppServiceProvider.php
    namespace AppProviders;
    
    use IlluminateSupportServiceProvider;
    use AppServicesMyService;
    
    class AppServiceProvider extends ServiceProvider
    {
       public function register()
       {
           $this->app->bind(MyService::class, function ($app) {
               return new MyService();
           });
       }
    }
  2. 在控制器中使用构造函数注入: 现在你可以通过构造函数注入服务到你的控制器中。

    // app/Http/Controllers/ExampleController.php
    namespace AppHttpControllers;
    
    use AppServicesMyService;
    
    class ExampleController extends Controller
    {
       protected $myService;
    
       public function __construct(MyService $myService)
       {
           $this->myService = $myService;
       }
    
       public function index()
       {
           return view('example.index', ['message' => $this->myService->getMessage()]);
       }
    }

方法二:使用 app 命令注入

如果你只需要在某个特定的请求中注入依赖,可以使用 app 命令注入。

// app/Http/Controllers/ExampleController.php
namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppServicesMyService;

class ExampleController extends Controller
{
    public function index(Request $request)
    {
        $myService = app(MyService::class);
        return view('example.index', ['message' => $myService->getMessage()]);
    }
}

方法三:使用 app 事件绑定注入

你也可以将依赖绑定到事件中,以便在整个应用中共享这些依赖。

// app/Providers/AppServiceProvider.php
namespace AppProviders;

use IlluminateSupportServiceProvider;
use AppServicesMyService;
use IlluminateEventsEventServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(EventServiceProvider $eventProvider)
    {
        $eventProvider->listen(IlluminateHttpRequest::class, function (IlluminateHttpRequest $request) {
            $myService = app(MyService::class);
            return view('example.index', ['message' => $myService->getMessage()]);
        });
    }
}

示例代码

假设我们有一个简单的 MyService 类,并且我们希望在控制器中使用它。

// app/Services/MyService.php
namespace AppServices;

class MyService
{
    public function getMessage()
    {
        return 'Hello from MyService!';
    }
}

然后,我们在控制器中使用构造函数注入:

// app/Http/Controllers/ExampleController.php
namespace AppHttpControllers;

use AppServicesMyService;

class ExampleController extends Controller
{
    protected $myService;

    public function __construct(MyService $myService)
    {
        $this->myService = $myService;
    }

    public function index()
    {
        return view('example.index', ['message' => $this->myService->getMessage()]);
    }
}

这样,当你访问 /example/index 路由时,会显示 “Hello from MyService!”。

黑板Bug讲师

黑板Bug讲师

介绍

依赖注入(Dependency Injection,简称DI)是一种设计模式,它允许一个类从外部获取其依赖项,而不是自己创建它们。在Laravel框架中,控制器可以受益于依赖注入,从而实现更加模块化、可测试和灵活的代码。本文将指导您如何向您的Laravel控制器中注入依赖项。

理解依赖注入(Dependency Injection, DI)

在深入实施之前,让我们先澄清一下什么是DI(依赖注入),通过一个简单的例子来说明。假设我们有一个……ReportGenerator那门课程要求什么?DatabaseConnection物体。

class ReportGenerator {
    protected $dbConnection;

    public function __construct(DatabaseConnection $dbConnection) {
        $this->dbConnection = $dbConnection;
    }

    // Methods that use $dbConnection to generate reports
}

对不起,我没明白你的意思,请重新描述一下。ReportGenerator它不实例化。DatabaseConnection它被注入其中。这是依赖注入的一个例子。

通过构造函数注入

最常见的Laravel中的DI方法是通过控制器的构造函数实现的。

<?php

namespace AppHttpControllers;

use AppServicesReportService;

class ReportController extends Controller {
    protected $reportService;

    public function __construct(ReportService $reportService) {
        $this->reportService = $reportService;
    }

    public function generate() {
        $report = $this->reportService->createReport();
        return view('reports.generate', compact('report'));
    }
}

在这个例子中,ReportController收到。ReportService通过构造函数实例化它。我们现在可以使用它了。$this->ReportService在我们生成报告的方法中。

解决依赖关系

Laravel 服务容器是管理类依赖并执行依赖注入的工具。它自动处理实例化和注入依赖。在上述示例中,Laravel 的服务容器会解析并注入。ReportServiceinto theReportController好的,请发送你需要翻译的内容。

在定义服务时,你可以利用应用的服务提供者将类绑定到服务容器中。通常,你在onCreate()方法中进行此操作。register服务提供商的方法。

<?php

namespace AppProviders;

use IlluminateSupportServiceProvider;
use AppServicesReportService;

cla(ss AppServiceProvider extends ServiceProvider {
    public function register() {
        $this->app->bind(ReportService::class, function ($app) {
            return new ReportService();
        });
    }
}

你现在已经指示了服务容器如何解决ReportService当你需要时。

依赖注入(Dependency Injection,DI)

除了构造函数注入之外,Laravel 还支持方法注入。这种方法尤其在依赖项仅在某些控制器动作中使用时非常有用。

public function showReport(ReportService $reportService, $reportId) {
    $report = $reportService->getReport($reportId);
    return view('reports.show', compact('report'));
}

对不起,我未能理解您的问题。如果您有其他需要帮助的内容,请提供更多信息或重新描述您的需求。ReportService实例被直接注入到动作中。showReport该实例将在执行时自动解决并提供给功能。

注入多个依赖项

控制器可能需要多个服务。Laravel 可以无缝处理这种情况。

public function __construct(ReportService $reportService, LoggerService $logger) {
    $this->reportService = $reportService;
    $this->logger = $logger;
}

在这种情况下,两者都……ReportServiceand 是中文里的“和”,表示并列或联合的意思。LoggerService它们通过构造函数注入的。

使用基于接口的注入

Laravel 也可以通过接口绑定来解决依赖问题。这提高了代码的灵活性,使得依赖的实现可以被替换而不修改消费类。

interface ReportServiceInterface {
    public function createReport();
}

class SqlReportService implements ReportServiceInterface {
    // Implementation of createReport
}

// Bind interface to implementation in a service provider
$this->app->bind(ReportServiceInterface::class, SqlReportService::class);

在控制器:

public function __construct(ReportServiceInterface $reportService) {
    $this->reportService = $reportService;
}

现在 Laravel 的容器将会注入一个实例。SqlReportService无论哪里都可以。ReportServiceInterface类型提示。

高级技术:上下文绑定和标签

Laravel 提供了更高级的依赖注入(DI)功能,例如上下文绑定和标签,允许您为特定情况定义具体的实现,并通过标签来标记多个服务并以数组的形式进行解耦。

$this->app->when(PhotoController::class)
  ->needs(RepositoryInterface::class)
  ->give(PhotoRepository::class);

$this->app->tag(['ReportService', 'LoggingService'], 'app.services');

$services = $this->app->tagged('app.services');

这些功能使开发人员能够更好地控制其服务架构,特别是对于复杂的应用程序。

结论。

Laravel的DI系统提供了一种强大的、灵活的方式来管理类依赖关系。掌握在Laravel中使用依赖注入,可以为编写更加清洁、可维护和测试的代码铺平道路,通过将类与其依赖项解耦并促进井然有序的服务架构来实现这一目标。

长工码奴1523

长工码奴1523

在Laravel框架中,你可以通过以下几种方式向控制器注入依赖:

  1. 使用依赖注入容器(DI)

    Laravel提供了一个名为IlluminateSupportServiceProvider的类,它允许你在应用的配置文件中注册服务提供商。服务提供者是为了解决依赖注入问题而设计的。

    // 在config/app.php 文件中
    
    'providers' => [
        IlluminateSupportServiceProvider::class,
    ],
  2. 使用依赖注入器(DI Container)

    你也可以直接创建一个新的依赖注入器,并将你的服务添加到其中。例如,如果你有一个名为UserRepository的服务,你可以这样操作:

    class UserRepository extends RepositoryInterface
    {
        protected $model = User::class;
    }
  3. 使用 Lumen 的 container() 方法

    如果你正在开发一个基于Lumen的项目,那么可以使用container()方法来注入依赖。这是一个更简洁的方法:

    public function boot()
    {
        $this->app->make('container');
    }
  4. 在控制器中注入依赖

    在控制器的构造函数中,你可以注入需要的依赖:

    <?php
    
    namespace AppHttpControllers;
    
    use AppModelsUser;
    use IlluminateContractsAuthAuthenticatable;
    
    class UserController extends Controller
    {
        /**
         * @var Authenticatable
         */
        private $authModel;
    
        public function __construct(Authenticatable $authModel)
        {
            $this->authModel = $authModel;
        }
    
        public function index()
        {
            return view('welcome', ['users' => $this->authModel->all()]);
        }
    }
  5. 使用 make() 方法

    Laravel还提供了make()方法,它可以用来创建新的模型和控制器等。这个方法接受一系列参数,包括依赖项。

    <?php
    
    namespace AppHttpControllers;
    
    use AppHttpRequestsCreateUserControllerRequest;
    use AppModelsUser;
    use IlluminateFoundationBusDispatchesJobs;
    use IlluminateRoutingController as BaseController;
    use IlluminateFoundationValidationValidatesRequests;
    use IlluminateFoundationAuthAccessAuthorizesRequests;
    
    abstract class Controller extends BaseController
    {
        use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
    
        protected $authModel;
    
        public function __construct(User $authModel)
        {
            $this->authModel = $authModel;
        }
    
        abstract public function index();
    }
    
    class UserController extends Controller
    {
        protected $authModel;
    
        public function __construct(User $authModel)
        {
            $this->authModel = $authModel;
        }
    
        public function index()
        {
            return view('welcome', ['users' => $this->authModel->all()]);
        }
    }
  6. 在路由中注入依赖

    在路由的定义中,你也可以注入依赖:

    Route::get('/users', [UserController::class, 'index']);
  7. 使用工厂模式

    Laravel也支持工厂模式,这是一种构建对象的方式,可以让你自定义对象的行为。

    <?php
    
    namespace AppHttpControllers;
    
    use AppModelsUser;
    use AppFactoriesFactoryFactory;
    use IlluminateContractsAuthAuthenticatable;
    
    class UserController extends Controller
    {
        protected $authModel;
    
        public function __construct(FactoryFactory $factory)
        {
            $this->authModel = $factory->create(User::class);
        }
    
        public function index()
        {
            return view('welcome', ['users' => $this->authModel->all()]);
        }
    }

以上就是在Laravel中向控制器注入依赖的一些常用方法。根据你的需求选择合适的方式来实现依赖注入。