[置顶] 自定义类自动加载类

8 篇文章 0 订阅
5 篇文章 0 订阅
<?php
require_once 'exception.php';

/**
 * 自动加载类
 *
 */
final class AutoloadClass {
	
	/**
     * 类搜索路径
     *
     * @var array
     */
    private static $_class_path = array();
    
    /**
     * 类搜索规则
     *
     * @var array
     */
    private static $_locate_rules = array();
            
    /**
     * 添加一个类搜索路径
     *
     * @param string $dir 要添加的搜索路径
     */
    static function import($dir)
    {
        $real_dir = realpath($dir);
        if ($real_dir)
        {
            $dir = rtrim($real_dir, '/\\') . DS;
            if (!isset(self::$_class_path[$dir]))
            {
                self::$_class_path[$dir] = $dir;
            }
        }
    }

    /**
     * 载入指定类的定义文件,如果载入失败抛出异常
     *
     * @param string $class_name 要载入的类
     * @param boolean $throw_exception 找不到指定类时是否抛出异常
     */
    static function loadClass($class_name, $throw_exception = true)
    {
        if (class_exists($class_name, false) || interface_exists($class_name, false))
            return;
		
        foreach (self::$_locate_rules as $rule){
        	$filename = call_user_func($rule,$class_name);
        	if ($filename) break;
        }
        
        // 缺省的类加载规则
        if (!$filename)
        	$filename = str_replace('_', DS, $class_name) . '.php';
    	
        foreach (self::$_class_path as $dir)
        {
            $path = $dir . DS . $filename ;
            if (is_file($path))
            {
                require $path;
            	if (class_exists($class_name, false) || interface_exists($class_name, false)) { return; }
            }
        }
        
        if ($throw_exception)
        { 
        	throw new ExpectedClassException($class_name, $filename, file_exists($filename));
        }
    }
    
    /**
     * 添加一个类查找规则回调函数,要求规则匹配成功则返回类路径名称
     * 
     * 诸如: modules\contact\controllers\default.php 
     * 失败返回false
     *
     * @param callback $callback
     */
    static function addLocateRule($callback){
    	if (is_callable($callback)) self::$_locate_rules[] = $callback;
    }
    
    /**
     * 用于 的类自动载入,不需要由开发者调用
     *
     * @param string $class_name
     * @access private
     */
    static function autoload($class_name)
    {
        self::loadClass($class_name, true);
    }

    /**
     * 注册或取消注册一个自动类载入方法
     * 
     * @param boolean $enabled 启用或禁用该服务
     */
    static function registerAutoload($enabled = true)
    {
        static $registered = false;

        if (!function_exists('spl_autoload_register'))
        {
            exit('spl_autoload does not exist in this PHP installation.');
        }
		
        $registered = $enabled ? ( $registered ? true : spl_autoload_register(array('AutoloadClass', 'autoload')) )
        	: !spl_autoload_unregister(array('AutoloadClass', 'autoload'));
    }
    

    /**
     * 按照 命名规则,搜索文件
     *
     * 命名规则就是文件名中的“_”替换为目录分隔符。
     *
     * @param string $filename
     * @param boolean $return 指示是否直接返回处理后的文件名,而不判断文件是否存在
     *
     * @return string
     */
    private static function getFilePath($filename, $return = false)
    {
    	$filename = str_replace('_', DS, $filename);
    	
    	$filename = DS == '/' ? str_replace('\\', DS, $filename) : str_replace('/', DS, $filename);

        if (strtolower(substr($filename, -4)) != '.php') {
            $filename .= '.php';
        }

        // 首先搜索当前目录
        if (is_file($filename)) { return $filename; }

        foreach (self::$_class_path as $dir)
        {
            $path = $dir . DS . $filename ;
        	if (is_file($path)) { return $path; }
        }
        return false;
    }
    
    /**
     * 载入指定的文件
     *
     * $filename 参数中的 “_” 将被替换为目录
     *
     * @param string $className
     * @param boolean $loadOnce 指定为 true 时,等同于 require_once
     *
     * @return boolean
     */
    static function loadFile($filename, $loadOnce = false)
    {
        static $is_loaded = array();

        $path = self::getFilePath($filename);
        if ($path != '') {
            if (isset($is_loaded[$path]) && $loadOnce) { return true; }
            $is_loaded[$path] = true;
            if ($loadOnce) {
                return require_once($path);
            } else {
                return require($path);
            }
        }
        throw new ExpectedFileException($filename);
    }
}

 使用demo:

<?php
// 

// 过滤 magic_quotes
if (get_magic_quotes_gpc()) {
	$in = array(& $_GET, & $_POST, & $_COOKIE, & $_REQUEST);
	while (list($k,$v) = each($in)) {
		foreach ($v as $key => $val) {
			if (!is_array($val)) {
				$in[$k][$key] = stripslashes($val);
				continue;
			}
			$in[] =& $in[$k][$key];
		}
	}
	unset($in);
}
set_magic_quotes_runtime(0);

// 设置自动加载类操作
require_once 'autoload.php';

AutoloadClass::registerAutoload(true);

// 导入应用根路径
AutoloadClass::import(App::ini('APP_DIR'));

/**
 * 定位控制器类文件路径
 *
 * @param string $class_name
 * @return string
 */
function locateControllerFile($class_name){
	if (!preg_match('/Controller$/i',$class_name))
		return false;
	$_ = preg_replace('/Controller$/i','',$class_name);
	
	if (empty($_)) return false;
	
	$_ = explode('_',$_);
	
	$_ = array_map('strtolower', $_);
	
	if ($_[0] == 'mod'){
		
		// Mod_Contact_DefaultController => modules\contact\controllers\default.php
		
		$_[0] = 'modules';
		$_[1] = $_[1] . '/controllers';
	}
	
	return implode('/',$_) . '.php';
}

/**
 * 定位模型类文件路径
 *
 * @param string $class_name
 * @return string
 */
function locateModelFile($class_name){
	
	if (!preg_match('/Model$/i',$class_name))
		return false;
	$_ = preg_replace('/Model$/i','',$class_name);
	
	if (empty($_)) return false;
	
	$_ = explode('_',$_);
	
	$_ = array_map('strtolower', $_);
	
	if ($_[0] == 'mod'){
		
		// Mod_Contact_UserModel => modules\contact\models\user.php
		
		$_[0] = 'modules';
		$_[1] = $_[1] . '/models';
	}
	
	return implode('/',$_) . '.php';
}

AutoloadClass::addLocateRule('locateControllerFile');
AutoloadClass::addLocateRule('locateModelFile');
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值