php не может повторно объявить _autoload()

Я все больше углубляюсь в php и создаю свой собственный мини-фреймворк mvc для изучения ООП.

У меня есть файл .htaccess, который перенаправляет все на index.php. В index.php я включаю файл с именем bootstrap.php для анализа URL-адреса и загрузки файла php класса.

Теперь, когда я добавляю ActiveRecord http://www.phpactiverecord.org для доступа к базе данных. Я получаю сообщение об ошибке:

Неустранимая ошибка: невозможно повторно объявить класс AutoLoader в /home/i554246/public_html/mvc/lib/Autoloader.php в строке 4.

Я не знаю, как остановить конфликт.

индекс.php:

include(MVC_CORE_INCLUDE_PATH . DS . 'Bootstrap.php')
include(MVC_CORE_INCLUDE_PATH . DS . 'activerecord/ActiveRecord.php');

autoloader.php, который включен в bootstrap.php

<?php

class AutoLoader
{
    public static function Load($Class)
    {
        $File = BASEDIR.$Class.'.php';

        if(is_readable($File))
        {
            require($File);
        }
        else
        {
            die('Requested module "'.$Class.'" is missing. Execution stopped.');
        }
   }
}

spl_autoload_register('AutoLoader::Load');

ActiveRecord.php

if (!defined('PHP_ACTIVERECORD_AUTOLOAD_DISABLE'))
    spl_autoload_register('activerecord_autoload',false,PHP_ACTIVERECORD_AUTOLOAD_PREPEND);

function activerecord_autoload($class_name)
{
    $path = ActiveRecord\Config::instance()->get_model_directory();
    $root = realpath(isset($path) ? $path : '.');

    if (($namespaces = ActiveRecord\get_namespaces($class_name)))
    {
        $class_name = array_pop($namespaces);
        $directories = array();

        foreach ($namespaces as $directory)
            $directories[] = $directory;

        $root .= DIRECTORY_SEPARATOR . implode($directories, DIRECTORY_SEPARATOR);
    }

    $file = "$root/$class_name.php";

    if (file_exists($file))
        require $file;
}
?>

person Keith Power    schedule 14.06.2012    source источник


Ответы (4)


Возможно изменить

if (file_exists($file))
    require $file;

to

if (file_exists($file))
    require_once($file);
person Kevin Bray    schedule 14.06.2012
comment
Если возможно, я бы не хотел ничего менять в ActiveRecord.php, поскольку он является сторонним и может привести к проблемам с обновлением. Был бы другой способ? - person Keith Power; 14.06.2012
comment
Возможно, но я склонен согласиться с Нэнн, что следующим шагом должна быть отладка стека. Я думаю, вам нужен точный отчет о порядке, в котором происходят события. Также прислушайтесь к совету Нанн по поводу пространств имен — даже если в корне этой проблемы нет конфликта пространств имен, дополнительная дисциплина поможет вам исключить отвлекающие маневры. - person Kevin Bray; 14.06.2012

Вы либо пытаетесь включить файл дважды (вы можете использовать require_once), либо у вас есть 2 класса (один из библиотеки, которую вы используете?) с тем же именем.

если кажется, что есть 2 класса с именем AutoLoader, вы можете заглянуть в пространства имен. Я не могу припомнить, чтобы у phpactiverecord был класс с таким названием, но, поскольку вы могли использовать несколько библиотек, вы должны были столкнуться с этим.

Лучшим способом было бы поместить свой собственный класс автозагрузчика в файл namespace. Убедитесь, что все ваши вызовы корректны, поэтому вызовы автозагрузчика должны иметь \yournamespace\ перед ним, а вызовы внутри автозагрузчика могут потребовать добавления \ к (например, \Exception)

person Nanne    schedule 14.06.2012
comment
Если я сначала загружаю ActiceRecord.php, возникает проблема с фатальной ошибкой: невозможно повторно объявить activerecord_autoload() (ранее объявленный в /home/i554246/public_html/mvc/lib/activerecord/ActiveRecord.php:28) в /home/i554246 /public_html/mvc/lib/activerecord/ActiveRecord.php в строке 48 - person Keith Power; 14.06.2012
comment
Что ж, у activerecord нет этой проблемы, так что должно быть что-то еще. Вероятно, вы включаете этот файл дважды, может быть, его включают оба автозагрузчика? Я бы посоветовал вам просто отладить его: поместите что-то, что записывает трассировку стека в этот дважды вызываемый файл, а затем проверьте, что происходит: теперь вы знаете, какие части кода загружают этот файл. во второй раз вы получите сообщение об ошибке, но затем вы можете продолжить и предотвратить его загрузку дважды. - person Nanne; 14.06.2012
comment
Спасибо, я добавил require_once в ActiveRecord.php, и ошибка перешла к следующему включенному и пожаловалась на этот класс. Я снова добавил к этому require_once, и ошибка снова перешла к следующему включению и не смогла повторно объявить этот класс. Кажется, перезагружается index.php, где находятся все включения. Очень странно, происходит только тогда, когда я включил ActiveRecords. - person Keith Power; 14.06.2012
comment
Может быть, автозагрузчик activerecord срабатывает по тем же запросам, что и ваш собственный автозагрузчик? так он загружает ваш автозагрузчик дважды? или все, что загружается автоматически, автоматически загружается дважды? - person Nanne; 14.06.2012
comment
да, думаю так, все новое для меня, поэтому я немного смущен. Кажется, это происходит с этой строкой, которая есть у меня в index.php под включением $Bootstrap = new Bootstrap(); - person Keith Power; 14.06.2012
comment
Что ж, как я уже сказал, вы должны пока оставить ошибку и добавить логирование! Используйте error_log и debug_backtrace, чтобы узнать, что и когда делает ваш код, а затем вы сможете увидеть, почему и как какой-то файл включается дважды. - person Nanne; 14.06.2012

PHP-ActiveRecord не имеет класса AutoLoader. Я думаю, что здесь происходит то, что у вас есть два загрузчика, которые загружают файл.

Поскольку он совместим с PSR-0, вы можете загрузить его с помощью собственной утилиты загрузки (при условии, что она поддерживает это соглашение). Если вы это сделаете, просто отключите утилиту автозагрузки PHP-AR.

define('PHP_ACTIVERECORD_AUTOLOAD_DISABLE', true);

Ванильный загрузчик наиболее полезен для поиска классов моделей, которые не понадобятся, если вы поместите их в собственное пространство имен. Поскольку ваш фреймворк может не следовать соглашению PHP-AR относительно расположения моделей, кажется правильным отключить этот автозагрузчик.

Посмотрите этот пример интеграции PHP-AR с литиевой платформой: li3_activerecord

person greut    schedule 14.06.2012

я переместил линию

$Bootstrap = new Bootstrap(); 

под

include(MVC_CORE_INCLUDE_PATH . DS . 'Bootstrap.php'); 
include(MVC_CORE_INCLUDE_PATH . DS . 'Controller.php'); 

но выше

require_once 'lib/activerecord/ActiveRecord.php'; the ActiveRecord seemed to want to load it again
person Keith Power    schedule 14.06.2012