常用底层知识 - 加载一个类 ¶
作者:KK
发表日期:2016.12.9
大概原理 ¶
Yii使用了psr-4的标准来加载class,所以没有被new过的class,相关的文件不会被include(你管它整个包有多少MB呢,反正没用的就不会被include,只占磁盘容量,不占内存)
先来看看这个别名的解析结果:
echo Yii::getAlias('@yii/log/FileTarget.php');
结果应该是类似我这样的:E:\projects\yii-demo\vendor\yiisoft\yii2/log/FileTarget.php
所以你应该发现了,当我们new \yii\log\FileTarget()
的时候,Yii底层先把命名空间里面yii
这一段当作@yii
以别名来解析,得到了@yii的路径
再跟后面的/log/FileTarget.php
拼接起来就成了整个类的路径
深入的加载原理文章请见《Yii的类自动加载机制》
示例详解 ¶
先确认一下echo Yii::getAlias('@app');
其实指的就是当前的项目目录吧
所以echo Yii::getAlias('@app/MySql.php');
就会变成类似这样:E:\projects\yii-demo\MySql.php
好,关键词“app\MySql”,我们就试下添加这个类吧,
平时我们用标准的语言来描述这个类的名称,其实不能说它叫“MySql”类,而是要把命名空间也附上,所以是“app\MySql”
这样才是它的完整类名,不然如果bpp命名空间下也有个MySql,谁知道你说的MySql是指app\MySql还是bpp\MySql呢?
好了请在@app目录下加个MySql.php
,代码如下:
namespace app;
class MySql{
public $dsn = '123';
}
这里要注意,通常情况下namespace的第一层都跟别名的名称完全对应(只是通常情况)
既然@app
解析到了项目的目录,那MySql
这个类处于项目目录下的话,我们就这么说吧:它也处于app
命名空间下
接下来在控制器里测试测试:
$mysql = new \app\MySql();
echo $mysql->dsn;
如无意外就会输出123
在别名目录的子目录增加类 ¶
我所谓的别名目录,就是指@app解析成的项目根目录,@vendor解析成的vendor目录,还有@yii的……
如果在这些目录的子目录添加class,则类的命名空间应该是这样写的:namespace 别名\子目录名称;
比如在@app的models目录增加一个类,那这个类的namespace就是app\models
,很好理解了对吧
其实就算models里面再来个user子目录,那里面的类的命名空间也就是app\models\user
变通一点,有些菜鸟不要把眼光定格于“框架应用自带的目录”
其实自己也可以创建自定义名字的目录添加class而不需要添加任何配置
比如在@app下加个lib目录,那再在这里加个Alipay类的话,类的命名空间和代码是这样的:
namespace app\lib;
class Alipay{}