自动加载一次只能注册一个类

时间:2014-08-05 15:12:29

标签: php autoload

我有这个自动加载器,一次只加载一个类。我无法弄清楚它有什么问题。我最初想尽可能多地学习PSR-0,尽管根据to code review我做了所需的一切,但它只是没有加载两个不同的文件,来自不同的命名空间,如下所示。

class Autoloader
{
    private $pathToClass; 

    //register the path
    function __construct($pathToClass)
    {
        $this->pathToClass = $pathToClass; 
    }

    //load the file
    public function load($class)
    {

        // expload the namespaces ex: foo\bar\tar array(foo, bar, tar)
        $explode = explode('\\', $class); 

        //get the last exploaded string and append .php so it becomes tar.php
        $class = $explode[count($explode) - 1].'.php'; 

        // required tar.php in the path it is found ex:
        // require '/foo/bar/tar.php' in lowecase to avoid windows/unix conflict
        if(file_exists(strtolower($this->pathToClass.$class))){
             require strtolower($this->pathToClass.$class);

            return true; 
        }

        return false; 
    }   

    // autoload
    public function register()
    {
        spl_autoload_register([$this, 'load']);
    }
}

以下是它的实例化方法:

$myLibLoader = new Autoloader(__DIR__.'/foo/bar/');
$myLibLoader->register();


$foo =  new foo();

修改

上面是我创建的第一个自动加载器,但是下面我展示了改进的自动加载器,我遇到了同样的问题。

<?php 
 class AutoloaderException extends Exception{}

class AutoLoader
{
    private $classDir; 
    private $namespace; 
    public $dirSeparatorSymbol = '\\'; 

    public function __construct($namespace, $classDir)
    {
        $this->classDir = $classDir; 
        $this->namespace = $namespace;

    }

    private function load($class)
    {

        $include_path = str_replace($this->dirSeparatorSymbol, DIRECTORY_SEPARATOR, $this->classDir);

        $classFilename = strtolower(substr($class, strrpos($class, '\\') + 1) . '.php');

        if(file_exists($include_path.$classFilename)){
            require $include_path.$classFilename;

            return true; 
        }


        throw new AutoloaderException('Class '.$classFilename. ' could not be loaded'); 
    }   

    public function register()
    {
        spl_autoload_register([$this, 'load']);
    }
}



/* INITIALIZING The autloader */

$b = new Autoloader('mercury\venus\earth', __DIR__.'/mercury/venus/earth/');
$b->register();

$a = new Autoloader('bar\tar', __DIR__.'/foo/bar/tar/');
$a->register();


$x = new bar\tar;

$y = new mercury\venus\earth;

1 个答案:

答案 0 :(得分:1)

我认为您的问题的关键在于您的原始CodeReview问题,特别是此评论:

  

您仍然没有从传递给的类限定符构造路径   加载()。关于如何做到这一点的问题在CodeReview上是offtopic,   考虑在StackOverflow上发布(有明确的解释)   你不明白的部分)。 - @ComFreek

我认为,鉴于两个没有命名空间的classess,你的自动加载器as-is应该可以正常运行。一旦引入名称空间,虽然您将遇到问题,因为您根本没有考虑它。

命名空间在PSR-0中很重要,因为它们包含更多路径信息。例如,您可能希望所有类都存在/some/directory中,但是如果您将命名空间添加到这些文件(使用\Foo\Bar\Tar类扩展您的示例),那么根据PSR-0该类必须在文件/some/directory/Foo/Bar/Tar.php中声明。

考虑到这一点,必须在自动装带器中更改这些行,以使其符合PSR-0标准:

if(file_exists(strtolower($this->pathToClass.$class))){
    require strtolower($this->pathToClass.$class);
    return true; 
}

具体来说,您尝试要求的类文件的文件路径应该是这样的:

$this->pathToClass . DIRECTORY_SEPARATOR . implode('/', $class) . '.php';

(也就是说,假设你选择了这一行:$class = $explode[count($explode) - 1].'.php';

我不确定您是否有机会,但Site Point上的this article是一个很好的阅读,涵盖了您需要了解的有关PSR-0和自动加载的所有内容。< / p>