<?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');