Неустранимая ошибка PHP: невозможно повторно объявить класс


162

Кто-нибудь знает, что может вызвать эту проблему?

Неустранимая ошибка PHP: невозможно повторно объявить класс


11
Это может добавить с APC + autload см stackoverflow.com/questions/4575341/...
gagarine

5
Используйте автозагрузку, или вы также можете попробоватьif(!class_exists('YourClass')){ include 'YourClass.php'; }
Тимо Хуовинен

Ответы:


117

Это означает, что вы уже создали класс.

Например:

class Foo {}

// some code here

class Foo {}

Тот второй Фу выдаст ошибку.


75
Этот ответ не так полезен, как AaronLS. Я не думаю, что спрашивающий задал бы вопрос, если бы он написал очевидное повторение, подобное этому (даже в довольно сложной ситуации). Подсказка include_once помогает прояснить скрытую особенность PHP.
DavidHyogo

2
Эта ошибка также может возникать, если вы определяете метод __construct более одного раза.
Джек Троубридж

4
Просто используйте include_once ('FooBar.php'), чтобы включить ваш класс. Название функции говорит само за себя.
Марко Матарацци

2
Ответ AaronLS намного выше, и вы можете найти его здесь .
Крис

1
На самом деле это прекрасно отвечает на вопрос, и он вне времени, AaronLS делает предположение, а затем пытается решить проблему, которая теперь может быть решена многими лучшими способами.
TarranJones

317

У вас есть класс с тем же именем, объявленным более одного раза. Может быть, через несколько включений. При включении других файлов вам нужно использовать что-то вроде

include_once "something.php";

предотвратить множественные включения. Это очень легко сделать, хотя и не всегда очевидно, поскольку между вами может быть длинная цепочка файлов.


10
это было действительно помочь полностью!
Marci-man

4
избегайте include_once , он медленный, используйте что-то другое, например, автозагрузку :)
Timo Huovinen

21
@Timo На основании тестов, на которые я смотрел, будет заметна разница примерно в 1 секунду, если у вас есть файл с 100 000 include_once. Вам было бы лучше оптимизировать доступ к БД или другую логику, чем преждевременная оптимизация вашего файла, включающая использование нестандартных методов, таких как главные включаемые файлы. Функция автозагрузки не работает значительно иначе. Каждый функционирует по-своему и не является взаимозаменяемо подходящим. Вы можете использовать одно для другого, но в некоторых случаях они не работают одинаково.
AaronLS

3
@Timo Цитировать страницу, на которую вы ссылались, «использование __autoload () не рекомендуется и может быть признано устаревшим или удалено в будущем».
AaronLS

1
@AaronLS Невозможно редактировать комментарии для SO, ссылка также указывает на лучший пример . Я предложил это после прочтения комментариев разработчиков APC и того, как он ненавидит include_once (мне было плохо из-за него). Кроме того, разница не только в производительности.
Тимо Хуовинен

55

Это происходит, когда вы объявляете класс более одного раза на странице. Вы можете исправить это, обернув этот класс оператором if (как показано ниже), или вы можете поместить его в отдельный файл и использовать require_once()вместо include().

if (!class_exists('TestClass')) {
   // Put class TestClass here
}

5
это class_exists ('TestClass') === false или! class_exist ('TestClass')
Дженс А. Кох

2
В комментарии @ Jens-AndréKoch во втором примере отсутствует буква "s" -> это class_exists('TestClass') === falseили!class_exists('TestClass')
фуринс

Правда. Спасибо что подметил это. Больше не редактируется .. тайм-аут.
Дженс А. Кох

Спасибо за эту логику.
Франк

21

Используйте include_once();- при этом ваши коды будут включены только один раз.


15

Это произойдет, если мы будем использовать любой из встроенных классов в библиотеке php. Я использовал имя класса в качестве каталога и получил ту же ошибку. Если вы получили ошибку, сначала убедитесь, что имя класса, которое вы используете, не является одним из встроенных классов.


Золотой ответ здесь для меня - я даже не думал, что у PHP могло быть то же имя класса, которое я использовал!
Джейми М

12

Эта ошибка также может возникнуть, если вы определяете __constructметод более одного раза.


2
Это должен быть комментарий к уже принятому и высоко голосуемому ответу
Ярослав

8

Иногда это происходит из-за некоторых ошибок в PHP FastCGI.

Попробуйте перезапустить его. В Ubuntu это:

service php-fastcgi restart

