我想在yii2中创建一个可以在整个Web应用程序中访问的组件,但只创建一个实例并能够在任何需要的地方检索该实例。
namespace app\components;
use yii;
use yii\base\Object;
class ContentManagerComponent extends Object
{
public function init(){
parent::init();
}
public function toBeUsed (){
return 'some variable';
}
}
然后我希望能够在Web应用程序的其他部分中调用该组件,就像在控制器中一样。
namespace app\Controllers;
use yii;
use app\controllers\
class SomeController extends Controller {
public function actionDoSomething(){
$contentComponent = Yii::$app->content;
$someVariable = $contentComponent->toBeUsed()
return $this->render( 'someView',[
'variable' => $someVariable,
]
}
}
我还将组件放在web.php文件中。
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
],
],
我最终得到的是phpstorm告诉我该课程不存在。我也想像应用程序中的其他组件一样拥有智能感知。
智能感知:
noIntele:
我可以通过添加以下答案建议的这一行来获得智能感知。 / ** @var ContentComponent $ contentManager * / 但是,每次我想使用内容组件时,我总是厌倦了输入。所以我在需要Content Component的组件的基类中创建了一个函数,它使用Yii :: app-> content方法返回Continent Component。在返回内容组件的函数上方,我添加了注释,它将返回ContentComponent和ContentComponent的类。现在为了让我使用具有智能感知功能的组件。我所要做的只是$ this-> getContentComponent。 Php storm将能够识别内容组件是返回的类。贝娄就是一个例子。
class BaseClass extends object
{
/**
* @return ContentComponent
*/
function getContentComponent () {
$contentComponent = Yii::app->content;
return $contentComponent
}
}
class SomeClass extends BaseClass
public function someFunction () {
$contentComponent = $this->getContentComponent;
}
答案 0 :(得分:2)
在配置文件中声明了content
组件后
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
],
],
然后你可以使用
来引用组件 Yii::$app->content
例如
Yii::$app->content->yourMethod();
最终添加use Yii;
或使用\Yii::$app->content
答案 1 :(得分:2)
PHPStorm无法识别您的自定义组件,因为它们是在框架加载时动态创建的,并且在运行时附加到Yii::$app
,这就是PHPStorm无法识别您的自定义组件的原因。因此,除非有人为PHPStorm等IDE开发智能插件,否则您必须进行一些调整才能实现目标。
您有两个选择:
创建一个新的Yii.php
文件(在根目录中)以供所有参考
必要的文档,这将告诉PHPStorm整个项目
关于你的组件(我在这里提出了一个完整的例子,如果你想创建仅适用于控制台/ web /两者的组件),请查看* @property ContentManagerComponent $content
(More read - samdark Alexander Makarov,Yii之一核心贡献者):
<?php
use app\components\ContentManagerComponent;
use yii\BaseYii;
/**
* Class Yii
* Yii bootstrap file.
* Used for enhanced IDE code autocompletion.
*/
class Yii extends BaseYii
{
/**
* @var BaseApplication|WebApplication|ConsoleApplication the application instance
*/
public static $app;
}
/**
* Class BaseApplication
* Used for properties that are identical for both WebApplication and ConsoleApplication
*
* @property ContentManagerComponent $content
*/
abstract class BaseApplication extends yii\base\Application
{
}
/**
* Class WebApplication
* Include only Web application related components here
*
*/
class WebApplication extends yii\web\Application
{
}
/**
* Class ConsoleApplication
* Include only Console application related components here
*/
class ConsoleApplication extends yii\console\Application
{
}
在任何想要使用组件的地方创建一个PHP文档 将告诉PHPStorm您的变量是组件的实例:
public function actionDoSomething()
{
/** @var ContentManagerComponent $contentComponent */
$contentComponent = Yii::$app->content;
$someVariable = $contentComponent->toBeUsed();
return $this->render('someView', [
'variable' => $someVariable,
]);
}
正如您所看到的,选项1是由Yii框架的核心贡献者之一提供的解决方案,因此我假设这是现在正确的选择(直到JetBrains或任何插件将提供本机支持)
答案 2 :(得分:0)
我将以下方法用于智能感知。
1。在config中设置组件。
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
'content2' => [
'class' => 'app\components\ContentManagerComponent2',
],
],
],
2。具有AppComponents
的特征,记录您的$app
拥有的所有实例。我喜欢将其保存在components/
目录中。
<?php
namespace app\components;
/**
* Trait AppComponents
* @package app\components
*
* @property ContentManagerComponent1 $content
* @property ContentManagerComponent2 $content2
*/
trait AppComponents {}
3。以自己的方式返回Yii::$app
。诱使编辑者相信可以返回AppComponents
。
<?php
namespace app\controllers;
use frontend\components\AppComponents;
use yii\rest\Controller;
class SiteController extends Controller {
/**
* @return \yii\web\Application|AppComponents
*/
public static function app() {
return \Yii::$app;
}
}
现在,您可以将SiteController::app()->content
与智能感知结合使用。您可以拥有一个更好的Root
类,并将\Yii::$app
替换为Root::app()
。所有 Controllers 都可以继承Root
类。在扩展的 Controllers 中进行编码时,也可以使用self::app()
。