PHP自动加载class文件的方案

PHP5中有一个很方便的__autoload的魔术函数,PHP Manual中的示例如下:

function __autoload($class_name) {
    require_once $class_name . '.php';
}
 
$obj  = new MyClass1();
$obj2 = new MyClass2();

算是很方便的一个函数,然而有一个缺陷就是没有名称空间,大量的class不得不放在一个目录下面,才可以用这个自动加载php的魔术函数,如果class文件要放在不同的目录里面,这个自动载入就无能为力了。为了解决这个问题,自己写了一个loadClass函数实现类似功能,代码如下:

function loadClass($tgt){
	$class = substr($tgt, strrpos($tgt, '.')+1);
	require_once(DIR_APP.str_replace('.','/',$tgt).'.php');
	return new $class();
}
 
$test = loadClass("model.test");
$test->myfunc();

DIR_APP/model/test.php:

class test{
	function myfunc(){
		echo "hello, world!~";
	}
}

如此一来,就可以方便的加载在不同的目录里面的(缺点就是要打完整的”名称空间”),并且应该在PHP4中也可以使用(虽然PHP5已经是大流)……

补充@2009-02-23 22:42

就此自动载入的问题咨询了一下某飞,给了两个采用spl_autoload的自动载入的实现(by flying~):

function loader($className) {
    $classPath = str_replace('_', DIRECTORY_SEPARATOR, $className);
    require $classPath . '.php';
}
 
spl_autoload_register('loader');
 
$user = new Model_User();
// load (inlcude paths):/Model/User.php

class的名称定义遵循PEAR标准用下划线_进行分隔
更加复杂点的支持多路径的”豪华版”(by flying~):

class Vifix_Loader {
 
    private static $paths = array();
 
    public function addPath($path) {
        self::$paths[] = $path;
    }
 
    public function load($className) {
        $classPath = str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
        foreach (self::$paths as $path) {
            if (file_exists($path . $classPath)) {
                require $path . $classPath;
            }
        }
    }
}
 
spl_autoload_register(array('Vifix_Loader', 'load'));
 
Vifix_Loader::addPath(dirname(__FILE__));
 
// ...

15 Responses

Leave a Comment

(Necessary)

(Necessary, will not be published)

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.