Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.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 如何将配置的应用程序组件注入模型实例?_Php_Dependency Injection_Yii2_Yii2 Basic App - Fatal编程技术网

Php 如何将配置的应用程序组件注入模型实例?

Php 如何将配置的应用程序组件注入模型实例?,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的配置的实例注入到搜索模型的实例中。是否有可能以更干净的方式实现我的目标

我在主题中描述了一个问题。让我解释一下。我使用基本的应用程序模板。我有一个简单的模型搜索,它使用应用程序组件GoogleCustomSearch通过GoogleCustomSearchAPI进行搜索。GoogleCustomSearch必须配置Google API密钥和搜索引擎ID。I通过application config/web.php指定Google API密钥和搜索引擎ID。我想将GoogleCustomSearch的配置的实例注入到搜索模型的实例中。是否有可能以更干净的方式实现我的目标(解决方法如下)

文件:models/Search.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;
    ...
}
文件: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中,我设置了
    GoogleCustomSearch
    ,而不是搜索模型:

    Yii::$container->set(GoogleCustomSearch::类,函数(container$container,$params,$config){ 返回Yii::$app->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()
    ;