# Yii的路径别名   **别名(Alias)** 可以将别名视为特殊的常量变量,他的作用在于避免将一些文件路径、URL以硬编码的方式 写入代码中,或者多处出现一长串的文件路径、URL。 ## 预定义的别名   Yii中,别名以`@`开头,以区别于正常的文件路径和URL。Yii中预定义了许多常用的 别名。别名的定义一般放在应用的最开始的阶段进行,比如引导阶段、初始化阶段等。 这样可以保证后续代码可以使用这些定义好的别名。   别名一般放在`<project>\common\config\bootstrap.php`, 或者在yii2高级版中`<project>\frontend\config\bootstrap.php`等`bootstrap.php`文件中定义。比如: ```php <?php Yii::setAlias('common', dirname(__DIR__)); Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend'); Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend'); Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console'); ```   在此定义的别名通过入口脚本引入Yii应用中,具体可以看看入口文件`index.php`部分的内容。上面的`<project>/common/config/bootstrap.php`文件定义了`@common`,`@frontend`,`@backend`和`@console`4个别名。 我们也可以自己在`bootstrap.php`中加入自己的别名定义,这是最常运用的定义别名的方式。 ## Yii预定义的别名 Yii预定义的别名主要分布在 `yii\BaseYii` 和 `yii\base\Application` 等类中。 默认情况下,会有: - `@app` ,必须由开发者在配置文件中提供,一般为配置文件的`dirname(__DIR__)` 。 即 `<project>/frontend` 之类的目录。 - `@vendor` ,一般定义为 `@app/vendor` ,高级模板中则定义为`@app/../vendor` - `@bower` ,定义为 `@vendor/bower` - `@npm` ,定义为 `@vendor/npm` - `@runtime` ,定义为 `@app/runtime` ### 所有预定义的别名[](http://www.digpage.com/aliases.html#id3 "Permalink to this headline") 小结一下,默认预定义别名一共有12个,其中路径别名11个,URL别名只有`@web`1个: * `@web`URL别名,表示当前应用的根URL,主要用于前端; * `@yii`表示Yii框架所在的目录,也是`yii\BaseYii`类文件所在的位置; * `@app`表示正在运行的应用的根目录,一般是`<project>/frontend`; * `@vendor`表示Composer第三方库所在目录,一般是`@app/vendor`或`@app/../vendor`; * `@bower`表示Bower第三方库所在目录,一般是`@vendor/bower`; * `@npm`表示NPM第三方库所在目录,一般是`@vendor/npm`; * `@runtime`表示正在运行的应用的运行时用于存放运行时文件的目录,一般是`@app/runtime`; * `@webroot`表示正在运行的应用的入口文件`index.php`所在的目录,一般是`@app/web`; * `@common`表示通用文件夹; * `@frontend`表示前台应用所在的文件夹; * `@backend`表示后台应用所在的文件夹; * `@console`表示命令行应用所在的文件夹; * 其他使用Composer安装的Yii扩展注册的二级别名,比如在`extensions.php`中key为`alias`的值。   这样,在整个Yii应用中,只要使用上述别名,就可方便、且统一地表示特定的路径或URL。 ## 别名的定义过程 ### 使用其他的方式定义别名 ``` // 使用一个路径定义一个路径别名 Yii::setAlias('@foo', 'path/to/foo'); // 使用一个URL定义一个URL别名 Yii::setAlias('@bar', 'http://www.domain.com'); // 使用一个别名定义另一个别名 Yii::setAlias('@fooba', '@foo/ba'); // 定义一个“二级”别名 Yii::setAlias('@foo/bar', 'path/to/foo/bar'); ``` ### 别名规范化   如果要定义的别名`$alias`并非以`@`打头,自动为这个别名加上`@`前缀。 总之,只要是别名,必然以`@`打头。下面的两个语句,都定义了相同的别名`@foo` ```php Yii::setAlias('foo', 'path/to/foo'); Yii::setAlias('@foo', 'path/to/foo'); ``` ### 获取根别名   `$alias`的根别名,就是`@`加上第一个`/`之间地内容,以`$root`表示。 这里可以看出,别名是分层次的。下面3个语句的根别名都是`@foo ```php Yii::setAlias('@foo', 'path/to/some/where'); Yii::setAlias('@foo/bar', 'path/to/some/where'); Yii::setAlias('@foo/bar/qux', 'path/to/some/where'); ``` ### 新定义别名还是删除别名   如果传入的`$path`不是`null`,说明是正常的别名定义。 对于正常的别名定义,就是往`BaseYii::$aliases[]`里写入信息。 而如果`$path`为`null`,说明是要删除别名: ```php // 定义别名@foo Yii::setAlias('@foo', 'path/to/some/where'); // 删除别名@foo Yii::setAlias('@foo', null); ``` ### 解析`$path`   对于新定义别名,既然`$path`不为`null`,那么先进行解析: 如果`$path`以`@`打头,说明这也是一个别名,则调用`Yii::getAlias()`, 并将解析后的结果作为新的`$path`; 如果`$path`不以`@`打头,说明是一个正常的path 或 URL, 那么去除`$path`末尾的`/`和`\`。 ### 别名的写入   对于全新的别名,也即其根别名是新的,`BaseYii::aliases[$root]`不存在。 那么全新别名的写入分两种情况: 如果全新别名本身就是根别名,那么直接`BaseYii::aliases[$alias]`=`$path`; 而如果全新的别名并非是一个根别名,即形如`@foo/bar`带有二级、三级等路径的,`BaseYii::aliases[$root]=[$alias=>$path]`。比如: ```php // BaseYii::aliases['@foo'] = ['@foo/bar' => 'path/to/foo/bar'] Yii::setAlias('@foo/bar', 'path/to/foo/bar'); // BaseYii::aliases['@qux'] = 'path/to/qux' Yii::setAlias('@qux', 'path/to/qux'); ``` ### 别名的删除   传入的 `$path` 为 `null` 表示要删除别名。 Yii使用PHP的 `unset()` 注销 `BaseYii::$aliases[]` 数组中的对应元素, 达到删除别名的目的。注意删除别名后,不需要调用 `krsort()`对数组进行处理。 参考:[Yii约定Alias别名](http://www.digpage.com/aliases.html)