Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php DI对象方法_Php_Symfony_Dependency Injection_Silex - Fatal编程技术网

Php DI对象方法

Php DI对象方法,php,symfony,dependency-injection,silex,Php,Symfony,Dependency Injection,Silex,如何在某些对象方法中注入依赖项而不是构造函数 下面的示例适用于_构造函数注入 如何在indexAction中注入DateTime对象 app.php $app['index.controller'] = $app->share(function() use ($app) { return new Controllers\IndexController(new \DateTime()); }); IndexController.php namespace Moo\

如何在某些对象方法中注入依赖项而不是构造函数

下面的示例适用于_构造函数注入

如何在indexAction中注入DateTime对象

app.php

 $app['index.controller'] = $app->share(function() use ($app) {
       return new Controllers\IndexController(new \DateTime());
     });
IndexController.php

namespace Moo\Controllers;

class IndexController
{
  private $date;
  public function __construct(\DateTime $date)
  {
    $this->date = $date;
  }
  public function indexAction()
  {
   return $this->date->format('y-m-d');
  }
}

如果您的类根据调用的方法具有不同的依赖项,那么这些方法可能应该在单独的类中定义

对于控制器,我认为规则很简单。操作方法所需的依赖项应通过构造函数传递。请求附带的任何内容都应作为方法参数

我不确定你想注入什么样的依赖关系如果它们只是服务,那么您应该将控制器拆分为多个类。大量构造函数参数是一种代码味道。很好,你关心它,但你试图用错误的方式解决它

如果请求附带依赖项,则应将其注入控制器方法(操作)控制器方法应接受请求并返回响应。

所有路由占位符都将自动注册为请求属性。因此,如果您的日期来自一个请求:

$app->get('/my/path/{date}', 'index.controller:indexAction');
它将作为请求属性提供:

public function indexAction(Request $request)
{
    $request->attributes->get('date');
}
任何请求属性都可以直接注入控制器:

public function indexAction($date)
{
}
这也意味着,如果手动设置请求属性,则可以将其注入控制器。它由名称匹配:

// somewhere in your code (event perhaps)
$request->attributes->set('myDate', new \DateTime());

// in your controller
public function indexAction(\DateTime $myDate)
{
}
最后,您可以将请求附带的简单类型转换为更复杂的类型


阅读文档了解更多信息。

只是为了记录,因为您可能不想这样做,实际上,可以使用extend方法在Silex中进行方法注入(事实上,负责注入的是Pimple容器):


将其注入构造函数有什么问题?如果我有5个方法,每个方法都需要处理不同的对象,该怎么办。只在依赖的方法中而不是在构造函数中注入每个对象是不合理的吗?那么让所有对象都在一个数组中呢?或者您可以为特定对象调用的服务?php的类对象被设计成在运行“actions”和“dependencyInjection”之前有一个构造函数来设置属性,因为您的所有操作都是这个类的一部分,所以您可能也会考虑为不同的对象使用不同的控制器,我想这是一个带有“通用对象getter”的服务是您正在寻找的方法注入的下注解决方案。它在拉雷维尔5号。您可以从中找到灵感,因为它是基于Symfony组件构建的。它每次都会注入deps,不是吗?因为服务是共享的,所以它不会在每次您想要从容器中检索它时创建一个新实例,因此它不会每次调用extend方法,只有在创建服务时,但我可能完全错了:-)我不在我的开发计算机上,所以我现在无法测试它,值得记住并在家尝试。我的意思是,每次初始化服务时,它都会注入所有的DEP。它初始化一次,但是所有的服务都被注入,甚至那些不一定要被使用的服务。这不是我们可以用容器解决的问题,责任需要分离。确切地说,它将注入依赖项,即使它们可能不需要,我完全同意“这不是我们可以用容器解决的问题,责任需要分离”。我只是想说明方法注入是可能的,但正如您所指出的,可能不是要走的路线
$callback = function ($post, Request $request) {
    return new Post($request->attributes->get('slug'));
};

$app->get('/blog/{id}/{slug}', 'your.controller:indexAction')
    ->convert('post', $callback);
<?php

$app['some_service'] = $app->share(function() use ($app) {
  return SomeClass($app['some_dependency']);
});

$app['some_service'] = $app->extend('some_service', function($instance, $app) {
   $instance->setSomeDependency($app['another_dependency']);

   return $instance;
});