在包含包含它的文件后,PHP不会实例化该类

时间:2011-06-09 09:39:21

标签: php require autoload

这是我的问题。我有一个文件(例如,func.inc.php)与自动加载器功能,由spl_autoload_register()注册:

function autoloaderFnc($class) {
    global $__CONFIG;

    $original = $class_name;
    $class_name = mb_strtolower ( $class_name );

    foreach ( $__CONFIG ['include_dirs'] as $path ) {
        if(file_exists ( $__CONFIG ['root'] . $path . $class_name . '.inc.php' )) {
            require ($__CONFIG ['root'] . $path . $class_name . '.inc.php');

            $classFound = TRUE;
            $foundAt = $__CONFIG ['root'] . $path . $class_name . '.inc.php';
            break;
        }
    }

    if( $classFound ) {
        if ( class_exists( $original ) ) {
            return true;
        } else {
            $backtrace = debug_backtrace();
            $error = "PHP User error: Cannot load class <b>$original</b> included at " . $backtrace[1]['file'] . ":" . $backtrace[1]['line'] . " (searching for <i>$class_name.inc.php</i>), but following file was included: $foundAt";
            error_log( $error );

            return false;
        }
    } else {
        $backtrace = debug_backtrace();
        $error = "PHP User error: Cannot find file with class <b>$original</b> included at " . $backtrace[1]['file'] . ":" . $backtrace[1]['line'] . " (searching for <i>$class_name.model.php</i> and <i>$class_name.inc.php</i>) in none of the following include dirs:<br />" . join ( '<br />', $__CONFIG ['include_dirs'] );
        error_log( $error );
    }

}

spl_autoload_register('autoloaderFnc');

然后我有第二个文件(show_me_poi.php),调用一些类:

POI::doSmth();

一切似乎都没问题,但有时候(有时甚至!)我在日志中收到以下错误:

  

[error] PHP用户错误:无法加载包含在/path_to_dir/php/generators/export.generator.php:156中的类 POI (搜索 poi.inc.php ),但包括以下文件:/path_to_dir/php/scripts/php/incs/poi.inc.php

这很奇怪,因为类POI是在正确包含的文件中定义的!我再说一遍,这种情况只发生在某个时候(我认为100个中有10个)。什么可以导致这种行为?我该如何解决?

提前致谢!

2 个答案:

答案 0 :(得分:1)

我也遇到了这个问题,我找到了解决方案。

在我的情况下,我有一个自定义会话处理程序,它在关闭会话时将数据写入数据库。

发生错误时,错误处理程序将触发,错误将正常处理。 但是会话关闭处理程序会运行,并且在尝试写入数据库时​​会遇到并出错导致catch语句触发,这取决于SQL错误的类型会抛出某种类型的异常,但这些类必须自动加载。 此时(在会话关闭处理程序中)您显然无法再自动加载类。

发生这种情况时检查。在正常的PHP执行期间,还是在某些“特殊”PHP模式(例如会话处理程序或执行错误处理时)?

我的解决方案是在尝试使用之前添加class_exists("MyClass", true)。我可以抛出一个正常的异常。由于没有任何东西可以捕获它,所以Exception仍然是“致命的”,但至少它会显示真正的异常,而不是自动加载错误。

答案 1 :(得分:0)

只有启用了APC op-cache才会出现此问题。我认为__autoload函数在某些情况下无法正常使用缓存。 AFAIS只有一些PHP和APC版本彼此不兼容。