内容摘要
- PHP的autoload自动加载机制
- Zend_Loader的源码分析
PHP的autoload自动加载机制
PHP的autoload大致包括两种方法:__autoload和spl方法。
1.1 __autoload方法
1.1.1函数名称:
__autoload
1.1.2功能:
尝试加载未定义的类
1.1.3函数原型:
void __autoload ( string $class
)
1.1.4实例:
<?php
// we've writen this code where we need
function __autoload($classname) {
$filename = "./". $classname .".php";
include_once($filename);
}
// we've called a class ***
$obj = new myClass();
?>
1.2 spl_autoload 方法
1.2.1函数名称:
spl_autoload
1.2.2功能:
__autoload()函数的默认实现。本函数提供了__autoload()的一个默认实现。如果不使用任何参数调用 autoload_register() 函数,则以后在进行 __autoload() 调用时会自动使用此函数。
1.2.3函数原型:
void spl_autoload ( string $class_name
[, string $file_extensions
] )
<?php
class Loader
{
/**
* Controller Directory Path
*
* @var Array
* @access protected
*/
protected $_controllerDirectoryPath = array();
/**
* Model Directory Path
*
* @var Array
* @access protected
*/
protected $_modelDirectoryPath = array();
/**
* Library Directory Path
*
* @var Array
* @access protected
*/
protected $_libraryDirectoryPath = array();
/**
* Constructor
* Constant contain my full path to Model, View, Controllers and Lobrary-
* Direcories.
*
* @Constant MPATH,VPATH,CPATH,LPATH
*/
public function __construct()
{
$this->modelDirectoryPath = MPATH;
$this->viewDirectoryPath = VPATH;
$this->controllerDirectoryPath = CPATH;
$this->libraryDirectoryPath = LPATH;
spl_autoload_register(array($this,'load_controller'));
spl_autoload_register(array($this,'load_model'));
spl_autoload_register(array($this,'load_library'));
log_message('debug',"Loader Class Initialized");
}
/**
*-----------------------------------------------------
* Load Library
*-----------------------------------------------------
* Method for load library.
* This method return class object.
*
* @library String
* @param String
* @access public
*/
public function load_library($library, $param = null)
{
if (is_string($library)) {
return $this->initialize_class($library);
}
if (is_array($library)) {
foreach ($library as $key) {
return $this->initialize_class($library);
}
}
}
/**
*-----------------------------------------------------
* Initialize Class
*-----------------------------------------------------
* Method for initialise class
* This method return new object.
* This method can initialize more class using (array)
*
* @library String|Array
* @param String
* @access public
*/
public function initialize_class($library)
{
try {
if (is_array($library)) {
foreach($library as $class) {
$arrayObject = new $class;
}
return $this;
}
if (is_string($library)) {
$stringObject = new $library;
}else {
throw new ISException('Class name must be string.');
}
if (null == $library) {
throw new ISException('You must enter the name of the class.');
}
} catch(Exception $exception) {
echo $exception;
}
}
/**
* Autoload Controller class
*
* @param string $class
* @return object
*/
public function load_controller($controller)
{
if ($controller) {
set_include_path($this->controllerDirectoryPath);
spl_autoload_extensions('.php');
spl_autoload($class);
}
}
/**
* Autoload Model class
*
* @param string $class
* @return object
*/
public function load_models($model)
{
if ($model) {
set_include_path($this->modelDirectoryPath);
spl_autoload_extensions('.php');
spl_autoload($class);
}
}
/**
* Autoload Library class
*
* @param string $class
* @return object
*/
public function load_library($library)
{
if ($library) {
set_include_path($this->libraryDirectoryPath);
spl_autoload_extensions('.php');
spl_autoload($class);
}
}
}
?>
</pre><p>2.Zend_Loader的源码分析</p><p> 2.1 Zend_Loder的结构</p><p> <img src="https://img-blog.csdn.net/20150702104548408?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjk0Nzk4OTc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></p><p> 2.2 剖析</p><p> Zend/Loader/Autoloader.php </p><p> 2.2.1 当PHP遇到不认识的类时,尝试自动加载这个类。通过spl_autoload_register方法,告诉PHP,用什么来加载我们的类。</p><p> __construct方法 :<pre name="code" class="php"> protected function __construct()
{
spl_autoload_register(array(__CLASS__, 'autoload'));
$this->_internalAutoloader = array($this, '_autoload');
}
autoload方法:
public static function autoload($class)
{
$self = self::getInstance();
foreach ($self->getClassAutoloaders($class) as $autoloader) {
if ($autoloader instanceof Zend_Loader_Autoloader_Interface) {
if ($autoloader->autoload($class)) {
return true;
}
} elseif (is_array($autoloader)) {
if (call_user_func($autoloader, $class)) {
return true;
}
} elseif (is_string($autoloader) || is_callable($autoloader)) {
if ($autoloader($class)) {
return true;
}
}
}
return false;
}
_autoload方法:
protected function _autoload($class)
{
$callback = $this->getDefaultAutoloader();
try {
if ($this->suppressNotFoundWarnings()) {
@call_user_func($callback, $class);
} else {
call_user_func($callback, $class);
}
return $class;
} catch (Zend_Exception $e) {
return false;
}
}