【问题标题】:Injecting parameters into constructor with PHP-DI使用 PHP-DI 将参数注入构造函数
【发布时间】:2016-03-26 11:33:10
【问题描述】:

我正在努力让依赖注入以我期望的方式工作 -

我正在尝试注入一个类 Api,它需要知道为特定用户连接到哪个服务器。这意味着在配置文件中覆盖构造函数属性是没有用的,因为每个用户可能需要连接到不同的服务器。

class MyController {
    private $api;

    public function __construct(Api $api) {
        $this->api = $api;
    }
}

class Api {
     private $userServerIp;

     public function __construct($serverip) {
         $this->userServerIp = $serverip;
     }
}

如何使用正确的参数注入此类?是否可以以某种方式覆盖定义?有没有办法通过带参数调用容器来获取类?

为了(希望)澄清一下 - 我正在尝试调用容器来实例化一个对象,同时将原本在定义中的参数传递给它。

【问题讨论】:

    标签: php containers controllers php-di


    【解决方案1】:

    由于 IP 取决于用户,您可能有一些逻辑来执行 user=>serverIP 映射。它可能是从 db 或简单的基于 id 的分片中读取,或者其他什么。使用该逻辑,您可以构建ApiFactory 服务,为特定用户创建Api

    class ApiFactory {
    
        private function getIp(User $user) {
            // simple sharding between 2 servers based on user id
            // in a real app this logic is probably more complex - so you will extract it into a separate class
    
            $ips = ['api1.example.com', 'api2.example.com'];
            $i = $user->id % 2;
            return $ips[$i];
        }
    
        public function createForUser(User $user) {
            return new Api($this->getIp($user);
        }
    }
    

    现在,您可以注入ApiFactory,而不是将Api 注入您的控制器(假设您的控制器知道它需要Api 实例的用户)

    class MyController {
        private $apiFactory;
    
        public function __construct(ApiFactory $apiFactory) {
            $this->apiFactory = $apiFactory;
        }
    
        public function someAction() {
            $currentUser = ... // somehow get the user - might be provided by your framework, or might be injected as well
            $api = $this->apiFactory->createForUser($currentUser);
            $api->makeSomeCall();
        }
    }
    

    【讨论】:

      【解决方案2】:

      我不确定我是否完全理解您的问题,但您可以像这样配置您的 Api 类:

      return [
          'Foo' => function () {
              return new Api('127.0.0.1');
          },
      ];
      

      查看文档以获取更多示例或详细信息:http://php-di.org/doc/php-definitions.html


      编辑:

      return [
          'foo1' => function () {
              return new Api('127.0.0.1');
          },
          'foo2' => function () {
              return new Api('127.0.0.2');
          },
      ];
      

      【讨论】:

      • 嗨,-是的,所以在这个定义中,所有 Api 对象都将具有 IP '127.0.0.1' - 我如何调用容器以便它使用不同的 IP 实例化 Api?
      • @PointToPoint 请查看编辑。还要阅读文档,尝试一些事情并解释您尝试过的内容,最好了解您被阻止的位置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 2017-03-29
      • 2011-10-19
      • 1970-01-01
      • 2018-04-04
      相关资源
      最近更新 更多