Фатальна помилка 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"), щоб включити свій клас. Назва функції - сама пояснювальна.
Marco Matarazzi

2
Відповідь AaronLS набагато вища, і ви можете знайти її тут .
qris

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

317

У вас однойменний клас, оголошений не один раз. Можливо, через кілька включає. При включенні інших файлів вам потрібно використовувати щось на кшталт

include_once "something.php";

для запобігання декількох включень. Це дуже легко, хоча і не завжди очевидно, оскільки у вас може бути довгий ланцюжок файлів, що включаються один до одного.


10
це справді допомогло повною мірою!
Marci-man

4
уникайте include_once , це повільно, використовуйте щось інше, наприклад автозавантаження :)
Timo Huovinen

21
@Timo Виходячи з орієнтирів, які я переглянув, помітна різниця буде приблизно в 1 секунду, якщо у вас є файл зі 100 000 включити_онце. Вам буде краще оптимізувати доступ до БД або іншу логіку, ніж передчасна оптимізація вашого файлу включає використання нестандартних методів, таких як master include files. Функція автоматичного завантаження не відрізняється значною мірою. Кожна функція по-різному, і не є взаємозамінними. Можна використовувати одне для іншого, але є кутові випадки, коли вони функціонують не однаково.
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" відсутній у другому прикладі -> it class_exists('TestClass') === falseor!class_exists('TestClass')
furins

Правда. Дякуємо, що вказали на це. Більше не можна редагувати .. тайм-аут.
Єнс А. Кох

Дякую за цю логіку.
Френк

21

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


15

Це станеться, якщо ми будемо використовувати будь-який із вбудованих класів у бібліотеці php. Я використовував ім'я класу як Каталог, і я отримав ту ж помилку. Якщо ви помилитеся спочатку, переконайтесь, що назва класу, який ви використовуєте, не є одним із вбудованих класів.


Золотий відповідь тут для мене - я навіть не думав, що PHP, можливо, мав те саме ім’я класу, що і я!
Джеймі М

12

Ця помилка також може виникнути, якщо __constructметод визначати кілька разів.


2
Це має бути коментар до вже прийнятої та висококваліфікованої відповіді
Ярослав

8

Іноді це трапляється через деякі помилки у FastCGI PHP.

Спробуйте перезапустити його. В 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. Після перейменування входу в 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.