我正在更新我刚才写的框架。我想采用新的标准,如名称空间和使用自动加载功能。
现在我的框架有一个非常基本但功能强大的自动加载功能,如下所示:
protected function runClasses()
{
$itemHandler = opendir( V_APP_PATH );
while( ( $item = readdir( $itemHandler ) ) !== false )
{
if ( substr( $item, 0, 1 ) != "." )
{
if( !is_dir( $item ) && substr( $item, -10 ) == ".class.php" )
{
if( !class_exists( $this->registry->$item ) )
{
require_once( V_APP_PATH . $item );
$item = str_replace( ".class.php", "", $item );
$this->registry->$item = new $item( $this->registry );
}
}
}
}
}
正如您在代码中看到的,此函数仅限于单个文件夹,但其优点是它将类加载到我的注册表中,允许我通过执行与{{{{{{{{{{{ 1}}这是我需要的功能。
我需要/想要完成的是使用自动加载器功能,但该功能不限于单个文件夹,而是能够浏览多个文件夹并实例化所需的类。
我只有一些测试文件,这是我当前的文件结构:
对于MyClass2,我有:
$this->registry->Class->somevar
对于MyClass1,我有:
namespace model;
Class MyClass2 {
function __construct() {
echo "MyClass2 is now loaded!";
}
}
对于Autoload,我有:
Class MyClass1 {
function __construct() {
echo "MyClass1 is now loaded!<br />";
}
}
我的问题是设置的方式它无法找到MyClass2的文件所以我想知道我做错了什么,其次,有没有像我的第一个“自动加载”功能,不需要在自动加载文件中指定命名空间并将其分配给我的注册表?
很抱歉这么长的问题,但非常感谢任何帮助。
答案 0 :(得分:2)
对于第二个问题:不建议使用__autoload,应该用spl_autoload_register替换。自动加载器应该做的是拆分命名空间和类:
function __autoload( $classname )
{
if( class_exists( $classname, false ))
return true;
$classparts = explode( '\\', $classname );
$classfile = '/' . strtolower( array_pop( $classparts )) . '.php';
$namespace = implode( '\\', $classparts );
// at this point you have to decide how to process further
}
根据您的文件结构,我建议根据命名空间和类名构建绝对路径:
define('ROOT_PATH', __DIR__);
function __autoload( $classname )
{
if( class_exists( $classname, false ))
return true;
$classparts = explode( '\\', $classname );
$classfile = '/' . strtolower( array_pop( $classparts )) . '.php';
$namespace = implode( '\\', $classparts );
$filename = ROOT_PATH . '/' . $namespace . $classfile;
if( is_readble($filename))
include_once $filename;
}
我采用了PSR0方法,其中命名空间是路径的一部分。