Невозможно переопределить класс на 'require_once'
UPDATE
Я отказался от CodeIgniter и желание создать веб-интерфейс вокруг моего приложения базы данных с PHP, так как не было никакого способа избавиться от этой ошибки...
Исключение
Я получаю это исключение:
Fatal error: require_once(): Cannot redeclare class doctrine\orm\abstractquery in Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php on line 190
Call Stack:
0.0007 330016 1. {main}() Q:\Digest\index.php:0
0.0058 330800 2. require_once('Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php') Q:\Digest\index.php:163
0.2207 935856 3. call_user_func_array() Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php:297
0.2207 935904 4. Crud->index() Q:\Digest\lib\CodeIgniter\core\CodeIgniter.php:0
0.2574 1065064 5. Crud->__getEntities() Q:\Digest\Application\controllers\crud.php:19
0.2649 1121824 6. Doctrine\ORM\AbstractQuery->getResult() Q:\Digest\Application\controllers\crud.php:49
0.2649 1121976 7. Doctrine\ORM\AbstractQuery->execute() Q:\Digest\lib\Doctrine\ORM\AbstractQuery.php:366
0.2651 1121976 8. Doctrine\ORM\Query->_doExecute() Q:\Digest\lib\Doctrine\ORM\AbstractQuery.php:528
0.2651 1121976 9. Doctrine\ORM\Query->_parse() Q:\Digest\lib\Doctrine\ORM\Query.php:223
0.2848 1185896 10. Doctrine\ORM\Query\Parser->parse() Q:\Digest\lib\Doctrine\ORM\Query.php:203
0.3089 1238704 11. Doctrine\ORM\Query\SqlWalker->getExecutor() Q:\Digest\lib\Doctrine\ORM\Query\Parser.php:311
0.3090 1239104 12. Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
0.3107 1241104 13. require_once('Q:\Digest\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php') Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
0.3108 1241440 14. Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
Я использую Doctrine 2.0, с Symfony UniversalClassLoader
, как можно видеть выше, для реализации анализа данных script. Чтобы просмотреть результаты, я создал проект CodeIgniter.
Вот что меня озадачило этим исключением: я устранил почти все разумные причины и ничего не нашел. Скажи мне, если я сделал что-то неправильно в раундах элеминации здесь.
Если у кого-то есть какая-то подсказка о том, что здесь может быть неправильным, пожалуйста, помогите. Если вы думаете, что есть какая-либо информация, которую я забыл, также, пожалуйста, скажите мне.
Спасибо.
Устранение повторяющихся деклараций
Это говорит мне, что я не могу переопределить класс. У меня есть grepped все мои файлы, и этот класс определяется только в его конкретном файле "Doctrine/ORM/AbstractQuery.php".
Обратите внимание, что изначально ошибка была сообщена при вызове require
в строке 190 Symfony UniversalClassLoader.php, и я изменил ее на require_once
, чтобы убедиться, что файл не загружен дважды.
Устранение файловой системы, чувствительной к регистру
Из-за примечания я нашел здесь, я думаю, мне следует поделиться тем, что я запускаю PHP 5.3.5 в Windows 7. Это должен означать, что ошибка/признак, описанный ниже, не имеет никакого влияния.
Это поведение изменилось в PHP 5, поэтому например, с Windows, путь сначала нормализовали, так что C:\PROGRA ~ 1\A.php реализуется одинаково как C:\Program Files\a.php и файл включен только один раз.
Устранение дублирования require
Теперь я дошел до того, что заменил каждый вызов в каждой библиотеке (и моем собственном коде) на функцию require
на один на require_once
, и ошибка не изменилась. Это означает, что теперь я могу с уверенностью сказать, что вызов require
не отвечает. Мой вопрос остается: что такое?
Выход отладчика
Запуск отладчика ничего мне не приносит:
...
0.4658 1274904 -> Doctrine\ORM\Query\SqlWalker->getExecutor() Q:\Digest\lib\Doctrine\ORM\Query\Parser.php:311
0.4660 1275304 -> Logger::autoload() Q:\Digest\lib\Log4PHP\Logger.php:0
0.4662 1275304 -> Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
0.4663 1275384 -> strripos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:183
0.4665 1275400 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:185
0.4666 1275488 -> strpos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:187
0.4667 1275520 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:188
0.4668 1275672 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4669 1275696 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4671 1275656 -> file_exists() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
0.4700 1277304 -> require_once(Q:\Digest\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php) Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:192
0.4702 1277640 -> Logger::autoload() Q:\Digest\lib\Log4PHP\Logger.php:0
0.4703 1277640 -> Symfony\Component\HttpFoundation\UniversalClassLoader->loadClass() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:0
0.4704 1277720 -> strripos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:183
0.4706 1277736 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:185
0.4707 1278280 -> strpos() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:187
0.4708 1278312 -> substr() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:188
0.4709 1278464 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4711 1278488 -> str_replace() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:189
0.4712 1278448 -> file_exists() Q:\Digest\lib\Symfony\Component\HttpFoundation\UniversalClassLoader.php:190
0.5259 zu
TRACE END [2011-03-28 11:28:00]
Некоторые дополнительные проверки говорят мне, что файл, загружаемый при его сбое, составляет lib\Doctrine\ORM\Query\Exec\AbstractSqlExecutor.php
или класс AbstractSqlExecutor
... таким образом, что-то совершенно не связанное.
Ответы
Ответ 1
Другие возможности, о которых я могу думать (после снятия предложенных ответов):
-
Может быть, есть символическая ссылка где-нибудь в вашем исходном дереве? (Я обнаружил, что require_once() недостаточно умен, чтобы знать, что вы импортируете один и тот же файл, если путь выглядит иначе).
-
Может быть, есть где-то в ваших зависимостях включения? (если A включает B, который включает C, который включает A, я обнаружил, что require_once() недостаточно умен, чтобы разорвать цикл).
Ответ 2
Проверьте, установлен ли на вашем сервере APC. Если это попытка отключить его, обновите или установите для параметра apc.include_once_override значение 0.
Ответ 3
Слишком плохо, что ты сдался. Простым способом исправить это было бы:
if (!class_exists('ClassName')) {
}
вокруг файла. Это не исправляет ошибку, просто заставляет симптом уходить. К сожалению, Codeigniter не слишком умен в отношении создания объектов PHP5 и может дважды загружать ваш код.
Ответ 4
Используете ли вы __autoload() в любом месте? Это единственное, о чем я могу думать, если у вас на самом деле нет того же класса, что и в двух разных файлах.
Ответ 5
Если вы изучили все очевидные решения, то каждый раз, когда я сталкивался с этой проблемой, это была проблема кэширования, как правило, с APC.
Если это проблема кэширования apc, для ее исправления добавьте следующее в файл верхнего уровня в верхней части файла:
apc_clear_cache();
Если проблема исчезнет, вы знаете, что это проблема. В частности, в средах с общим хостингом, если файлы меняются, я обнаружил, что APC почти непригодна для использования, поэтому я всегда добавляю это в файл верхнего уровня, который я могу вызвать.
PS: Я даже сталкиваюсь с ситуациями, когда, похоже, APC кэширует неправильный файл, так что он сбой, когда я включаю файл, который явно никогда не имел класс, на который он жалуется.
Ответ 6
Если вы включаете UniveralClassLoader
несколькими способами, например:
- через
require_once
- использовать
Symfony\Component\ClassLoader\UniversalClassLoader;
то фатальная ошибка может быть вызвана тем, что компилятор считает переопределением класса. Удалите строку require_once
, если она существует, и просто используйте вторую опцию.
Ответ 7
у вас может быть один и тот же класс, определенный в двух файлах. require_once() в этом случае не поможет
Ответ 8
root
+ a.php
+ c/
+c.php
+ b.php
_ a.php _
require_once 'c/b.php'; -> will work
require_once 'c/c.php'; -> will work
_ c/b.php _
require_once 'c.php'; -> will work too 'c/c.php'!='c.php' :(