应用的配置可能是最复杂的配置之一。因为 yii\web\Application 类拥有很多可配置的属性和事件。更重要的是它的 yii\web\Application::components 属性可以接收配置数组并通过应用注册为组件。
这是 Yii 权威指南中的一句话。由此可见 Yii 的配置之复杂。
Yii 的配置分开来说有两大块,一是 Yii 应用主体的配置,二是 Yii 加载的组件的配置,即 yii\base\Application::components
属性。Yii 应用主体的配置官方介绍很详细,附上链接 应用主体。但是 Yii 加载组件的配置文档中介绍的就很简单了。大家经常不知道有哪些组件,不同组件有哪些配置。今天就是解决这些问题。
首先看一个简单的配置
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
],
'log' => [
'class' => 'yii\log\Dispatcher',
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
],
],
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=stay2',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
根据上面可知一个组件的配置格式为
'组建名' => [
'class' => '组建类的命名空间位置',
'配置键' => '配置值',
],
配置完成后,你就可以通过Yii::$app->componentID
来访问注册的插件了。注意的是,配置后程序运行后并没有实例化该类, 只有你访问该组件时(通过Yii::$app->componentID
或其他方式),Yii 才会根据组件配置中的class
实例化对应的类,然后将配置数组传入该实例,初始化配置信息,返回该实例。
当然你也可以不用这种方式实例化组件。你可以在你的类里,导入组件的命名空间。自己传入配置,然后实例化,这样就不用配置components
。当然,前提是你愿意这么麻烦的话。
这里我们以user
组件举例说明一下。可是user
组件并没有指定class
,那它实例化的是什么呢?其实在程序运行期间,Yii 已经配置了核心的组件了。代码如下
@yii\base\application.php 文件
public function coreComponents()
{
return [
'log' => ['class' => 'yii\log\Dispatcher'],
'view' => ['class' => 'yii\web\View'],
'formatter' => ['class' => 'yii\i18n\Formatter'],
'i18n' => ['class' => 'yii\i18n\I18N'],
'mailer' => ['class' => 'yii\swiftmailer\Mailer'],
'urlManager' => ['class' => 'yii\web\UrlManager'],
'assetManager' => ['class' => 'yii\web\AssetManager'],
'security' => ['class' => 'yii\base\Security'],
];
}
@yii\web\application.php 文件
public function coreComponents()
{
return array_merge(parent::coreComponents(), [
'request' => ['class' => 'yii\web\Request'],
'response' => ['class' => 'yii\web\Response'],
'session' => ['class' => 'yii\web\Session'],
'user' => ['class' => 'yii\web\User'],
'errorHandler' => ['class' => 'yii\web\ErrorHandler'],
]);
}
这两个地方定义了我们核心的组件类。包括我们的user
组件。打开该文件,贴上代码。
额。。。。700多行,算了,还是贴一部分吧。想看全部的自己去翻自己的源文件吧。
<?php
/**
* [@link](/member/link) http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\web;
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\base\InvalidValueException;
use yii\rbac\CheckAccessInterface;
/**
* User is the class for the "user" application component that manages the user authentication status.
*
* You may use [[isGuest]] to determine whether the current user is a guest or not.
* If the user is a guest, the [[identity]] property would return null. Otherwise, it would
* be an instance of [[IdentityInterface]].
*
* You may call various methods to change the user authentication status:
*
* - [[login()]]: sets the specified identity and remembers the authentication status in session and cookie.
* - [[logout()]]: marks the user as a guest and clears the relevant information from session and cookie.
* - [[setIdentity()]]: changes the user identity without touching session or cookie.
* This is best used in stateless RESTful API implementation.
*
* Note that User only maintains the user authentication status. It does NOT handle how to authenticate
* a user. The logic of how to authenticate a user should be done in the class implementing [[IdentityInterface]].
* You are also required to set [[identityClass]] with the name of this class.
*
* User is configured as an application component in [[\yii\web\Application]] by default.
* You can access that instance via `Yii::$app->user`.
*
* You can modify its configuration by adding an array to your application config under `components`
* as it is shown in the following example:
*
*
* 'user' => [
* 'identityClass' => 'app\models\User', // User must implement the IdentityInterface
* 'enableAutoLogin' => true,
* // 'loginUrl' => ['user/login'],
* // ...
* ]
*
*
* @property string|integer $id The unique identifier for the user. If null, it means the user is a guest.
* This property is read-only.
* @property IdentityInterface|null $identity The identity object associated with the currently logged-in
* user. `null` is returned if the user is not logged in (not authenticated).
* @property boolean $isGuest Whether the current user is a guest. This property is read-only.
* @property string $returnUrl The URL that the user should be redirected to after login. Note that the type
* of this property differs in getter and setter. See [[getReturnUrl()]] and [[setReturnUrl()]] for details.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class User extends Component
{
const EVENT_BEFORE_LOGIN = 'beforeLogin';
const EVENT_AFTER_LOGIN = 'afterLogin';
const EVENT_BEFORE_LOGOUT = 'beforeLogout';
const EVENT_AFTER_LOGOUT = 'afterLogout';
/**
* @var string the class name of the [[identity]] object.
*/
public $identityClass;
/**
* @var boolean whether to enable cookie-based login. Defaults to false.
* Note that this property will be ignored if [[enableSession]] is false.
*/
public $enableAutoLogin = false;
/**
* @var boolean whether to use session to persist authentication status across multiple requests.
* You set this property to be false if your application is stateless, which is often the case
* for RESTful APIs.
*/
public $enableSession = true;
/**
* @var string|array the URL for login when [[loginRequired()]] is called.
* If an array is given, [[UrlManager::createUrl()]] will be called to create the corresponding URL.
* The first element of the array should be the route to the login action, and the rest of
* the name-value pairs are GET parameters used to construct the login URL. For example,
*
* php
* ['site/login', 'ref' => 1]
*
*
* If this property is null, a 403 HTTP exception will be raised when [[loginRequired()]] is called.
*/
public $loginUrl = ['site/login'];
/**
* @var array the configuration of the identity cookie. This property is used only when [[enableAutoLogin]] is true.
* @see Cookie
*/
public $identityCookie = ['name' => '_identity', 'httpOnly' => true];
/**
* @var integer the number of seconds in which the user will be logged out automatically if he
* remains inactive. If this property is not set, the user will be logged out after
* the current session expires (c.f. [[Session::timeout]]).
* Note that this will not work if [[enableAutoLogin]] is true.
*/
public $authTimeout;
/**
* @var CheckAccessInterface The acess checker to use for checking access.
* If not set the application auth manager will be used.
* @since 2.0.9
*/
public $accessChecker;
/**
* @var integer the number of seconds in which the user will be logged out automatically
* regardless of activity.
* Note that this will not work if [[enableAutoLogin]] is true.
*/
public $absoluteAuthTimeout;
/**
* @var boolean whether to automatically renew the identity cookie each time a page is requested.
* This property is effective only when [[enableAutoLogin]] is true.
* When this is false, the identity cookie will expire after the specified duration since the user
* is initially logged in. When this is true, the identity cookie will expire after the specified duration
* since the user visits the site the last time.
* @see enableAutoLogin
*/
public $autoRenewCookie = true;
/**
* @var string the session variable name used to store the value of [[id]].
*/
public $idParam = '__id';
/**
* @var string the session variable name used to store the value of expiration timestamp of the authenticated state.
* This is used when [[authTimeout]] is set.
*/
public $authTimeoutParam = '__expire';
/**
* @var string the session variable name used to store the value of absolute expiration timestamp of the authenticated state.
* This is used when [[absoluteAuthTimeout]] is set.
*/
public $absoluteAuthTimeoutParam = '__absoluteExpire';
/**
* @var string the session variable name used to store the value of [[returnUrl]].
*/
public $returnUrlParam = '__returnUrl';
/**
* @var array MIME types for which this component should redirect to the [[loginUrl]].
* @since 2.0.8
*/
public $acceptableRedirectTypes = ['text/html', 'application/xhtml+xml'];
private $_access = [];
/**
* Initializes the application component.
*/
public function init()
{
parent::init();
if ($this->identityClass === null) {
throw new InvalidConfigException('User::identityClass must be set.');
}
if ($this->enableAutoLogin && !isset($this->identityCookie['name'])) {
throw new InvalidConfigException('User::identityCookie must contain the "name" element.');
}
}
private $_identity = false;
首先,在该文件前面的注视部分,有基本的使用方法,英语不到位的,自行有道,或百度,也能看的七七八八。
'user' => [
'identityClass' => 'app\models\User', // User must implement the IdentityInterface
'enableAutoLogin' => true,
// 'loginUrl' => ['user/login'],
// ...
]
其次是该类的属性
const EVENT_BEFORE_LOGIN = 'beforeLogin'; //定义了四个常量表示事件,可在控制器里定义事件,或导入事件行为
const EVENT_AFTER_LOGIN = 'afterLogin';
const EVENT_BEFORE_LOGOUT = 'beforeLogout';
const EVENT_AFTER_LOGOUT = 'afterLogout';
/**
* @var string the class name of the [[identity]] object.
*/
public $identityClass; //就是继承了`IdentityInterface`的模型类
/**
* @var boolean whether to enable cookie-based login. Defaults to false.
* Note that this property will be ignored if [[enableSession]] is false.
*/
public $enableAutoLogin = false; //是否开启自动登录
/**
* @var boolean whether to use session to persist authentication status across multiple requests.
* You set this property to be false if your application is stateless, which is often the case
* for RESTful APIs.
*/
public $enableSession = true; //是否使用 Session
/**
* @var string|array the URL for login when [[loginRequired()]] is called.
* If an array is given, [[UrlManager::createUrl()]] will be called to create the corresponding URL.
* The first element of the array should be the route to the login action, and the rest of
* the name-value pairs are GET parameters used to construct the login URL. For example,
*
*
* ['site/login', 'ref' => 1]
*
*
* If this property is null, a 403 HTTP exception will be raised when [[loginRequired()]] is called.
*/
public $loginUrl = ['site/login']; //设置登录 Url
/**
* @var array the configuration of the identity cookie. This property is used only when [[enableAutoLogin]] is true.
* @see Cookie
*/
public $identityCookie = ['name' => '_identity', 'httpOnly' => true];
/**
* @var integer the number of seconds in which the user will be logged out automatically if he
* remains inactive. If this property is not set, the user will be logged out after
* the current session expires (c.f. [[Session::timeout]]).
* Note that this will not work if [[enableAutoLogin]] is true.
*/
public $authTimeout;
/**
* @var CheckAccessInterface The acess checker to use for checking access.
* If not set the application auth manager will be used.
* @since 2.0.9
*/
public $accessChecker;
/**
* @var integer the number of seconds in which the user will be logged out automatically
* regardless of activity.
* Note that this will not work if [[enableAutoLogin]] is true.
*/
public $absoluteAuthTimeout;
/**
* @var boolean whether to automatically renew the identity cookie each time a page is requested.
* This property is effective only when [[enableAutoLogin]] is true.
* When this is false, the identity cookie will expire after the specified duration since the user
* is initially logged in. When this is true, the identity cookie will expire after the specified duration
* since the user visits the site the last time.
* @see enableAutoLogin
*/
public $autoRenewCookie = true;
/**
* @var string the session variable name used to store the value of [[id]].
*/
public $idParam = '__id';
/**
* @var string the session variable name used to store the value of expiration timestamp of the authenticated state.
* This is used when [[authTimeout]] is set.
*/
public $authTimeoutParam = '__expire';
/**
* @var string the session variable name used to store the value of absolute expiration timestamp of the authenticated state.
* This is used when [[absoluteAuthTimeout]] is set.
*/
public $absoluteAuthTimeoutParam = '__absoluteExpire';
/**
* @var string the session variable name used to store the value of [[returnUrl]].
*/
public $returnUrlParam = '__returnUrl';
/**
* @var array MIME types for which this component should redirect to the [[loginUrl]].
* @since 2.0.8
*/
public $acceptableRedirectTypes = ['text/html', 'application/xhtml+xml'];
private $_access = [];
注释中文写了一部分,其他自定翻译吧,我真的不是懒,是太懒。。。
看到这里大家应该明白一些了,组件的配置就是大部分就是该类的属性(有小部分不是),用我们在components
组件里的配置覆盖了该组件类默认的配置。
。
其他组件的配置,打开该组件对应的类文件,查看属性,看懂了自然好,不懂的有道吧,还不懂的到 yiichina 提问交流吧。
多说几句:
Yii::$app->componentID->functionID
.附上组件对应表,应该有遗漏,欢迎大神在评论去补充
'log' => ['class' => 'yii\log\Dispatcher'],
'view' => ['class' => 'yii\web\View'],
'formatter' => ['class' => 'yii\i18n\Formatter'],
'i18n' => ['class' => 'yii\i18n\I18N'],
'mailer' => ['class' => 'yii\swiftmailer\Mailer'],
'urlManager' => ['class' => 'yii\web\UrlManager'],
'assetManager' => ['class' => 'yii\web\AssetManager'],
'security' => ['class' => 'yii\base\Security'],
'request' => ['class' => 'yii\web\Request'],
'response' => ['class' => 'yii\web\Response'],
'session' => ['class' => 'yii\web\Session'],
'user' => ['class' => 'yii\web\User'],
'errorHandler' => ['class' => 'yii\web\ErrorHandler'],
'db' => 'class' => 'yii\db\Connection',
'cache' => 'class' => 'yii\caching\ApcCache',
本文由 stoneyang 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。
其实之所以能够实现上面的配置基础还是所有的组件类都继承自 yii\base\Component
,而 yii\base\Component
又继承自 yii\base\Object
, yii\base\Object
是Yii中所有类的基类。在Yii中对象的创建都是用Yii::createObject
方法创建的,createObject的方法说明如下:
* Creates a new object using the given configuration.
*
* You may view this method as an enhanced version of the `new` operator.
* The method supports creating an object based on a class name, a configuration array or
* an anonymous function.
*
* Below are some usage examples:
*
* ```php
* // create an object using a class name
* $object = Yii::createObject('yii\db\Connection');
*
* // create an object using a configuration array
* $object = Yii::createObject([
* 'class' => 'yii\db\Connection',
* 'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
* 'username' => 'root',
* 'password' => '',
* 'charset' => 'utf8',
* ]);
*
* // create an object with two constructor parameters
* $object = \Yii::createObject('MyClass', [$param1, $param2]);
* ```
*
* Using [[\yii\di\Container|dependency injection container]], this method can also identify
* dependent objects, instantiate them and inject them into the newly created object.
*
* @param string|array|callable $type the object type. This can be specified in one of the following forms:
*
* - a string: representing the class name of the object to be created
* - a configuration array: the array must contain a `class` element which is treated as the object class,
* and the rest of the name-value pairs will be used to initialize the corresponding object properties
* - a PHP callable: either an anonymous function or an array representing a class method (`[$class or $object, $method]`).
* The callable should return a new instance of the object being created.
*
* @param array $params the constructor parameters
* @return object the created object
* @throws InvalidConfigException if the configuration is invalid.
* @see \yii\di\Container
也就是说通过传入类名和类的属性,调用这个方法即可生成对象。
@qihuajun [#5楼](#comment5) 谢谢解释。附上源码位于yii\BaseYii.php
文件中。
public static function createObject($type, array $params = [])
{
if (is_string($type)) {
return static::$container->get($type, $params);
} elseif (is_array($type) && isset($type['class'])) {
$class = $type['class'];
unset($type['class']);
return static::$container->get($class, $params, $type);
} elseif (is_callable($type, true)) {
return static::$container->invoke($type, $params);
} elseif (is_array($type)) {
throw new InvalidConfigException('Object configuration must be an array containing a "class" element.');
} else {
throw new InvalidConfigException('Unsupported configuration type: ' . gettype($type));
}
}
通过该方法,去容器中寻找该对象。至于容器的促使化在yii/Yii.php
文件中
class Yii extends \yii\BaseYii
{
}
spl_autoload_register(['Yii', 'autoload'], true, true);
Yii::$classMap = require(__DIR__ . '/classes.php');
Yii::$container = new yii\di\Container();
注册了自动加载函数(在BaseYii中),导入映射类文件(避免查找,提高性能),然后实例化容器类文件