Хорошо, это решение, но оно не решает проблему. В моем случае проблема появляется случайным образом один или два раза в месяц. :(
SkaJess

@SkaJess - вы можете добавить команду перезапуска в crontab для перезапуска ежечасно. грязный - но гарантирует, что максимальное время простоя вашего сайта будет 1 час.
Лучанинов

@how - это не очень хорошее решение для меня, потому что php падает в течение рабочего дня. Я думаю, что одним способом я буду добавлять команду перезагрузки ежедневно в течение ночи. Во-вторых, я рассмотрю возможность обновления IIS и PHP.
SkaJess

6

У меня была такая же проблема при использовании autoloadследующим образом:

<?php

function __autoload($class_name)
{
    include $class_name . '.php';
}


__autoload("MyClass1");

$obj = new MyClass1();

?>

а в другом классе было:

namespace testClassNamespace;


class MyClass1
{

    function  __construct()
    {
        echo "MyClass1 constructor";
    }
}

Решение состоит в том, чтобы сохранить совместимость пространства имен, в моем примере namespace testClassNamespace;в обоих файлах.


3

Просто добавляю;

Эта ошибка также может возникнуть, если вы по ошибке поместили функцию в другую функцию.


3

PHP 5.3 (я думаю, что и более старые версии), кажется, имеет проблемы с тем же именем в разных случаях. Так что у меня возникла эта проблема, когда у класса был класс Login и интерфейс, в котором он реализовывал LogIn. После того, как я переименовал LogIn в Log_In, проблема была решена.


3

Просто сделайте одну вещь, когда вы включаете или запрашиваете имя файла, а именно class.login.php. Вы можете включить это так:

include_once class.login.php or 
require_once class.login.php

Таким образом, это никогда не выдает ошибку.


2

Эта функция напечатает стек, сообщающий вам, откуда он был вызван:

function PrintTrace() {
    $trace = debug_backtrace();
    echo '<pre>';
    $sb = array();
    foreach($trace as $item) {
        if(isset($item['file'])) {
            $sb[] = htmlspecialchars("$item[file]:$item[line]");
        } else {
            $sb[] = htmlspecialchars("$item[class]:$item[function]");
        }
    }
    echo implode("\n",$sb);
    echo '</pre>';
}

Вызовите эту функцию вверху файла, который включает ваш класс.

Иногда он будет напечатан только один раз, даже если ваш класс включен два или более раз. Это связано с тем, что PHP фактически анализирует все классы верхнего уровня в файле перед выполнением любого кода и немедленно генерирует фатальную ошибку. Чтобы исправить это, оберните объявление класса вif(true) { ... } , которая переместит ваш класс на уровень в области видимости. Тогда вы должны получить две трассировки до фатальных ошибок PHP.

Это должно помочь вам найти, где ваш класс включается несколько раз в сложный проект.


1

Вы использовали Zend Framework? У меня такая же проблема.
Я решил это, закомментировав следующую строку config/application.ini:

;includePaths.library = APPLICATION_PATH "/../library"

Я надеюсь, что это поможет вам.


1

Другой возможный виновник - контроль источников и неразрешенные конфликты. SVN может привести к тому, что один и тот же класс появится дважды в файле конфликтующего кода; две его альтернативные версии («моя» и «их»).


1

Я столкнулся с той же проблемой: более новая версия php не работает одинаково с несколькими включениями одного и того же файла (как библиотеки), поэтому теперь мне нужно изменить все мои включения с помощью include_once.

Или эти трюки могут помочь, если у вас не слишком много классов в вашей библиотеке ...

if( class_exists('TestClass') != true )
{
   //your definition of TestClass
}

1

У меня была та же проблема "PHP Fatal error: Невозможно повторно объявить класс XYZ.php".

У меня есть два каталога, как controllerи modelя по ошибке загрузил XYZ.php в обоих каталогах (поэтому файл с одинаковым именем вызывает проблему).

Первое решение:

Найдите в своем проекте и убедитесь, что у вас есть только один класс XYZ.php.

Второе решение:

Добавьте пространство имен в свой класс, чтобы вы могли использовать то же имя класса.


0

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


0

На самом деле это означает, что класс уже объявлен на странице, и вы пытаетесь воссоздать его.

Простая техника заключается в следующем.

Я решил проблему с помощью следующего. Надеюсь, это поможет вам немного.

if(!class_exists("testClassIfExist"))
{
    require_once("testClassIfExist.php");
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.