php中的基本自动加载和命名空间

时间:2012-09-20 16:24:43

标签: php autoload

我正在更新我刚才写的框架。我想采用新的标准,如名称空间和使用自动加载功能。

现在我的框架有一个非常基本但功能强大的自动加载功能,如下所示:

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}}这是我需要的功能。

我需要/想要完成的是使用自动加载器功能,但该功能不限于单个文件夹,而是能够浏览多个文件夹并实例化所需的类。

我只有一些测试文件,这是我当前的文件结构:

File Structure

对于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的文件所以我想知道我做错了什么,其次,有没有像我的第一个“自动加载”功能,不需要在自动加载文件中指定命名空间并将其分配给我的注册表?

很抱歉这么长的问题,但非常感谢任何帮助。

1 个答案:

答案 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方法,其中命名空间是路径的一部分。