PHP не создает экземпляр класса после включения файла, содержащего его - PullRequest
1 голос
/ 09 июня 2011

Вот моя проблема.У меня есть один файл (скажем, 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 User error: Невозможно загрузить класс POI включено в /path_to_dir/php/generators/export.generator.php:156 (поиск poi.inc.php ), но был включен следующий файл: / path_to_dir / php / scripts / php /incs / poi.inc.php

Это странно, потому что класс POI определен в правильно включенном файле!И я повторяю, такая ситуация случается только когда-то (10 из 100, я думаю).Что может вызвать такое поведение?И как я могу это исправить?

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 09 июня 2011

Я также столкнулся с этой проблемой и нашел решение для своего случая.

В моей ситуации у меня был также собственный обработчик сеанса, который записывал данные в базу данных при закрытии сеанса.

При возникновении ошибки обработчик ошибок будет запущен, и ошибка будет обработана нормально.Но затем запустится обработчик закрытия сеанса, и при попытке записи в базу данных возникнет ошибка, из-за которой сработает оператор catch, который в зависимости от типа ошибки SQL вызовет исключение определенного типа, но эти классы должныбыть автозагрузкой. В этот момент (в обработчике закрытия сеанса) вы больше не можете автоматически загружать классы.

Проверьте , когда это происходит.Во время обычного выполнения PHP, или в каком-то «специальном» режиме PHP, таком как обработчик сеанса, или во время обработки ошибок?

В моем случае решение было добавить class_exists("MyClass", true) перед попыткой его использования.Я мог бы бросить нормальное исключение вместо этого.Исключение по-прежнему будет «Фатальным», так как не осталось ничего, чтобы его перехватить, но, по крайней мере, оно покажет исключение real , а не ошибку автозагрузки.

0 голосов
/ 06 июля 2011

Проблема возникает только при включенном операционном кеше APC.Я думаю, что функция __autoload в некоторых случаях не может работать должным образом с кешами.AFAIS только некоторые версии PHP и APC несовместимы друг с другом.

...