扩展 Zend_Loader,增加 classpath 功能

Posted on 30th January 2008 by Nio in Zend Framework, 程序人生

Zend Framework 一个比较基本的类是 Zend_Loader,可以很方便地注册 autoload,自动根据命名规则加载使用到的类,如:


<?php
Zend_Loader::registerAutoload();
?>

但这个类不支持 classpath,我们可能需要用到多个搜索路径去查找类文件,比如:Nio_Ajax_Response 的路径为 /home/nio/lib/Nio/Ajax/Response.php,classpath 为:/home/nio/lib,而测试用的类,通常会放到另一个单独的目录下:/home/nio/test,Nio_Ajax_Response 的测试类 Nio_Test_Ajax_Response 对应的文件是 /home/nio/test/Nio/Test/Ajax/Response.php。这样,我们就需要用到 classpath 了,依次在不同的目录下查找类文件。

扩展一下 Zend_Loader:


<?php
require_once 'Zend/Loader.php';

/**
 * Class/Interface/File loader.
 *
 * @author Nio Xiao
 */
class Nio_Loader extends Zend_Loader
{    
    /**
     * @var array classpath
     */
    private static $classPaths = array();
    
    /**
     * spl_autoload() suitable implementation for supporting class autoloading.
     *
     * Attach to spl_autoload() using the following:
     * <code>
     * spl_autoload_register(array('Nio_Loader', 'autoload'));
     * </code>
     *
     * @param string $class
     * @return string|false Class name on success; false on failure
     */
    public static function autoload($class)
    {
        try {
            if (preg_match('/^Zend/'$class)) {    //Zend Framework class
                parent::loadClass($class);
            } else {    //my class
                parent::loadClass($classself::$classPaths);
            }
            return $class;
        } catch (Exception $e) {
            return false;
        }
    }    
    
    /**
     * Get current class path array.
     *
     * @return array
     */
    public static function getClassPaths()
    {
        return self::$classPaths;
    }
    
    /**
     * Add a class path to the loader for searching classes.
     *
     * @param string|array $path
     */
    public static function addClassPath($path)
    {
        if (is_array($path)) {
            foreach ($path as $pself::addClassPath($p);
        } else {
            self::$classPaths[] = $path;            
        }
    }
    
    /**
     * Remove a class path from the loader.
     *
     * @param string $path
     */
    public static function removeClassPath($path)
    {
        if ($key array_search($pathself::$classPaths)) {
            unset(self::$classPaths[$key]);
        }
    }
}
?>

现在我们就可以用 Nio_Loader 来加入 classpath 了:


<?php
Zend_Loader::registerAutoload('Nio_Loader'); //注册我们自己的 loader

$classpaths = array(
    '/home/nio/lib',
    '/home/nio/test');
    
K12_Loader::addClassPath($classpaths);
var_dump(K12_Loader::getClassPaths());

K12_Loader::removeClassPath('/home/nio/test');
var_dump(K12_Loader::getClassPaths());
?>

有了这个我们就可以加入多个类搜索路径,不再需要重复写 require_once()/include_once()/Zend_Loader::loadFile() 的代码了 :)