* @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license https://www.yiiframework.com/license/
* Application is the base class for all application classes.
* For more details and usage information on Application, see the [guide article on applications](guide:structure-applications).
* @property-read \yii\web\AssetManager $assetManager The asset manager application component.
* @property-read \yii\rbac\ManagerInterface|null $authManager The auth manager application component or null
* if it's not configured.
* @property string $basePath The root directory of the application.
* @property-read \yii\caching\CacheInterface|null $cache The cache application component. Null if the
* component is not enabled.
* @property-write array $container Values given in terms of name-value pairs.
* @property-read \yii\db\Connection $db The database connection.
* @property-read \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application
* @property-read \yii\i18n\Formatter $formatter The formatter application component.
* @property-read \yii\i18n\I18N $i18n The internationalization application component.
* @property-read \yii\log\Dispatcher $log The log dispatcher application component.
* @property-read \yii\mail\MailerInterface $mailer The mailer application component.
* @property-read \yii\web\Request|\yii\console\Request $request The request component.
* @property-read \yii\web\Response|\yii\console\Response $response The response component.
* @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime"
* subdirectory under [[basePath]].
* @property-read \yii\base\Security $security The security application component.
* @property string $timeZone The time zone used by this application.
* @property-read string $uniqueId The unique ID of the module.
* @property-read \yii\web\UrlManager $urlManager The URL manager for this application.
* @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under
* @property-read View|\yii\web\View $view The view application component that is used to render various view
* @author Qiang Xue <qiang.xue@gmail.com>
abstract class Application extends Module
* @event Event an event raised before the application starts to handle a request.
const EVENT_BEFORE_REQUEST = 'beforeRequest';
* @event Event an event raised after the application successfully handles a request (before the response is sent out).
const EVENT_AFTER_REQUEST = 'afterRequest';
* Application state used by [[state]]: application just started.
* Application state used by [[state]]: application is initializing.
* Application state used by [[state]]: application is triggering [[EVENT_BEFORE_REQUEST]].
const STATE_BEFORE_REQUEST = 2;
* Application state used by [[state]]: application is handling the request.
const STATE_HANDLING_REQUEST = 3;
* Application state used by [[state]]: application is triggering [[EVENT_AFTER_REQUEST]]..
const STATE_AFTER_REQUEST = 4;
* Application state used by [[state]]: application is about to send response.
const STATE_SENDING_RESPONSE = 5;
* Application state used by [[state]]: application has ended.
* @var string the namespace that controller classes are located in.
* This namespace will be used to load controller classes by prepending it to the controller class name.
* The default namespace is `app\controllers`.
* Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details.
public $controllerNamespace = 'app\\controllers';
* @var string the application name.
public $name = 'My Application';
* @var string the charset currently used for the application.
public $charset = 'UTF-8';
* @var string the language that is meant to be used for end users. It is recommended that you
* use [IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands
* for English, while `en-US` stands for English (United States).
public $language = '[[language]]';
* @var string the language that the application is written in. This mainly refers to
* the language that the messages and view files are written in.
public $sourceLanguage = 'en-US';
* @var Controller the currently active controller instance
* @var string|bool the layout that should be applied for views in this application. Defaults to 'main'.
* If this is false, layout will be disabled.
* @var string the requested route
* @var Action|null the requested Action. If null, it means the request cannot be resolved into an action.
* @var array the parameters supplied to the requested action.
* @var array|null list of installed Yii extensions. Each array element represents a single extension
* with the following structure:
* 'name' => 'extension name',
* 'version' => 'version number',
* 'bootstrap' => 'BootstrapClassName', // optional, may also be a configuration array
* '@alias1' => 'to/path1',
* '@alias2' => 'to/path2',
* The "bootstrap" class listed above will be instantiated during the application
* [[bootstrap()|bootstrapping process]]. If the class implements [[BootstrapInterface]],
* its [[BootstrapInterface::bootstrap()|bootstrap()]] method will be also be called.
* If not set explicitly in the application config, this property will be populated with the contents of
* `@vendor/yiisoft/extensions.php`.
* @var array list of components that should be run during the application [[bootstrap()|bootstrapping process]].
* Each component may be specified in one of the following formats:
* - an application component ID as specified via [[components]].
* - a module ID as specified via [[modules]].
* - a configuration array.
* During the bootstrapping process, each component will be instantiated. If the component class
* implements [[BootstrapInterface]], its [[BootstrapInterface::bootstrap()|bootstrap()]] method
* will be also be called.
* @var int the current application state during a request handling life cycle.
* This property is managed by the application. Do not modify this property.
* @var array list of loaded modules indexed by their class names.
public $loadedModules = [];
* @param array $config name-value pairs that will be used to initialize the object properties.
* Note that the configuration must contain both [[id]] and [[basePath]].
* @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
public function __construct($config = [])
static::setInstance($this);
$this->state = self::STATE_BEGIN;
$this->registerErrorHandler($config);
Component::__construct($config);
* Pre-initializes the application.
* This method is called at the beginning of the application constructor.
* It initializes several important application properties.
* If you override this method, please make sure you call the parent implementation.
* @param array $config the application configuration
* @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
public function preInit(&$config)
if (!isset($config['id'])) {
throw new InvalidConfigException('The "id" configuration for the Application is required.');
if (isset($config['basePath'])) {
$this->setBasePath($config['basePath']);
unset($config['basePath']);
throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
if (isset($config['vendorPath'])) {
$this->setVendorPath($config['vendorPath']);
unset($config['vendorPath']);
if (isset($config['runtimePath'])) {
$this->setRuntimePath($config['runtimePath']);
unset($config['runtimePath']);
if (isset($config['timeZone'])) {
$this->setTimeZone($config['timeZone']);
unset($config['timeZone']);
} elseif (!ini_get('date.timezone')) {
$this->setTimeZone('UTC');
if (isset($config['container'])) {
$this->setContainer($config['container']);
unset($config['container']);
// merge core components with custom components
foreach ($this->coreComponents() as $id => $component) {
if (!isset($config['components'][$id])) {
$config['components'][$id] = $component;
} elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) {
$config['components'][$id]['class'] = $component['class'];
$this->state = self::STATE_INIT;
* Initializes extensions and executes bootstrap components.
* This method is called by [[init()]] after the application has been fully configured.
* If you override this method, make sure you also call the parent implementation.
protected function bootstrap()
if ($this->extensions === null) {
$file = Yii::getAlias('@vendor/yiisoft/extensions.php');
$this->extensions = is_file($file) ? include $file : [];
foreach ($this->extensions as $extension) {
if (!empty($extension['alias'])) {
foreach ($extension['alias'] as $name => $path) {
Yii::setAlias($name, $path);
if (isset($extension['bootstrap'])) {
$component = Yii::createObject($extension['bootstrap']);
if ($component instanceof BootstrapInterface) {
Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
$component->bootstrap($this);
Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
foreach ($this->bootstrap as $mixed) {
if ($mixed instanceof \Closure) {
Yii::debug('Bootstrap with Closure', __METHOD__);
if (!$component = call_user_func($mixed, $this)) {
} elseif (is_string($mixed)) {
if ($this->has($mixed)) {
$component = $this->get($mixed);
} elseif ($this->hasModule($mixed)) {
$component = $this->getModule($mixed);
} elseif (strpos($mixed, '\\') === false) {
throw new InvalidConfigException("Unknown bootstrapping component ID: $mixed");
if (!isset($component)) {
$component = Yii::createObject($mixed);
if ($component instanceof BootstrapInterface) {
Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
$component->bootstrap($this);
Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
* Registers the errorHandler component as a PHP error handler.
* @param array $config application config
protected function registerErrorHandler(&$config)
if (YII_ENABLE_ERROR_HANDLER) {
if (!isset($config['components']['errorHandler']['class'])) {
echo "Error: no errorHandler component is configured.\n";
$this->set('errorHandler', $config['components']['errorHandler']);
unset($config['components']['errorHandler']);
$this->getErrorHandler()->register();
* Returns an ID that uniquely identifies this module among all modules within the current application.
* Since this is an application instance, it will always return an empty string.
* @return string the unique ID of the module.
public function getUniqueId()
* Sets the root directory of the application and the @app alias.
* This method can only be invoked at the beginning of the constructor.
* @param string $path the root directory of the application.
* @property string the root directory of the application.
* @throws InvalidArgumentException if the directory does not exist.
public function setBasePath($path)
parent::setBasePath($path);
Yii::setAlias('@app', $this->getBasePath());
* This is the main entrance of an application.
* @return int the exit status (0 means normal, non-zero values mean abnormal)
$this->state = self::STATE_BEFORE_REQUEST;
$this->trigger(self::EVENT_BEFORE_REQUEST);
$this->state = self::STATE_HANDLING_REQUEST;
$response = $this->handleRequest($this->getRequest());
$this->state = self::STATE_AFTER_REQUEST;
$this->trigger(self::EVENT_AFTER_REQUEST);
$this->state = self::STATE_SENDING_RESPONSE;
$this->state = self::STATE_END;
return $response->exitStatus;
} catch (ExitException $e) {
$this->end($e->statusCode, isset($response) ? $response : null);
* Handles the specified request.
* This method should return an instance of [[Response]] or its child class
* which represents the handling result of the request.
* @param Request $request the request to be handled
* @return Response the resulting response
abstract public function handleRequest($request);
* Returns the directory that stores runtime files.
* @return string the directory that stores runtime files.
* Defaults to the "runtime" subdirectory under [[basePath]].
public function getRuntimePath()
if ($this->_runtimePath === null) {
$this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . 'runtime');
return $this->_runtimePath;
* Sets the directory that stores runtime files.
* @param string $path the directory that stores runtime files.
public function setRuntimePath($path)
$this->_runtimePath = Yii::getAlias($path);
Yii::setAlias('@runtime', $this->_runtimePath);
* Returns the directory that stores vendor files.
* @return string the directory that stores vendor files.
* Defaults to "vendor" directory under [[basePath]].
public function getVendorPath()
if ($this->_vendorPath === null) {
$this->setVendorPath($this->getBasePath() . DIRECTORY_SEPARATOR . 'vendor');
return $this->_vendorPath;
* Sets the directory that stores vendor files.
* @param string $path the directory that stores vendor files.
public function setVendorPath($path)
$this->_vendorPath = Yii::getAlias($path);
Yii::setAlias('@vendor', $this->_vendorPath);
Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
* Returns the time zone used by this application.
* This is a simple wrapper of PHP function date_default_timezone_get().
* If time zone is not configured in php.ini or application config,
* it will be set to UTC by default.
* @return string the time zone used by this application.
* @see https://www.php.net/manual/en/function.date-default-timezone-get.php
public function getTimeZone()
return date_default_timezone_get();
* Sets the time zone used by this application.
* This is a simple wrapper of PHP function date_default_timezone_set().
* Refer to the [php manual](https://www.php.net/manual/en/timezones.php) for available timezones.
* @param string $value the time zone used by this application.
* @see https://www.php.net/manual/en/function.date-default-timezone-set.php
public function setTimeZone($value)
date_default_timezone_set($value);
* Returns the database connection component.
* @return \yii\db\Connection the database connection.