Php 如何将配置的应用程序组件注入模型实例?
我在主题中描述了一个问题。让我解释一下。我使用基本的应用程序模板。我有一个简单的模型搜索,它使用应用程序组件GoogleCustomSearch通过GoogleCustomSearchAPI进行搜索。GoogleCustomSearch必须配置Google API密钥和搜索引擎ID。I通过application config/web.php指定Google API密钥和搜索引擎ID。我想将GoogleCustomSearch的配置的实例注入到搜索模型的实例中。是否有可能以更干净的方式实现我的目标(解决方法如下) 文件:models/Search.phpPhp 如何将配置的应用程序组件注入模型实例?,php,dependency-injection,yii2,yii2-basic-app,Php,Dependency Injection,Yii2,Yii2 Basic App,我在主题中描述了一个问题。让我解释一下。我使用基本的应用程序模板。我有一个简单的模型搜索,它使用应用程序组件GoogleCustomSearch通过GoogleCustomSearchAPI进行搜索。GoogleCustomSearch必须配置Google API密钥和搜索引擎ID。I通过application config/web.php指定Google API密钥和搜索引擎ID。我想将GoogleCustomSearch的配置的实例注入到搜索模型的实例中。是否有可能以更干净的方式实现我的目标
namespace app\models;
use app\components\GoogleCustomSearch;
use yii\base\Model;
class Search extends Model
{
/** @var GoogleCustomSearch */
protected $googleCustomSearch;
public function __construct(GoogleCustomSearch $googleCustomSearch, array $config = [])
{
$this->googleCustomSearch = $googleCustomSearch;
parent::__construct($config);
}
....
}
namespace app\components;
use yii\base\Component;
use yii\base\InvalidValueException;
class GoogleCustomSearch extends Component
{
public $searchEngineId;
public $apiKey;
...
}
文件:components/GoogleCustomSearch.php
namespace app\models;
use app\components\GoogleCustomSearch;
use yii\base\Model;
class Search extends Model
{
/** @var GoogleCustomSearch */
protected $googleCustomSearch;
public function __construct(GoogleCustomSearch $googleCustomSearch, array $config = [])
{
$this->googleCustomSearch = $googleCustomSearch;
parent::__construct($config);
}
....
}
namespace app\components;
use yii\base\Component;
use yii\base\InvalidValueException;
class GoogleCustomSearch extends Component
{
public $searchEngineId;
public $apiKey;
...
}
下面是我当前的解决方法 文件:config/bootstrap.php
use app\models\Search;
use yii\di\Container;
use yii\web\Application;
\Yii::$container->set('search', function (Container $container, $params, $config) {
$googleCustomSearch = $container->get(Application::class)->googleCustomSearch;
array_unshift($params, $googleCustomSearch);
return $container->get(Search::class, $params, $config);
});
文件:web/index.php
use yii\web\Application;
....
require (__DIR__ . '/../config/bootstrap.php');
$config = require(__DIR__ . '/../config/web.php');
\Yii::$container
->setSingleton(Application::class, [], [$config])
->get(Application::class)
->run()
;
然后打电话
/** @var Search $model */
$model = \Yii::createObject('search');
是否有更干净的方法将配置的组件注入对象实例?- 你的模型部分很好。它不知道依赖关系是如何注入的,这是正确的方法
- 在bootstrap中,我设置了
,而不是搜索模型: Yii::$container->set(GoogleCustomSearch::类,函数(container$container,$params,$config){ 返回Yii::$app->googleCustomSearch; });GoogleCustomSearch
- 不确定修改的
的目的index.php
use yii\web\Application;
....
require (__DIR__ . '/../config/bootstrap.php');
$config = require(__DIR__ . '/../config/web.php');
\Yii::$container
->setSingleton(Application::class, [], [$config])
->get(Application::class)
->run()
;
Yii::$container->set(GoogleCustomSearch::class,function(){return Yii::$app->GoogleCustomSearch;})代码>我认为这会导致初始化中出现循环是的。很可能。那么您的方法是好的,除了index.php
修改。为什么您认为index.php修改不好\Yii::$app是单例的,为什么不应该通过DI容器存储和访问它?我不是在争论,只是想知道我可能错过了什么。把所有东西都放进容器里是没有意义的。在这种特殊情况下,什么都没有实现,但调用变得有点复杂。
use yii\web\Application;
....
require (__DIR__ . '/../config/bootstrap.php');
$config = require(__DIR__ . '/../config/web.php');
\Yii::$container
->setSingleton(Application::class, [], [$config])
->get(Application::class)
->run()
;