草庐IT

php - 依赖注入(inject) Slim Framework 3

coder 2024-01-02 原文

我正在使用 Slim Framework 3 创建 API。应用程序结构是:MVCP(模型、 View 、 Controller 、提供者)。

是否可以让 Slim Dependency Inject 我所有的类?

我正在使用 composer 来自动加载我所有的依赖项。

我的目录结构是这样的:

/app
   - controllers/
   - Models/
   - services/
   index.php
/vendor
 composer.json

这是我的 composer.json 文件。

{
  "require": {
    "slim/slim": "^3.3",
    "monolog/monolog": "^1.19"
  },
  "autoload" : {
    "psr-4" : {
        "Controllers\\" : "app/controllers/",
        "Services\\" : "app/services/",
        "Models\\" : "app/models/"
    }
  }
}

这是我的 index.php 文件。同样,依赖项由 Composer 自动注入(inject)

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

$container = new \Slim\Container;
$app = new \Slim\App($container);

$app->get('/test/{name}', '\Controllers\PeopleController:getEveryone');

$app->run();

我的 Controller 看起来像这样

<?php #controllers/PeopleController.php

namespace Controllers;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;


class PeopleController
{
    protected $peopleService;

    protected $ci;
    protected $request;
    protected $response;

    public function __construct(Container $ci, PeopleService $peopleService)
    {
        $this->peopleService = $peopleService;
        $this->ci = $ci;
    }

    public function getEveryone($request, $response)
    {
        die($request->getAttribute('name'));

        return $this->peopleService->getAllPeoples();
    }
}

我的 PeopleService 文件如下所示:

<?php

namespace Services;

use Model\PeopleModel;
use Model\AddressModel;
use Model\AutoModel;


class PeopleService
{
    protected $peopleModel;
    protected $autoModel;
    protected $addressModel;

    public function __construct(PeopleModel $peopleModel, AddressModel $addressModel, AutoModel $autoModel)
    {
        $this->addressModel = $addressModel;
        $this->autoModel = $autoModel;
        $this->peopleModel = $peopleModel;
    }

    public function getAllPeopleInfo()
    {
        $address = $this->addressModel->getAddress();
        $auto = $this->autoModel->getAutoMake();
        $person = $this->peopleModel->getPeople();

        return [
            $person[1], $address[1], $auto[1]
        ];
    }
}

模型/AddressModels.php

<?php

namespace Model;

class AddressModel
{

    public function __construct()
    {
        // do stuff
    }

    public function getAddress()
    {
        return [
            1 => '123 Maple Street',
        ];
    }
}

模型/AutoModel.php

namespace Model;

class AutoModel
{

    public function __construct()
    {
        // do stuff
    }

    public function getAutoMake()
    {
        return [
            1 => 'Honda'
        ];
    }
}

模型/PeopleModel.php

<?php
namespace Model;

class PeopleModel
{

    public function __construct()
    {
        // do stuff
    }

    public function getPeople()
    {
        return [
            1 => 'Bob'
        ];
    }

}

错误 我现在收到以下错误:

PHP Catchable fatal error:  Argument 2 passed to Controllers\PeopleController::__construct() must be an instance of Services\PeopleService, none given, called in /var/www/vendor/slim/slim/Slim/CallableResolver.php on line 64 and defined in /var/www/app/controllers/PeopleController.php on line 21

问题 我如何依赖注入(inject)我所有的类?有没有办法自动告诉 Slim 的 DI 容器去做?

最佳答案

当你在可调用路由中引用一个类时,Slim 会向 DIC 请求它。如果 DIC 没有该类名的注册,那么它将实例化该类本身,将容器作为唯一参数传递给该类。

因此,要为您的 Controller 注入(inject)正确的依赖项,您只需创建自己的 DIC 工厂:

$container = $app->getContainer();
$container['\Controllers\PeopleController'] = function ($c) {
    $peopleService = $c->get('\Services\PeopleService');
    return new Controllers\PeopleController($c, $peopleService);
};

当然,您现在需要一个用于 PeopleService 的 DIC 工厂:

$container['\Services\PeopleService'] = function ($c) {
    $peopleModel = new Models\PeopleModel;
    $addressModel = new Models\AddressModel;
    $autoModel = new Models\AutoModel;
    return new Services\PeopleService($peopleModel, $addressModel, $autoModel);
};

(如果 PeopleModel、AddressModel 或 AutoModel 有依赖关系,那么您也可以为它们创建 DIC 工厂。)

关于php - 依赖注入(inject) Slim Framework 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36845725/

有关php - 依赖注入(inject) Slim Framework 3的更多相关文章

  1. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby - 这个 ruby​​ 注入(inject)魔术是如何工作的? - 2

    我今天看到了一个ruby​​代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem

  4. ruby - 有什么方法可以告诉 sidekiq 一项工作依赖于另一项工作 - 2

    有什么方法可以告诉sidekiq一项工作依赖于另一项工作,并且在后者完成之前无法开始? 最佳答案 仅使用Sidekiq;答案是否定的。正如DickieBoy所建议的那样,您应该能够在依赖作业完成时将其启动。像这样。#app/workers/hard_worker.rbclassHardWorkerincludeSidekiq::Workerdefperform()puts'Doinghardwork'LazyWorker.perform_async()endend#app/workers/lazy_worker.rbclassLaz

  5. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  6. ruby - 有人可以解释一下在 Ruby 中注入(inject)的真实、通俗易懂的用法吗? - 2

    我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有

  7. ruby - 防止SQL注入(inject)/好的Ruby方法 - 2

    Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject

  8. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  9. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  10. Ruby:映射和注入(inject)之间的区别 - 2

    在此处阅读有关SO的各种解释,它们是这样描述的:map:Themapmethodtakesanenumerableobjectandablock,andrunstheblockforeachelement注入(inject):Injecttakesavalueandablock,anditrunsthatblockonceforeachelementofthelist.希望你明白为什么我觉得它们表面上看起来很相似。我什么时候会选择一个而不是另一个,它们之间有什么明显的区别吗? 最佳答案 如果您认为inject也别名为reduce,这

随机推荐