Answer the question
In order to leave comments, you need to log in
How does Yii::app() work?
As far as I understand, Yii::app() is a method through which you can access the services registered in the framework. What is DI and Service Locator I know and understand that Yii::app() implements access to them. But how exactly? How does the name of the service get into the app() method, how to implement it?
Answer the question
In order to leave comments, you need to log in
1. Initialization of Yii::app()
Look, there are such lines in the www/index.php file
1. $config = APP_PATH . '/protected/config/main.php';
2. $app = \Yii::createWebApplication($config); // @var CWebApplication $app
3. $app->run();
1. class YiiBase {
2. {
3. // ... другой код
4.
5. public static function createWebApplication($config=null)
6. {
7. return self::createApplication('CWebApplication',$config);
8. }
9.
10. public static function createApplication($class,$config=null)
11. {
12. return new $class($config);
13. }
14. }
return new CWebApplication($config);
1. abstract class CApplication extends CModule
2. {
3. // ... другой код
4.
5. public function __construct($config=null)
6. {
7. Yii::setApplication($this);
8. // ... и другой код
9. }
10. }
Yii::setApplication($this);
, and if you look at the class Yii
and its parent YiiBase
, you can see how the variable for the construction is eventually initializedYii::app()
class YiiBase {
{
private static $_app;
public static function setApplication($app) // тут определяется значение self::$_app для Yii::app()
{
if(self::$_app===null || $app===null)
self::$_app=$app;
else
throw new CException(Yii::t('yii','Yii application can only be created once.'));
}
public static function app() // тут можно прочитать значение self::$_app через Yii::app()
{
return self::$_app;
}
}
CWebApplication
this entity was set to a private variable YiiBase::$_app
, which is available through the call Yii::app()
CApplication
abstract class CApplication extends CModule
{
public function __construct($config=null)
{
Yii::setApplication($this);
// ... другой код
$this->configure($config);
// ... другой код
}
}
configure($config)
prepares data that will be needed later for such calls as (for example) Yii::app()->db
abstract class CModule extends CComponent
{
public function configure($config) // сохранить всё что передали по переменным
{
if(is_array($config))
{
foreach($config as $key=>$value)
$this->$key=$value;
}
}
public function __get($name) // если кто-то пытается вызвать несуществующее свойство, например Yii::app()->db
{
if($this->hasComponent($name)) // проверить что есть настройки или готовая сущность компоненты
return $this->getComponent($name); // вернуть сущность компоненты
else
return parent::__get($name);
}
public function hasComponent($id) // проверить что есть настройки или готовая сущность компоненты
{
return isset($this->_components[$id]) || isset($this->_componentConfig[$id]);
}
public function getComponent($id,$createIfNull=true) // вернуть сущность компоненты
{
if(isset($this->_components[$id])) // если есть готовая сущность компоненты, вернуть её
return $this->_components[$id];
elseif(isset($this->_componentConfig[$id]) && $createIfNull)
{
$config=$this->_componentConfig[$id];
if(!isset($config['enabled']) || $config['enabled'])
{
unset($config['enabled']);
$component=Yii::createComponent($config); // создать новую сущность компоненты
$component->init();
return $this->_components[$id]=$component; // сохранить и вернуть её
}
}
}
}
Yii::app()->db
Yii::app()
it is an entity of type CWebApplication
, and it does not have a public property $db
, so PHP calls the magic method __get()
from the base class CModule
. (Look in the documentation "magic methods") CWebApplication->db
does not exist and is called CModule->__get('db')
, then the code considers that the component may be called. CModule->hasComponent('db')
checks that some settings were previously set specified through the configuration file protected/config/main.php
or otherwise. If so, then is called CModule->getComponent('db', ...)
, which calls Yii::createComponent($config)
, where $config
are the found settings of the specified component, for example, the database connection parameters for the db component Yii::createComponent($config)
class YiiBase
{
public static function createComponent($config)
{
// посмотри сам, тут интересно
}
}
CModule::createComponent()
can be called from anywhere and it has a lot of options for passing parameters. CModule::createComponent()
created and returned a new entity. And at the exit from the method, the CModule::getComponent()
resulting entity is written to the array CModule->_components
under the name 'db'. Yii::app()->db
will check for the presence of the instantiated entity in the array
and
use
it CModule->_components['db']
if found
there via the configuration file protected/config/main.phpDidn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question