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

发布于 2024-11-14 12:22:43 字数 2031 浏览 5 评论 0原文

这是我的问题。我有一个带有自动加载函数的文件(例如 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();

一切看起来都不错,但有时(而且只是有时! )我在日志中收到以下错误:

[错误] 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 次)。什么会导致这种行为?我该如何解决它?

提前致谢!

Here is my problem. I have one file (say, func.inc.php) with autoloader function, registered by 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');

Then I have a second file (show_me_poi.php), calling some class:

POI::doSmth();

Everything seems OK, but sometimes (and only sometimes!) I receive a following error in log:

[error] PHP User error: Cannot load class POI included at /path_to_dir/php/generators/export.generator.php:156 (searching for poi.inc.php), but following file was included: /path_to_dir/php/scripts/php/incs/poi.inc.php

This is weird, because class POI is defined in properly included file! And I repeat, this situation happens only sometime (10 out of 100 I think). What can cause such behaviour? And how can I fix it?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对岸观火 2024-11-21 12:22:43

我也遇到了这个问题,并且我找到了适合我的情况的解决方案。

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

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

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

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

I've run into this problem as well and I found a solution for my case.

In my situation I had a custom session handler as well which wrote data to the database when closing the session.

When an error occurred the error handler would fire and the error would be handled normally.
But then the session close handler would run and it would encounter and error when trying to write to the database which caused catch statement to fire which, depending on the type of SQL error would throw an Exception of a certain type, but those classes had to be autoloaded. At that point (in a session close handler) you can no longer autoload classes apparently.

Check when this is happening. During normal PHP execution, or in some 'special' PHP mode such as a session handler or a while doing error handling?

The solution in my case was to add class_exists("MyClass", true) before trying to use it. I could throw a normal Exception instead. The Exception will still 'Fatal' as there is nothing left to catch it, but at least it will show the real Exception and not the autoload error.

一个人的旅程 2024-11-21 12:22:43

该问题似乎仅在 APC op-cache 打开时才会出现。我认为 __autoload 函数在某些情况下无法与缓存一起正常工作。 AFAIS 仅部分 PHP 和 APC 版本彼此不兼容。

The problem seems to arise only with APC op-cache turned on. I think that __autoload function can't work properly with caches in some cases. AFAIS only some PHP and APC versions are not compatible with each other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文