Zend的AutoLoad机制介绍
程序员文章站
2022-04-19 23:25:37
代码示例 复制代码 代码如下: set_include_path(usvn_lib_dir . path_separator . get_include_path());...
代码示例
set_include_path(usvn_lib_dir . path_separator . get_include_path());
require_once 'zend/loader/autoloader.php';
$autoloader = zend_loader_autoloader::getinstance();
$autoloader->registernamespace("zend_");
$autoloader->registernamespace("usvn_");
$autoloader->registernamespace("menus_");
$config = new usvn_config_ini(usvn_config_file, usvn_config_section);
过程分析
首先是设置了include_path,include_path就是php中调用include的时候文件寻找的地址
下面就是 require_once 'zend/loader/autoloader.php';
在zend/loader/autoloader.php文件内,读入了zend/loader.php, 这个php定义了zend_loader这个类,这个类包含了loadclass,loadfile, isreadable(文件是否可读)等函数
实例化zend_loader_autoloader的过程就是调用其构造函数(这里是使用了单例模式)的过程
它的构造函数中的spl_autoload_register(array(__class__, 'autoload'));将zend_loader_autoloader:autoload作为类自动加载函数。
还做了一个操作将_internalautoloader赋值了自身的_autoload
至于这里面是怎么autoload的等会根据具体例子查看
接下来调用了zend_loader_autoloader:registernamespace("usvn_"),这个函数做的事就只是在zend_loader_autoloader的内部属性_namespaces上挂载一个key为usvn_和value为true的值。
看到这个函数就明白其实代码也可以写成
$autoloader->registernamespace("zend_")->registernamespace("usvn_")
或者
$autoloader->registernamespace(array("zend_","usvn_"))
好了,现在到调用 usvn_config_ini类了
这个类自然走的就是zend_loader_autoloader:autoload("usvn_config_ini")
这个函数第一步会去调用getclassautoloaders获取这个类的autoloader。getclassautoloaders里面增加了对namespaceautoloader的选择和判断,由于我们很少使用,直接跳过
这里返回的loader打印出来是这样的
array ( [0] => zend_loader_autoloader object ( [_autoloaders:protected] => array ( ) [_defaultautoloader:protected] => array ( [0] => zend_loader [1] => loadclass ) [_fallbackautoloader:protected] => [_internalautoloader:protected] => array *recursion* [_namespaces:protected] => array ( [zend_] => 1 [zendx_] => 1 [usvn_] => 1 [menus_] => 1 ) [_namespaceautoloaders:protected] => array ( ) [_suppressnotfoundwarnings:protected] => [_zfpath:protected] => ) [1] => _autoload )
其实就是前面设置的_internalautoloader。
这里就会实际调用zend_loader_autoloader:_autoload ("usvn_config_ini")
好了,现在就看到了zend_loader_autoloader:_autoload函数
$callback = $this->getdefaultautoloader();
这里会获取默认的autoloader,什么是默认的autoloader? 看这个类初始定义,实际上是array('zend_loader', 'loadclass');
下面自然就调用的是call_user_func($callback, $class);即zend_loader:loadclass("usvn_config_ini")
首先zend_loader已经在autoloader.php中被require了
其次我们看看zend_loader:loadclass方法,这个方法第一步是检查异常,跳过。第二步是将类分隔,拼凑成$file, 比如usvn/config/ini.php,下面就直接调用self::loadfile($file, null, true);
接下来查看self::loadfile,
首先_securitycheck看类名中是否有非法字符,没有,就include了这个$file。这里的$file当然是相对路径,需要拼接上include_path, 记得include_path是在哪里设置的吗?在程序的一开始就设置了!好了,这里就把usvn_config_ini这个类读取进来了。
看到这里你就该明白了,如果你自己定义了一个类,并且注册了namespace,比如usvn,那么你就应该在include_path下面创建一个同名文件夹(大小写必须区分),然后你要引入的相对的文件路径名就是以类名的_做分隔读入的。
到这里autoload机制就阅读完了。
复制代码 代码如下:
set_include_path(usvn_lib_dir . path_separator . get_include_path());
require_once 'zend/loader/autoloader.php';
$autoloader = zend_loader_autoloader::getinstance();
$autoloader->registernamespace("zend_");
$autoloader->registernamespace("usvn_");
$autoloader->registernamespace("menus_");
$config = new usvn_config_ini(usvn_config_file, usvn_config_section);
过程分析
首先是设置了include_path,include_path就是php中调用include的时候文件寻找的地址
下面就是 require_once 'zend/loader/autoloader.php';
在zend/loader/autoloader.php文件内,读入了zend/loader.php, 这个php定义了zend_loader这个类,这个类包含了loadclass,loadfile, isreadable(文件是否可读)等函数
实例化zend_loader_autoloader的过程就是调用其构造函数(这里是使用了单例模式)的过程
它的构造函数中的spl_autoload_register(array(__class__, 'autoload'));将zend_loader_autoloader:autoload作为类自动加载函数。
还做了一个操作将_internalautoloader赋值了自身的_autoload
至于这里面是怎么autoload的等会根据具体例子查看
接下来调用了zend_loader_autoloader:registernamespace("usvn_"),这个函数做的事就只是在zend_loader_autoloader的内部属性_namespaces上挂载一个key为usvn_和value为true的值。
看到这个函数就明白其实代码也可以写成
$autoloader->registernamespace("zend_")->registernamespace("usvn_")
或者
$autoloader->registernamespace(array("zend_","usvn_"))
好了,现在到调用 usvn_config_ini类了
这个类自然走的就是zend_loader_autoloader:autoload("usvn_config_ini")
这个函数第一步会去调用getclassautoloaders获取这个类的autoloader。getclassautoloaders里面增加了对namespaceautoloader的选择和判断,由于我们很少使用,直接跳过
这里返回的loader打印出来是这样的
复制代码 代码如下:
array ( [0] => zend_loader_autoloader object ( [_autoloaders:protected] => array ( ) [_defaultautoloader:protected] => array ( [0] => zend_loader [1] => loadclass ) [_fallbackautoloader:protected] => [_internalautoloader:protected] => array *recursion* [_namespaces:protected] => array ( [zend_] => 1 [zendx_] => 1 [usvn_] => 1 [menus_] => 1 ) [_namespaceautoloaders:protected] => array ( ) [_suppressnotfoundwarnings:protected] => [_zfpath:protected] => ) [1] => _autoload )
其实就是前面设置的_internalautoloader。
这里就会实际调用zend_loader_autoloader:_autoload ("usvn_config_ini")
好了,现在就看到了zend_loader_autoloader:_autoload函数
$callback = $this->getdefaultautoloader();
这里会获取默认的autoloader,什么是默认的autoloader? 看这个类初始定义,实际上是array('zend_loader', 'loadclass');
下面自然就调用的是call_user_func($callback, $class);即zend_loader:loadclass("usvn_config_ini")
首先zend_loader已经在autoloader.php中被require了
其次我们看看zend_loader:loadclass方法,这个方法第一步是检查异常,跳过。第二步是将类分隔,拼凑成$file, 比如usvn/config/ini.php,下面就直接调用self::loadfile($file, null, true);
接下来查看self::loadfile,
首先_securitycheck看类名中是否有非法字符,没有,就include了这个$file。这里的$file当然是相对路径,需要拼接上include_path, 记得include_path是在哪里设置的吗?在程序的一开始就设置了!好了,这里就把usvn_config_ini这个类读取进来了。
看到这里你就该明白了,如果你自己定义了一个类,并且注册了namespace,比如usvn,那么你就应该在include_path下面创建一个同名文件夹(大小写必须区分),然后你要引入的相对的文件路径名就是以类名的_做分隔读入的。
到这里autoload机制就阅读完了。