Yii2,Component,创建一个实例并在Web应用程序中随处访问它
Yii2, Component, Make a single instance and access it everywhere in the web application
我想在 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 告诉我 class 不存在。我也希望像应用程序中的其他组件一样拥有智能感知。
智能感知:
无智能:
更新:#
我能够按照以下答案的建议添加这一行来让智能感知工作。 /** @var ContentComponent $contentManager */
然而,每次我想使用内容组件时,我都厌倦了总是在上面输入这些内容。因此,我在需要内容组件的组件的基础 class 中创建了一个函数,该组件使用 Yii::app->content 方法 return 大陆组件。在 return 内容组件的函数上方,我添加了注释,它会 return ContentComponent 和 class 的 ContentComponent。现在为了让我使用具有智能感知功能的组件。我所要做的就是 $this->getContentComponent。 Php 风暴将能够识别内容组件属于 class returned。贝娄就是一个例子。
class BaseClass extends object
{
/**
* @return ContentComponent
*/
function getContentComponent () {
$contentComponent = Yii::app->content;
return $contentComponent
}
}
class SomeClass extends BaseClass
public function someFunction () {
$contentComponent = $this->getContentComponent;
}
一旦您在配置文件中声明了 content
组件
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
],
],
然后您可以使用
引用该组件
Yii::$app->content
例如
Yii::$app->content->yourMethod();
最终添加 use Yii;
或参考使用 \Yii::$app->content
PHPStorm 无法识别您的自定义组件,因为它们是在框架加载时动态创建并在运行时附加到 Yii::$app
,这就是 PHPStorm 无法识别您的组件的原因自定义组件。因此,在有人为像 PHPStorm 这样的 IDE 开发智能插件之前,您必须进行一些调整才能实现您的目标。
您有 2 个选择:
创建一个新的 Yii.php
文件(在根目录中)以供参考
必要的文档,这将在整个项目中告诉 PHPStorm
关于你的组件(我在这里放了一个完整的例子,如果你想创建仅适用于 console/web/both 的组件)看看 * @property ContentManagerComponent $content
(More read - 归功于 Yii 之一的 samdark Alexander Makarov核心贡献者):
<?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 或任何其他公司提供原生支持)插件)
我使用以下方法进行智能感知。
1.Set 配置中的组件。
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
'content2' => [
'class' => 'app\components\ContentManagerComponent2',
],
],
],
2.Have 一个 AppComponents
特质 ,记录你的 $app
拥有的所有实例。我喜欢把它放在 components/
目录中。
<?php
namespace app\components;
/**
* Trait AppComponents
* @package app\components
*
* @property ContentManagerComponent1 $content
* @property ContentManagerComponent2 $content2
*/
trait AppComponents {}
3.ReturnYii::$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
class,并用 Root::app()
替换 \Yii::$app
。所有 控制器 都可以继承自 Root
class。在扩展 Controllers.
中编码时,您也可以使用 self::app()
我想在 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 告诉我 class 不存在。我也希望像应用程序中的其他组件一样拥有智能感知。
智能感知:
无智能:
更新:#
我能够按照以下答案的建议添加这一行来让智能感知工作。 /** @var ContentComponent $contentManager */ 然而,每次我想使用内容组件时,我都厌倦了总是在上面输入这些内容。因此,我在需要内容组件的组件的基础 class 中创建了一个函数,该组件使用 Yii::app->content 方法 return 大陆组件。在 return 内容组件的函数上方,我添加了注释,它会 return ContentComponent 和 class 的 ContentComponent。现在为了让我使用具有智能感知功能的组件。我所要做的就是 $this->getContentComponent。 Php 风暴将能够识别内容组件属于 class returned。贝娄就是一个例子。
class BaseClass extends object
{
/**
* @return ContentComponent
*/
function getContentComponent () {
$contentComponent = Yii::app->content;
return $contentComponent
}
}
class SomeClass extends BaseClass
public function someFunction () {
$contentComponent = $this->getContentComponent;
}
一旦您在配置文件中声明了 content
组件
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
],
],
然后您可以使用
引用该组件 Yii::$app->content
例如
Yii::$app->content->yourMethod();
最终添加 use Yii;
或参考使用 \Yii::$app->content
PHPStorm 无法识别您的自定义组件,因为它们是在框架加载时动态创建并在运行时附加到 Yii::$app
,这就是 PHPStorm 无法识别您的组件的原因自定义组件。因此,在有人为像 PHPStorm 这样的 IDE 开发智能插件之前,您必须进行一些调整才能实现您的目标。
您有 2 个选择:
创建一个新的
Yii.php
文件(在根目录中)以供参考 必要的文档,这将在整个项目中告诉 PHPStorm 关于你的组件(我在这里放了一个完整的例子,如果你想创建仅适用于 console/web/both 的组件)看看* @property ContentManagerComponent $content
(More read - 归功于 Yii 之一的 samdark Alexander Makarov核心贡献者):<?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 或任何其他公司提供原生支持)插件)
我使用以下方法进行智能感知。
1.Set 配置中的组件。
$config = [
'components' => [
'content' => [
'class' => 'app\components\ContentManagerComponent',
],
'content2' => [
'class' => 'app\components\ContentManagerComponent2',
],
],
],
2.Have 一个 AppComponents
特质 ,记录你的 $app
拥有的所有实例。我喜欢把它放在 components/
目录中。
<?php
namespace app\components;
/**
* Trait AppComponents
* @package app\components
*
* @property ContentManagerComponent1 $content
* @property ContentManagerComponent2 $content2
*/
trait AppComponents {}
3.ReturnYii::$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
class,并用 Root::app()
替换 \Yii::$app
。所有 控制器 都可以继承自 Root
class。在扩展 Controllers.
self::app()