類別 yii\di\Container
繼承 | yii\di\Container » yii\base\Component » yii\base\BaseObject |
---|---|
實作 | yii\base\Configurable |
自版本起可用 | 2.0 |
原始碼 | https://github.com/yiisoft/yii2/blob/master/framework/di/Container.php |
Container 實作了依賴注入容器。
依賴注入 (DI) 容器是一個物件,它知道如何實例化和配置物件及其所有依賴的物件。有關 DI 的更多資訊,請參閱 Martin Fowler 的文章。
Container 支援建構函式注入以及屬性注入。
要使用 Container,您首先需要呼叫 set() 來設定類別依賴項。然後,您呼叫 get() 來建立新的類別物件。Container 將自動實例化依賴物件、將它們注入到正在建立的物件中、進行設定,並最終傳回新建立的物件。
預設情況下,Yii::$container 指的是 Container 實例,Yii::createObject() 使用它來建立新的物件實例。當您建立新物件時,可以使用此方法來取代 new
運算子,這讓您能夠享有自動依賴項解析和預設屬性設定的好處。
以下是 Container 的使用範例
namespace app\models;
use yii\base\BaseObject;
use yii\db\Connection;
use yii\di\Container;
interface UserFinderInterface
{
function findUser();
}
class UserFinder extends BaseObject implements UserFinderInterface
{
public $db;
public function __construct(Connection $db, $config = [])
{
$this->db = $db;
parent::__construct($config);
}
public function findUser()
{
}
}
class UserLister extends BaseObject
{
public $finder;
public function __construct(UserFinderInterface $finder, $config = [])
{
$this->finder = $finder;
parent::__construct($config);
}
}
$container = new Container;
$container->set('yii\db\Connection', [
'dsn' => '...',
]);
$container->set('app\models\UserFinderInterface', [
'class' => 'app\models\UserFinder',
]);
$container->set('userLister', 'app\models\UserLister');
$lister = $container->get('userLister');
// which is equivalent to:
$db = new \yii\db\Connection(['dsn' => '...']);
$finder = new UserFinder($db);
$lister = new UserLister($finder);
有關 Container 的更多詳細資訊和使用方式,請參閱關於 di-containers 的 指南文章。
公共屬性
屬性 | 類型 | 描述 | 定義於 |
---|---|---|---|
$behaviors | yii\base\Behavior[] | 附加到此組件的行為列表。 | yii\base\Component |
$definitions | array | 物件定義或已載入的共享物件列表 (類型或 ID => 定義或實例)。 | yii\di\Container |
$resolveArrays | boolean | 是否嘗試解析陣列依賴項中的元素。 | yii\di\Container |
$singleton | string | 類別名稱、介面名稱或別名 | yii\di\Container |
$singletons | array | 單例定義的陣列。 | yii\di\Container |
公共方法
保護方法
方法 | 描述 | 定義於 |
---|---|---|
build() | 建立指定類別的實例。 | yii\di\Container |
getDependencies() | 傳回指定類別的依賴項。 | yii\di\Container |
mergeParams() | 將使用者指定的建構子參數與透過 set() 註冊的參數合併。 | yii\di\Container |
normalizeDefinition() | 正規化類別定義。 | yii\di\Container |
resolveDependencies() | 透過以實際物件實例取代依賴項來解析依賴項。 | yii\di\Container |
屬性詳細資訊
類別名稱、介面名稱或別名
單例定義的陣列。有關陣列的允許格式,請參閱 setDefinitions()。
方法詳細資訊
定義於: yii\base\Component::__call()
呼叫不是類別方法的具名方法。
此方法將檢查是否有任何附加的行為具有具名方法,並在可用的情況下執行它。
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當呼叫未知方法時會隱式呼叫它。
public mixed __call ( $name, $params ) | ||
$name | string |
方法名稱 |
$params | array |
方法參數 |
return | mixed |
方法傳回值 |
---|---|---|
throws | yii\base\UnknownMethodException |
當呼叫未知方法時 |
public function __call($name, $params)
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $object) {
if ($object->hasMethod($name)) {
return call_user_func_array([$object, $name], $params);
}
}
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}
public void __clone ( ) |
public function __clone()
{
$this->_events = [];
$this->_eventWildcards = [];
$this->_behaviors = null;
}
定義於: yii\base\BaseObject::__construct()
建構子。
預設實作執行兩件事
- 使用給定的設定
$config
初始化物件。 - 呼叫 init()。
如果此方法在子類別中被覆寫,建議
- 建構子的最後一個參數是設定陣列,例如此處的
$config
。 - 在建構子的結尾呼叫父類別實作。
public void __construct ( $config = [] ) | ||
$config | array |
將用於初始化物件屬性的名稱-值對 |
public function __construct($config = [])
{
if (!empty($config)) {
Yii::configure($this, $config);
}
$this->init();
}
定義於: yii\base\Component::__get()
傳回組件屬性的值。
此方法將依以下順序檢查並採取相應措施
- 由 getter 定義的屬性:傳回 getter 結果
- 行為的屬性:傳回行為屬性值
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $value = $component->property;
時會隱式呼叫它。
另請參閱 __set()。
public mixed __get ( $name ) | ||
$name | string |
屬性名稱 |
return | mixed |
屬性值或行為的屬性值 |
---|---|---|
throws | yii\base\UnknownPropertyException |
如果未定義屬性 |
throws | yii\base\InvalidCallException |
如果屬性為唯寫。 |
public function __get($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
// read property, e.g. getName()
return $this->$getter();
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name;
}
}
if (method_exists($this, 'set' . $name)) {
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::__isset()
檢查屬性是否已設定,即已定義且非 null。
此方法將依以下順序檢查並採取相應措施
- 由 setter 定義的屬性:傳回屬性是否已設定
- 行為的屬性:傳回屬性是否已設定
- 對於不存在的屬性,傳回
false
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 isset($component->property)
時會隱式呼叫它。
public boolean __isset ( $name ) | ||
$name | string |
屬性名稱或事件名稱 |
return | boolean |
具名屬性是否已設定 |
---|
public function __isset($name)
{
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter() !== null;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name)) {
return $behavior->$name !== null;
}
}
return false;
}
定義於: yii\base\Component::__set()
設定組件屬性的值。
此方法將依以下順序檢查並採取相應措施
- 由 setter 定義的屬性:設定屬性值
- 格式為 "on xyz" 的事件:將處理程式附加到事件 "xyz"
- 格式為 "as xyz" 的行為:附加名為 "xyz" 的行為
- 行為的屬性:設定行為屬性值
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $component->property = $value;
時會隱式呼叫它。
另請參閱 __get()。
public void __set ( $name, $value ) | ||
$name | string |
屬性名稱或事件名稱 |
$value | mixed |
屬性值 |
throws | yii\base\UnknownPropertyException |
如果未定義屬性 |
---|---|---|
throws | yii\base\InvalidCallException |
如果屬性為唯讀。 |
public function __set($name, $value)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
// set property
$this->$setter($value);
return;
} elseif (strncmp($name, 'on ', 3) === 0) {
// on event: attach event handler
$this->on(trim(substr($name, 3)), $value);
return;
} elseif (strncmp($name, 'as ', 3) === 0) {
// as behavior: attach behavior
$name = trim(substr($name, 3));
$this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value));
return;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = $value;
return;
}
}
if (method_exists($this, 'get' . $name)) {
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
}
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::__unset()
將組件屬性設定為 null。
此方法將依以下順序檢查並採取相應措施
- 由 setter 定義的屬性:將屬性值設定為 null
- 行為的屬性:將屬性值設定為 null
請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 unset($component->property)
時會隱式呼叫它。
public void __unset ( $name ) | ||
$name | string |
屬性名稱 |
throws | yii\base\InvalidCallException |
如果屬性為唯讀。 |
---|
public function __unset($name)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
$this->$setter(null);
return;
}
// behavior property
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name)) {
$behavior->$name = null;
return;
}
}
throw new InvalidCallException('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
}
定義於: yii\base\Component::attachBehavior()
將行為附加到此組件。
此方法將根據給定的設定建立行為物件。之後,將透過呼叫 yii\base\Behavior::attach() 方法將行為物件附加到此組件。
另請參閱 detachBehavior()。
public yii\base\Behavior attachBehavior ( $name, $behavior ) | ||
$name | string |
行為的名稱。 |
$behavior | string|array|yii\base\Behavior |
行為設定。這可以是下列其中一項
|
return | yii\base\Behavior |
行為物件 |
---|
public function attachBehavior($name, $behavior)
{
$this->ensureBehaviors();
return $this->attachBehaviorInternal($name, $behavior);
}
定義於: yii\base\Component::attachBehaviors()
將行為列表附加到組件。
每個行為都依其名稱索引,並且應該是 yii\base\Behavior 物件、指定行為類別的字串,或是用於建立行為的設定陣列。
另請參閱 attachBehavior()。
public void attachBehaviors ( $behaviors ) | ||
$behaviors | array |
要附加到組件的行為列表 |
public function attachBehaviors($behaviors)
{
$this->ensureBehaviors();
foreach ($behaviors as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
定義於: yii\base\Component::behaviors()
傳回此組件應表現為的行為列表。
子類別可以覆寫此方法,以指定它們想要表現為的行為。
此方法的傳回值應該是由行為名稱索引的行為物件或設定陣列。行為設定可以是指定行為類別的字串,或是具有以下結構的陣列
'behaviorName' => [
'class' => 'BehaviorClass',
'property1' => 'value1',
'property2' => 'value2',
]
請注意,行為類別必須從 yii\base\Behavior 擴展。行為可以使用名稱或匿名方式附加。當名稱用作陣列索引鍵時,使用此名稱,稍後可以使用 getBehavior() 檢索行為,或使用 detachBehavior() 分離行為。匿名行為無法檢索或分離。
在此方法中宣告的行為將自動 (依需求) 附加到組件。
public array behaviors ( ) | ||
return | array |
行為設定。 |
---|
public function behaviors()
{
return [];
}
建立指定類別的實例。
此方法將解析指定類別的依賴項、實例化它們,並將它們注入到指定類別的新實例中。
protected object build ( $class, $params, $config ) | ||
$class | string |
類別名稱 |
$params | array |
建構子參數 |
$config | array |
要應用於新實例的設定 |
return | object |
指定類別的新建立實例 |
---|---|---|
throws | yii\di\NotInstantiableException |
如果解析為抽象類別或介面 (自 2.0.9 起) |
protected function build($class, $params, $config)
{
/* @var $reflection ReflectionClass */
list($reflection, $dependencies) = $this->getDependencies($class);
$addDependencies = [];
if (isset($config['__construct()'])) {
$addDependencies = $config['__construct()'];
unset($config['__construct()']);
}
foreach ($params as $index => $param) {
$addDependencies[$index] = $param;
}
$this->validateDependencies($addDependencies);
if ($addDependencies && is_int(key($addDependencies))) {
$dependencies = array_values($dependencies);
$dependencies = $this->mergeDependencies($dependencies, $addDependencies);
} else {
$dependencies = $this->mergeDependencies($dependencies, $addDependencies);
$dependencies = array_values($dependencies);
}
$dependencies = $this->resolveDependencies($dependencies, $reflection);
if (!$reflection->isInstantiable()) {
throw new NotInstantiableException($reflection->name);
}
if (empty($config)) {
return $reflection->newInstanceArgs($dependencies);
}
$config = $this->resolveDependencies($config);
if (!empty($dependencies) && $reflection->implementsInterface('yii\base\Configurable')) {
// set $config as the last parameter (existing one will be overwritten)
$dependencies[count($dependencies) - 1] = $config;
return $reflection->newInstanceArgs($dependencies);
}
$object = $reflection->newInstanceArgs($dependencies);
foreach ($config as $name => $value) {
$object->$name = $value;
}
return $object;
}
定義於: yii\base\Component::canGetProperty()
傳回指示屬性是否可讀取的值。
如果滿足以下條件,則可以讀取屬性
- 類別具有與指定名稱關聯的 getter 方法 (在這種情況下,屬性名稱不區分大小寫);
- 類別具有具有指定名稱的成員變數 (當
$checkVars
為 true 時); - 附加的行為具有給定名稱的可讀屬性 (當
$checkBehaviors
為 true 時)。
另請參閱 canSetProperty()。
public boolean canGetProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | string |
屬性名稱 |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此組件的屬性 |
return | boolean |
屬性是否可讀取 |
---|
public function canGetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canGetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
定義於: yii\base\Component::canSetProperty()
傳回指示屬性是否可設定的值。
如果滿足以下條件,則可以寫入屬性
- 類別具有與指定名稱關聯的 setter 方法 (在這種情況下,屬性名稱不區分大小寫);
- 類別具有具有指定名稱的成員變數 (當
$checkVars
為 true 時); - 附加的行為具有給定名稱的可寫屬性 (當
$checkBehaviors
為 true 時)。
另請參閱 canGetProperty()。
public boolean canSetProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | string |
屬性名稱 |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此組件的屬性 |
return | boolean |
屬性是否可寫入 |
---|
public function canSetProperty($name, $checkVars = true, $checkBehaviors = true)
{
if (method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->canSetProperty($name, $checkVars)) {
return true;
}
}
}
return false;
}
::class
。
定義於: yii\base\BaseObject::className()
傳回此類別的完整限定名稱。
public static string className ( ) | ||
return | string |
此類別的完整限定名稱。 |
---|
public static function className()
{
return get_called_class();
}
移除指定名稱的定義。
public void clear ( $class ) | ||
$class | string |
類別名稱、介面名稱或別名 |
public function clear($class)
{
unset($this->_definitions[$class], $this->_singletons[$class]);
}
public yii\base\Behavior|null detachBehavior ( $name ) | ||
$name | string |
行為的名稱。 |
return | yii\base\Behavior|null |
分離的行為。如果行為不存在,則為 Null。 |
---|
public function detachBehavior($name)
{
$this->ensureBehaviors();
if (isset($this->_behaviors[$name])) {
$behavior = $this->_behaviors[$name];
unset($this->_behaviors[$name]);
$behavior->detach();
return $behavior;
}
return null;
}
定義於: yii\base\Component::detachBehaviors()
從組件分離所有行為。
public void detachBehaviors ( ) |
public function detachBehaviors()
{
$this->ensureBehaviors();
foreach ($this->_behaviors as $name => $behavior) {
$this->detachBehavior($name);
}
}
定義於: yii\base\Component::ensureBehaviors()
確保在 behaviors() 中宣告的行為已附加到此組件。
public void ensureBehaviors ( ) |
public function ensureBehaviors()
{
if ($this->_behaviors === null) {
$this->_behaviors = [];
foreach ($this->behaviors() as $name => $behavior) {
$this->attachBehaviorInternal($name, $behavior);
}
}
}
傳回請求類別的實例。
您可以提供建構子參數 ($params
) 和物件設定 ($config
),它們將在建立實例期間使用。
如果類別實作了 yii\base\Configurable,則 $config
參數將作為最後一個參數傳遞給類別建構子;否則,設定將在物件實例化之後應用。
請注意,如果透過呼叫 setSingleton() 將類別宣告為單例,則每次呼叫此方法時都會傳回相同的類別實例。在這種情況下,建構子參數和物件設定僅在首次實例化類別時使用。
public object get ( $class, $params = [], $config = [] ) | ||
$class | string|yii\di\Instance |
先前透過 set() 或 setSingleton() 註冊的類別實例、名稱或別名 (例如 |
$params | array |
建構子參數值的列表。使用以下兩種定義之一
|
$config | array |
將用於初始化物件屬性的名稱-值對列表。 |
return | object |
請求類別的實例。 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果類別無法識別或對應於無效的定義 |
throws | yii\di\NotInstantiableException |
如果解析為抽象類別或介面 (自 2.0.9 起) |
public function get($class, $params = [], $config = [])
{
if ($class instanceof Instance) {
$class = $class->id;
}
if (isset($this->_singletons[$class])) {
// singleton
return $this->_singletons[$class];
} elseif (!isset($this->_definitions[$class])) {
return $this->build($class, $params, $config);
}
$definition = $this->_definitions[$class];
if (is_callable($definition, true)) {
$params = $this->resolveDependencies($this->mergeParams($class, $params));
$object = call_user_func($definition, $this, $params, $config);
} elseif (is_array($definition)) {
$concrete = $definition['class'];
unset($definition['class']);
$config = array_merge($definition, $config);
$params = $this->mergeParams($class, $params);
if ($concrete === $class) {
$object = $this->build($class, $params, $config);
} else {
$object = $this->get($concrete, $params, $config);
}
} elseif (is_object($definition)) {
return $this->_singletons[$class] = $definition;
} else {
throw new InvalidConfigException('Unexpected object definition type: ' . gettype($definition));
}
if (array_key_exists($class, $this->_singletons)) {
// singleton
$this->_singletons[$class] = $object;
}
return $object;
}
定義於: yii\base\Component::getBehavior()
傳回具名行為物件。
public yii\base\Behavior|null getBehavior ( $name ) | ||
$name | string |
行為名稱 |
return | yii\base\Behavior|null |
行為物件,如果行為不存在則為 null |
---|
public function getBehavior($name)
{
$this->ensureBehaviors();
return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;
}
定義於: yii\base\Component::getBehaviors()
傳回附加到此組件的所有行為。
public yii\base\Behavior[] getBehaviors ( ) | ||
return | yii\base\Behavior[] |
附加到此元件的行為列表 |
---|
public function getBehaviors()
{
$this->ensureBehaviors();
return $this->_behaviors;
}
傳回物件定義或已載入的共享物件列表。
public array getDefinitions ( ) | ||
return | array |
物件定義或已載入的共享物件列表 (類型或 ID => 定義或實例)。 |
---|
public function getDefinitions()
{
return $this->_definitions;
}
傳回指定類別的依賴項。
protected array getDependencies ( $class ) | ||
$class | string |
類別名稱、介面名稱或別名 |
return | array |
指定類別的依賴項。 |
---|---|---|
throws | yii\di\NotInstantiableException |
如果依賴項無法解析或依賴項無法滿足時。 |
protected function getDependencies($class)
{
if (isset($this->_reflections[$class])) {
return [$this->_reflections[$class], $this->_dependencies[$class]];
}
$dependencies = [];
try {
$reflection = new ReflectionClass($class);
} catch (\ReflectionException $e) {
throw new NotInstantiableException(
$class,
'Failed to instantiate component or class "' . $class . '".',
0,
$e
);
}
$constructor = $reflection->getConstructor();
if ($constructor !== null) {
foreach ($constructor->getParameters() as $param) {
if (PHP_VERSION_ID >= 50600 && $param->isVariadic()) {
break;
}
if (PHP_VERSION_ID >= 80000) {
$c = $param->getType();
$isClass = false;
if ($c instanceof ReflectionNamedType) {
$isClass = !$c->isBuiltin();
}
} else {
try {
$c = $param->getClass();
} catch (ReflectionException $e) {
if (!$this->isNulledParam($param)) {
$notInstantiableClass = null;
if (PHP_VERSION_ID >= 70000) {
$type = $param->getType();
if ($type instanceof ReflectionNamedType) {
$notInstantiableClass = $type->getName();
}
}
throw new NotInstantiableException(
$notInstantiableClass,
$notInstantiableClass === null ? 'Can not instantiate unknown class.' : null
);
} else {
$c = null;
}
}
$isClass = $c !== null;
}
$className = $isClass ? $c->getName() : null;
if ($className !== null) {
$dependencies[$param->getName()] = Instance::of($className, $this->isNulledParam($param));
} else {
$dependencies[$param->getName()] = $param->isDefaultValueAvailable()
? $param->getDefaultValue()
: null;
}
}
}
$this->_reflections[$class] = $reflection;
$this->_dependencies[$class] = $dependencies;
return [$reflection, $dependencies];
}
傳回指示容器是否具有指定名稱的定義的值。
另請參閱 set()。
public boolean has ( $class ) | ||
$class | string |
類別名稱、介面名稱或別名 |
return | boolean |
容器是否具有指定名稱的定義。 |
---|
public function has($class)
{
return isset($this->_definitions[$class]);
}
定義於: yii\base\Component::hasEventHandlers()
傳回指示是否有名稱事件附加任何處理程式的值。
public boolean hasEventHandlers ( $name ) | ||
$name | string |
事件名稱 |
return | boolean |
是否有任何處理器附加到事件。 |
---|
public function hasEventHandlers($name)
{
$this->ensureBehaviors();
if (!empty($this->_events[$name])) {
return true;
}
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) {
return true;
}
}
return Event::hasHandlers($this, $name);
}
定義於: yii\base\Component::hasMethod()
傳回指示是否已定義方法的值。
方法定義於:
- 類別具有指定名稱的方法
- 附加的行為具有給定名稱的方法 (當
$checkBehaviors
為 true 時)。
public boolean hasMethod ( $name, $checkBehaviors = true ) | ||
$name | string |
屬性名稱 |
$checkBehaviors | boolean |
是否將行為的方法視為此元件的方法 |
return | boolean |
方法是否已定義 |
---|
public function hasMethod($name, $checkBehaviors = true)
{
if (method_exists($this, $name)) {
return true;
} elseif ($checkBehaviors) {
$this->ensureBehaviors();
foreach ($this->_behaviors as $behavior) {
if ($behavior->hasMethod($name)) {
return true;
}
}
}
return false;
}
定義於: yii\base\Component::hasProperty()
傳回指示是否為此組件定義屬性的值。
屬性定義於:
- 類別具有與指定名稱關聯的 getter 或 setter 方法 (在這種情況下,屬性名稱不區分大小寫);
- 類別具有具有指定名稱的成員變數 (當
$checkVars
為 true 時); - 附加的行為具有給定名稱的屬性 (當
$checkBehaviors
為 true 時)。
另請參閱
public boolean hasProperty ( $name, $checkVars = true, $checkBehaviors = true ) | ||
$name | string |
屬性名稱 |
$checkVars | boolean |
是否將成員變數視為屬性 |
$checkBehaviors | boolean |
是否將行為的屬性視為此組件的屬性 |
return | boolean |
屬性是否已定義 |
---|
public function hasProperty($name, $checkVars = true, $checkBehaviors = true)
{
return $this->canGetProperty($name, $checkVars, $checkBehaviors) || $this->canSetProperty($name, false, $checkBehaviors);
}
傳回指示給定名稱是否對應於已註冊的單例的值。
public boolean hasSingleton ( $class, $checkInstance = false ) | ||
$class | string |
類別名稱、介面名稱或別名 |
$checkInstance | boolean |
是否檢查單例是否已被實例化。 |
return | boolean |
給定名稱是否對應於已註冊的單例。如果 |
---|
public function hasSingleton($class, $checkInstance = false)
{
return $checkInstance ? isset($this->_singletons[$class]) : array_key_exists($class, $this->_singletons);
}
public void init ( ) |
public function init()
{
}
呼叫回呼函數,並解析參數中的依賴項。
此方法允許調用回呼函數,並讓類型提示的參數名稱解析為 Container 的物件。它還允許使用具名參數調用函數。
例如,可以使用 Container 調用以下回呼函數來解析 formatter 依賴項
$formatString = function($string, \yii\i18n\Formatter $formatter) {
// ...
}
Yii::$container->invoke($formatString, ['string' => 'Hello World!']);
這會將字串 'Hello World!'
作為第一個參數傳遞,並將 DI 容器建立的 formatter 實例作為第二個參數傳遞給可調用項。
public mixed invoke ( callable $callback, $params = [] ) | ||
$callback | 可調用項 |
要調用的可調用項。 |
$params | array |
函數的參數陣列。這可以是參數列表,也可以是表示具名函數參數的關聯陣列。 |
return | mixed |
回呼函數的傳回值。 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果依賴項無法解析或依賴項無法滿足時。 |
throws | yii\di\NotInstantiableException |
如果解析為抽象類別或介面 (自 2.0.9 起) |
public function invoke(callable $callback, $params = [])
{
return call_user_func_array($callback, $this->resolveCallableDependencies($callback, $params));
}
將使用者指定的建構子參數與透過 set() 註冊的參數合併。
protected array mergeParams ( $class, $params ) | ||
$class | string |
類別名稱、介面名稱或別名 |
$params | array |
建構函式參數 |
return | array |
合併後的參數 |
---|
protected function mergeParams($class, $params)
{
if (empty($this->_params[$class])) {
return $params;
} elseif (empty($params)) {
return $this->_params[$class];
}
$ps = $this->_params[$class];
foreach ($params as $index => $value) {
$ps[$index] = $value;
}
return $ps;
}
正規化類別定義。
protected array normalizeDefinition ( $class, $definition ) | ||
$class | string |
類別名稱 |
$definition | string|array|callable |
類別定義 |
return | array |
標準化的類別定義 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果定義無效。 |
protected function normalizeDefinition($class, $definition)
{
if (empty($definition)) {
return ['class' => $class];
} elseif (is_string($definition)) {
return ['class' => $definition];
} elseif ($definition instanceof Instance) {
return ['class' => $definition->id];
} elseif (is_callable($definition, true) || is_object($definition)) {
return $definition;
} elseif (is_array($definition)) {
if (!isset($definition['class']) && isset($definition['__class'])) {
$definition['class'] = $definition['__class'];
unset($definition['__class']);
}
if (!isset($definition['class'])) {
if (strpos($class, '\\') !== false) {
$definition['class'] = $class;
} else {
throw new InvalidConfigException('A class definition requires a "class" member.');
}
}
return $definition;
}
throw new InvalidConfigException("Unsupported definition type for \"$class\": " . gettype($definition));
}
定義於: yii\base\Component::off()
從此組件分離現有的事件處理程式。
此方法與 on() 相反。
注意:如果為事件名稱傳遞了萬用字元模式,則只會移除使用此萬用字元註冊的處理器,而使用與此萬用字元匹配的純名稱註冊的處理器將保留。
另請參閱 on()。
public boolean off ( $name, $handler = null ) | ||
$name | string |
事件名稱 |
$handler | callable|null |
要移除的事件處理器。如果為 null,則會移除附加到具名事件的所有處理器。 |
return | boolean |
如果找到並分離處理器 |
---|
public function off($name, $handler = null)
{
$this->ensureBehaviors();
if (empty($this->_events[$name]) && empty($this->_eventWildcards[$name])) {
return false;
}
if ($handler === null) {
unset($this->_events[$name], $this->_eventWildcards[$name]);
return true;
}
$removed = false;
// plain event names
if (isset($this->_events[$name])) {
foreach ($this->_events[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_events[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_events[$name] = array_values($this->_events[$name]);
return true;
}
}
// wildcard event names
if (isset($this->_eventWildcards[$name])) {
foreach ($this->_eventWildcards[$name] as $i => $event) {
if ($event[0] === $handler) {
unset($this->_eventWildcards[$name][$i]);
$removed = true;
}
}
if ($removed) {
$this->_eventWildcards[$name] = array_values($this->_eventWildcards[$name]);
// remove empty wildcards to save future redundant regex checks:
if (empty($this->_eventWildcards[$name])) {
unset($this->_eventWildcards[$name]);
}
}
}
return $removed;
}
將事件處理程式附加到事件。
事件處理器必須是有效的 PHP 回呼函數。以下是一些範例
function ($event) { ... } // anonymous function
[$object, 'handleClick'] // $object->handleClick()
['Page', 'handleClick'] // Page::handleClick()
'handleClick' // global function handleClick()
事件處理器必須使用以下簽名定義:
function ($event)
其中 $event
是 yii\base\Event 物件,其中包含與事件關聯的參數。
自 2.0.14 版本起,您可以將事件名稱指定為萬用字元模式
$component->on('event.group.*', function ($event) {
Yii::trace($event->name . ' is triggered.');
});
另請參閱 off()。
public void on ( $name, $handler, $data = null, $append = true ) | ||
$name | string |
事件名稱 |
$handler | 可調用項 |
事件處理器 |
$data | mixed |
事件觸發時要傳遞給事件處理器的資料。調用事件處理器時,可以透過 yii\base\Event::$data 存取此資料。 |
$append | boolean |
是否將新的事件處理器附加到現有處理器列表的末尾。如果為 false,則新處理器將插入到現有處理器列表的開頭。 |
public function on($name, $handler, $data = null, $append = true)
{
$this->ensureBehaviors();
if (strpos($name, '*') !== false) {
if ($append || empty($this->_eventWildcards[$name])) {
$this->_eventWildcards[$name][] = [$handler, $data];
} else {
array_unshift($this->_eventWildcards[$name], [$handler, $data]);
}
return;
}
if ($append || empty($this->_events[$name])) {
$this->_events[$name][] = [$handler, $data];
} else {
array_unshift($this->_events[$name], [$handler, $data]);
}
}
解析函數的依賴項。
此方法可用於實作與 invoke() 在其他元件中提供的類似功能。
public array resolveCallableDependencies ( callable $callback, $params = [] ) | ||
$callback | 可調用項 |
要調用的可調用項。 |
$params | array |
函數的參數陣列,可以是數值或關聯陣列。 |
return | array |
已解析的依賴項。 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果依賴項無法解析或依賴項無法滿足時。 |
throws | yii\di\NotInstantiableException |
如果解析為抽象類別或介面 (自 2.0.9 起) |
public function resolveCallableDependencies(callable $callback, $params = [])
{
if (is_array($callback)) {
$reflection = new \ReflectionMethod($callback[0], $callback[1]);
} elseif (is_object($callback) && !$callback instanceof \Closure) {
$reflection = new \ReflectionMethod($callback, '__invoke');
} else {
$reflection = new \ReflectionFunction($callback);
}
$args = [];
$associative = ArrayHelper::isAssociative($params);
foreach ($reflection->getParameters() as $param) {
$name = $param->getName();
if (PHP_VERSION_ID >= 80000) {
$class = $param->getType();
if ($class instanceof \ReflectionUnionType || (PHP_VERSION_ID >= 80100 && $class instanceof \ReflectionIntersectionType)) {
$isClass = false;
foreach ($class->getTypes() as $type) {
if (!$type->isBuiltin()) {
$class = $type;
$isClass = true;
break;
}
}
} else {
$isClass = $class !== null && !$class->isBuiltin();
}
} else {
$class = $param->getClass();
$isClass = $class !== null;
}
if ($isClass) {
$className = $class->getName();
if (PHP_VERSION_ID >= 50600 && $param->isVariadic()) {
$args = array_merge($args, array_values($params));
break;
}
if ($associative && isset($params[$name]) && $params[$name] instanceof $className) {
$args[] = $params[$name];
unset($params[$name]);
} elseif (!$associative && isset($params[0]) && $params[0] instanceof $className) {
$args[] = array_shift($params);
} elseif (isset(Yii::$app) && Yii::$app->has($name) && ($obj = Yii::$app->get($name)) instanceof $className) {
$args[] = $obj;
} else {
// If the argument is optional we catch not instantiable exceptions
try {
$args[] = $this->get($className);
} catch (NotInstantiableException $e) {
if ($param->isDefaultValueAvailable()) {
$args[] = $param->getDefaultValue();
} else {
throw $e;
}
}
}
} elseif ($associative && isset($params[$name])) {
$args[] = $params[$name];
unset($params[$name]);
} elseif (!$associative && count($params)) {
$args[] = array_shift($params);
} elseif ($param->isDefaultValueAvailable()) {
$args[] = $param->getDefaultValue();
} elseif (!$param->isOptional()) {
$funcName = $reflection->getName();
throw new InvalidConfigException("Missing required parameter \"$name\" when calling \"$funcName\".");
}
}
foreach ($params as $value) {
$args[] = $value;
}
return $args;
}
透過以實際物件實例取代依賴項來解析依賴項。
protected array resolveDependencies ( $dependencies, $reflection = null ) | ||
$dependencies | array |
依賴項 |
$reflection | ReflectionClass|null |
與依賴項關聯的類別反射 |
return | array |
已解析的依賴項 |
---|---|---|
throws | yii\base\InvalidConfigException |
如果依賴項無法解析或依賴項無法滿足時。 |
protected function resolveDependencies($dependencies, $reflection = null)
{
foreach ($dependencies as $index => $dependency) {
if ($dependency instanceof Instance) {
if ($dependency->id !== null) {
$dependencies[$index] = $dependency->get($this);
} elseif ($reflection !== null) {
$name = $reflection->getConstructor()->getParameters()[$index]->getName();
$class = $reflection->getName();
throw new InvalidConfigException("Missing required parameter \"$name\" when instantiating \"$class\".");
}
} elseif ($this->_resolveArrays && is_array($dependency)) {
$dependencies[$index] = $this->resolveDependencies($dependency, $reflection);
}
}
return $dependencies;
}
向此容器註冊類別定義。
例如:
// register a class name as is. This can be skipped.
$container->set('yii\db\Connection');
// register an interface
// When a class depends on the interface, the corresponding class
// will be instantiated as the dependent object
$container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer');
// register an alias name. You can use $container->get('foo')
// to create an instance of Connection
$container->set('foo', 'yii\db\Connection');
// register a class with configuration. The configuration
// will be applied when the class is instantiated by get()
$container->set('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
// register an alias name with class configuration
// In this case, a "class" element is required to specify the class
$container->set('db', [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
// register a PHP callable
// The callable will be executed when $container->get('db') is called
$container->set('db', function ($container, $params, $config) {
return new \yii\db\Connection($config);
});
如果已存在同名的類別定義,則會以新的定義覆寫它。您可以使用 has() 來檢查類別定義是否已存在。
public set ( $class, $definition = [], array $params = [] ) | ||
$class | string |
類別名稱、介面名稱或別名 |
$definition | mixed |
與 |
$params | array |
建構函式參數列表。當調用 get() 時,參數將傳遞給類別建構函式。 |
return | $this |
容器本身 |
---|
public function set($class, $definition = [], array $params = [])
{
$this->_definitions[$class] = $this->normalizeDefinition($class, $definition);
$this->_params[$class] = $params;
unset($this->_singletons[$class]);
return $this;
}
在此容器中註冊類別定義。
另請參閱 set(),以瞭解有關定義的可能值的更多資訊。
public void setDefinitions ( array $definitions ) | ||
$definitions | array |
定義陣列。陣列有兩種允許的格式。第一種格式
範例:
]);
第二種格式
範例:
]);
|
public function setDefinitions(array $definitions)
{
foreach ($definitions as $class => $definition) {
if (is_array($definition) && count($definition) === 2 && array_values($definition) === $definition && is_array($definition[1])) {
$this->set($class, $definition[0], $definition[1]);
continue;
}
$this->set($class, $definition);
}
}
public void setResolveArrays ( $value ) | ||
$value | boolean |
是否嘗試解析陣列依賴項中的元素 |
public function setResolveArrays($value)
{
$this->_resolveArrays = (bool) $value;
}
向此容器註冊類別定義,並將類別標記為單例類別。
此方法與 set() 類似,不同之處在於透過此方法註冊的類別只會有一個實例。每次調用 get() 時,都會傳回指定類別的相同實例。
另請參閱 set()。
public $this setSingleton ( $class, $definition = [], array $params = [] ) | ||
$class | string |
類別名稱、介面名稱或別名 |
$definition | mixed |
與 |
$params | array |
建構函式參數列表。當調用 get() 時,參數將傳遞給類別建構函式。 |
return | $this |
容器本身 |
---|
public function setSingleton($class, $definition = [], array $params = [])
{
$this->_definitions[$class] = $this->normalizeDefinition($class, $definition);
$this->_params[$class] = $params;
$this->_singletons[$class] = null;
return $this;
}
透過呼叫 setSingleton(),將類別定義註冊為此容器內的單例。
另請參閱
- setDefinitions() 以瞭解 $singletons 參數的允許格式。
- setSingleton() 以瞭解有關定義的可能值的更多資訊。
public void setSingletons ( array $singletons ) | ||
$singletons | array |
單例定義的陣列。有關陣列的允許格式,請參閱 setDefinitions()。 |
public function setSingletons(array $singletons)
{
foreach ($singletons as $class => $definition) {
if (is_array($definition) && count($definition) === 2 && array_values($definition) === $definition) {
$this->setSingleton($class, $definition[0], $definition[1]);
continue;
}
$this->setSingleton($class, $definition);
}
}
public void trigger ( $name, yii\base\Event $event = null ) | ||
$name | string |
事件名稱 |
$event | yii\base\Event|null |
事件實例。如果未設定,將會建立預設的 yii\base\Event 物件。 |
public function trigger($name, Event $event = null)
{
$this->ensureBehaviors();
$eventHandlers = [];
foreach ($this->_eventWildcards as $wildcard => $handlers) {
if (StringHelper::matchWildcard($wildcard, $name)) {
$eventHandlers[] = $handlers;
}
}
if (!empty($this->_events[$name])) {
$eventHandlers[] = $this->_events[$name];
}
if (!empty($eventHandlers)) {
$eventHandlers = call_user_func_array('array_merge', $eventHandlers);
if ($event === null) {
$event = new Event();
}
if ($event->sender === null) {
$event->sender = $this;
}
$event->handled = false;
$event->name = $name;
foreach ($eventHandlers as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
// stop further handling if the event is handled
if ($event->handled) {
return;
}
}
}
// invoke class-level attached handlers
Event::trigger($this, $name, $event);
}
註冊 或 登入 以發表評論。