Существует ли способ, которым я могу заставить PHP проигнорировать переобъявления классов, а не блевать ФАТАЛЬНАЯ ОШИБКА? Или, по крайней мере, выдайте исключение? (Я мог легко поймать его затем и продолжить двигаться (также журнал предпринятая автозагрузка).)
Я предполагаю не, и фатальная ошибка является фатальной ошибкой - в конце концов, в девяносто девять из ста случаев, это - довольно разумное поведение - и я должен буду, вероятно, просто зафиксировать экземпляры его инициированный в зависимости от конкретного случая. Но возможно кому-то более умному, чем я выяснили это.
Если бы Вы спрашиваете себя, "С какой стати Вы хотели бы сделать это?", продолжать читать.
Я работаю над инструментом, который использует Отражение для агрегации определенной информации об используемых функциях и классах. Одним из аргументов сценария является дополнительный файл начальной загрузки для создания Отражения более надежным с автозагрузкой (меньше ReflectionExceptions
это заканчивается пойманное и инициирование эвристики нейтрализации, потому что классы неизвестны в определенном файле).
Теперь, загружающиеся загрузки, которые прекрасный автопогрузчик (автопогрузчики), и сценарий выполняет, как предназначено, перемещения через несколько сотен файлов без жалобы, пока я не наткнулся на препятствие:
Фатальная ошибка PHP: не Может повторно объявить класс PHPUnit_Framework_Constraint в/usr/share/php/PHPUnit/Framework/Constraint.php на строке 62
У меня есть две проблемы:
Один, я понятия не имею, что инициировало это. Я скорректировал начальную загрузку, которая используется, но только чередуется между, 'Не может повторно объявить', и 'Не удалось открыть файл', в зависимости от включать используемого пути. Нет никакого второго плана, т.е. никакого смысла, где никакая ошибка не происходит. Однако, я все еще занимаюсь расследованиями. (Эта проблема не то, что вопрос о, все же.)
Два, что еще более важно, и ведущий к предмету этого вопроса, мне нужен способ поймать его. Я попытался писать пользовательский обработчик ошибок, но это, кажется, не хочет работать на Fatal error
s (несколько разумно, можно было бы спорить).
Я намереваюсь выпустить этот инструмент в мир с открытым исходным кодом в какой-то момент, и это кажется мне довольно недопустимым поведением. У меня есть эвристика нейтрализации для классов, которые не существуют - я быть бы они объявляться однажды слишком редко, чем слишком часто, но не злоупотребляя эвристику, также, который должен сказать, я действительно хочу предложить возможность использования bootstrapper. Не повреждая сценарий. Когда-либо. Даже если это - худший автопогрузчик в истории автопогрузчиков.
(Для выделения: Я не хочу справку со своими автопогрузчиками. Это не то, о чем этот вопрос.)
Одним из лучших вариантов избежать Cannot redeclare
является функция class_exists
. Вы можете использовать ее в автозагрузке для предотвращения повторного объявления классов. С помощью class_exists
вы не обязаны ловить ошибку, вы просто предотвращаете ее.
На самом деле существует два вида фатальных ошибок: улавливаемые и не улавливаемые. Повторное объявление класса не вызывает E_RECOVERABLE_ERROR
(ошибка, которую можно поймать), и вы не можете ее обработать.
Итак, ответ на ваш вопрос: "Нельзя."
.Автозагрузка никогда не будет автоматически пытаться загрузить уже загруженный класс. Если у вас есть класс >1 с таким же именем, вы, вероятно, делаете это неправильно.
Если вы анализируете «небезопасный» код, вы можете поискать в файле имя класса, прежде чем пытаться загрузить его, но это следует использовать только в крайнем случае, так как это огромная трата процессора и, вероятно, просто скрытие допустимых ошибок.
Если у вас есть структура требования и система автозагрузки, вы можете включить файл один раз в автозагрузку, а затем снова в требование. Вы можете взломать исправление, обернув класс с помощью if( class_exists(