yii的入口文件
yii的入口文件这里使用了一个第三方的配置管理插件:marcovwout,来管理Yii的配置,细节我就不说了。剩下的就是就是一些基本的全局变量设置了。往Yii::createWebApplication里面传入配置的数组,然后调用run方法,一个web应用是不是就这么跑起来了,是的,抽象到最高层就是这样:我往一个容器里面传入对应的配置,然后这个应用可以基于该配置正常运行起来。
说YiiBase中的两个比较重要的方法 (import,autoload)
YiiBase中的几个静态变量然后看看YiiBase中的import方法就知道这些静态变量是干嘛用的了:
/* Yii::import()
* $alias: 要导入的类名或路径
* $forceInclude false:只导入不include类文件,true则导入并include类文件
*/
public static function import($alias, $forceInclude = false){
//Yii把所有的依赖放入到这个全局的$_imports数组中,名字不能重复
//如果当前依赖已经被引入过了,那么直接返回
if (isset(self::$_imports[$alias])) {
return self::$_imports[$alias];
}
//class_exists和interface_exists方法的第二个参数的值为false表示不autoload
if (class_exists($alias, false) || interface_exists($alias, false)) {
return self::$_imports[$alias] = $alias;
}
//如果传进来的是一个php5.3版本的命名空间格式的类(例如:\a\b\c.php)
if (($pos = strrpos($alias, '\\')) !== false) {
//$namespace = a.b
$namespace = str_replace('\\', '.', ltrim(substr($alias, 0, $pos), '\\'));
//判断a.b这个路径是否存在,或者a.b只是alias里面的一个键,调用该方法返回这个键对应的值,比如'email' => realpath(__DIR__ . '/../vendor/cornernote/yii-email-module/email')
if (($path = self::getPathOfAlias($namespace)) !== false) {
$classFile = $path . DIRECTORY_SEPARATOR . substr($alias, $pos + 1) . '.php';
if ($forceInclude) {
if (is_file($classFile)) {
require($classFile);
} else {
throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.', array('{alias}' => $alias)));
}
self::$_imports[$alias] = $alias;
} else {
self::$classMap[$alias] = $classFile;
}
return $alias;
} else {
// try to autoload the class with an autoloader
if (class_exists($alias, true)) {
return self::$_imports[$alias] = $alias;
} else {
throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing directory or file.', array('{alias}' => $namespace)));
}
}
}
if (($pos = strrpos($alias, '.')) === false) // a simple class name
{
// try to autoload the class with an autoloader if $forceInclude is true
if ($forceInclude && (Yii::autoload($alias, true) || class_exists($alias, true))) {
self::$_imports[$alias] = $alias;
}
return $alias;
}
$className = (string)substr($alias, $pos + 1);
$isClass = $className !== '*';
if ($isClass && (class_exists($className, false) || interface_exists($className, false))) {
return self::$_imports[$alias] = $className;
}
if (($path = self::getPathOfAlias($alias)) !== false) {
if ($isClass) {
if ($forceInclude) {
if (is_file($path . '.php')) {
require($path . '.php');
} else {
throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.', array('{alias}' => $alias)));
}
self::$_imports[$alias] = $className;
} else {
self::$classMap[$className] = $path . '.php';
}
return $className;
}
// $alias是’system.web.*’这样的已*结尾的路径,将路径加到include_path中
else // a directory
{
if (self::$_includePaths === null) {
self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path()));
if (($pos = array_search('.', self::$_includePaths, true)) !== false) {
unset(self::$_includePaths[$pos]);
}
}
array_unshift(self::$_includePaths, $path);
if (self::$enableIncludePath && set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) {
self::$enableIncludePath = false;
}
return self::$_imports[$alias] = $path;
}
} else {
throw new CException(Yii::t('yii', 'Alias "{alias}" is invalid. Make sure it points to an existing directory or file.', array('{alias}' => $alias)));
}
}
是的,上面这个方法最后就把要加载的东西都放到$_imports,$_includePaths中去了。这就是Yii的import方法,好的,接下来我们看看autoload方法:
public static function autoload($className, $classMapOnly = false){ // use include so that the error PHP file may appear
if (isset(self::$classMap[$className])) {
include(self::$classMap[$className]);
} elseif (isset(self::$_coreClasses[$className])) {
include(YII_PATH . self::$_coreClasses[$className]);
} elseif ($classMapOnly) {
return false;
} else {
// include class file relying on include_path
if (strpos($className, '\\') === false)
// class without namespace
{
if (self::$enableIncludePath === false) {
foreach (self::$_includePaths as $path) {
$classFile = $path . DIRECTORY_SEPARATOR . $className . '.php';
if (is_file($classFile)) {
include($classFile);
if (YII_DEBUG && basename(realpath($classFile)) !== $className . '.php') {
throw new CException(Yii::t('yii', 'Class name "{class}" does not match class file "{file}".', array( '{class}' => $className, '{file}' => $classFile, )));
}
break;
}
}
} else {
include($className . '.php');
}
} else // class name with namespace in PHP 5.3
{
$namespace = str_replace('\\', '.', ltrim($className, '\\'));
if (($path = self::getPathOfAlias($namespace)) !== false) {
include($path . '.php');
} else {
return false;
}
}
return class_exists($className, false) || interface_exists($className, false); } return true;}
config文件中的 import 项里的类或路径在脚本启动中会被自动导入。用户应用里个别类需要引入的类可以在类定义前加入 Yii::import() 语句。
网友评论