加载类时出现spl_autoload_register问题

时间:2013-10-24 04:06:40

标签: php spl-autoload-register

所以我之前已经在这里提出过这个问题,但所提供的解决方案并不适用于我。 这是我的设置:

/mylib
    /Vendor/Module/MyClass.php
/document_root
    index.php

这是我的index.php

<?php


define('CLASSDIR', 'mylib');
define('BASEPATH',  @realpath( dirname (__FILE__).'/../').'/'.CLASSDIR);

spl_autoload_register(null, false);
spl_autoload_extensions('.php');

function autoLoader($className){

    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        echo 'does it come here? nope.'; 
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= BASEPATH.'/'.str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

    require $fileName; 
}

spl_autoload_register('autoLoader');

//$obj = new MyClass();

$obj = new \Vendor\Module\MyClass();

$obj::test();

 ?>

这是我的MyClass.php

<?php

namespace Vendor\Module;

class MyClass{

    public function __construct(){
        echo 'weird';
    }

    public function test(){
        echo 'strange';
    }
}
?>

我的所有回声都没有显示任何内容。显然我的班级也没有加载。相反,我得到了这个错误。

Fatal error: Call to undefined method MyClass::test() in /<documentroot>/index.php on line 29

请帮忙。我已经坚持了很长一段时间,而我的其余部分都在受苦。我尝试移动到spl_autoload_register()只是因为它是推荐的方式。现在失去的时间让我感到后悔。

2 个答案:

答案 0 :(得分:4)

您正在正确调用test()函数(使用静态方式?)。

使用以下方法调用该函数:

$obj = new MyClass();
$obj->test();

如果您打算使用MyClass::test()之类的静态方法,请在您的类中声明您的函数:

public static function test() {
}

此外,您的自动加载器过于复杂。它可以简化为:

$class_dir = array(
    '/mylib/Vendor/Module/',
    // Add more paths here ( or you can build your own $class_dir )
);

function class_loader($class_name) {
    global $class_dir;
    foreach ($class_dir as $directory) {
        if (file_exists($directory . $class_name . '.php')) {
            require_once($directory . $class_name . '.php');
            return;
        }
    }
}
spl_autoload_register('class_loader');

第3次修改:

我注意到你设置的路径不正确。

$fileName .= BASEPATH.'/'.str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

应该是:

$filename = BASEPATH .'/' . $filename . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';

如前所述,可以通过回显$filename的值来轻松调试它。

答案 1 :(得分:3)

F ** k是的。是的,我可以冒昧地在公共论坛上发誓这一次。

向@Shivan Raptor大声喊叫,帮助我一路走来,不放弃。

自动加载器功能中存在许多小问题。但调试花了我很长时间,原因只是一个简单的原因,我看不到任何回音消息。只有主和XAMPP知道原因。看起来像XAMPP在第一次运行时以某种方式缓存了这个类或者其他东西,后来没有任何变化显示任何效果。但是创建一个新的类和类文件突然开始显示我的所有回声,包括autoload中的回声。任何从下面的链接中获取自动加载器代码的人,请确保您查看所有变量的值。如果你没有将所有内容保存在文档根目录中,它就无法“开箱即用”。如果你是PSR-0和自动加载概念的新手,这可以杀死至少相当大一部分完美能力的脑细胞。

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

这是最终的index.php对我有用。

<?php

define('CLASSDIR', 'mylib');
define('BASEPATH',  @realpath( dirname (__FILE__).'/../').'/'.CLASSDIR);

spl_autoload_register(null, false);
spl_autoload_extensions('.php');

function autoLoader($className){
    $className = ltrim($className, '\\');
    $classPath  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {    
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $classPath = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR;
    }
    $fileName = BASEPATH.'/'.$classPath.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
    require $fileName;
}

spl_autoload_register('autoLoader');

$obj = new \Vendor\Module\MyClass();
$obj::test();
?>