Błąd krytyczny PHP: nie można ponownie zadeklarować klasy


Odpowiedzi:


117

Oznacza to, że utworzyłeś już klasę.

Na przykład:

class Foo {}

// some code here

class Foo {}

To drugie Foo spowodowałoby błąd.


75
Ta odpowiedź nie jest tak pomocna jak odpowiedź AaronLS. Nie sądzę, żeby pytający zadał pytanie, gdyby napisał takie oczywiste powtórzenie (nawet w dość złożonej sytuacji). Wskazówka include_once pomaga w wyjaśnieniu niejasnej funkcji PHP.
DavidHyogo

2
Ten błąd może również wystąpić, jeśli zdefiniujesz metodę __construct więcej niż raz.
Jack Trowbridge

4
Po prostu użyj include_once ('FooBar.php'), aby dołączyć swoją klasę. Nazwa funkcji jest oczywista.
Marco Matarazzi

2
Odpowiedź AaronLS jest znacznie wyżej oceniana i można ją znaleźć poniżej .
qris,

1
Właściwie to doskonale odpowiada na pytanie i jest ponadczasowe, AaronLS przyjmuje założenie, a następnie próbuje rozwiązać problem, który można teraz rozwiązać na wiele lepszych sposobów.
TarranJones

317

Masz klasę o tej samej nazwie zadeklarowaną więcej niż raz. Może przez wiele dołączeń. Dołączając inne pliki, musisz użyć czegoś takiego jak

include_once "something.php";

aby zapobiec wielokrotnym wtrąceniom. Jest to bardzo łatwe, choć nie zawsze jest to oczywiste, ponieważ możesz mieć długi łańcuch plików dołączanych jeden do drugiego.


10
to była naprawdę pomoc pełna!
Marci-man

4
unikaj include_once , jest powolny, zamiast tego użyj czegoś innego, na przykład automatycznego ładowania :)
Timo Huovinen

21
@Timo Opierając się na testach porównawczych, które sprawdziłem, zauważalna różnica będzie wynosić około 1 sekundy, jeśli masz plik zawierający 100 000 include_once. Byłoby lepiej, gdybyś zoptymalizował dostęp do bazy danych lub inną logikę niż przedwczesna optymalizacja pliku przy użyciu technik niespełniających standardów, takich jak główne pliki dołączane. Funkcja automatycznego ładowania nie działa znacząco inaczej. Każdy funkcjonuje inaczej i nie są zamiennie odpowiednie. Możesz użyć jednego do drugiego, ale są przypadki narożne, w których nie działają tak samo.
AaronLS,

3
@Timo Cytowanie strony, do której utworzyłeś link „przy użyciu __autoload () jest odradzane i może zostać wycofane lub usunięte w przyszłości”.
AaronLS

1
@AaronLS Nie można edytować komentarzy w SO, link również prowadzi do lepszego przykładu . Zasugerowałem to po przeczytaniu komentarzy deweloperów APC i tego, jak nienawidził include_once (było mi go żal). Różnica wykracza poza samą wydajność.
Timo Huovinen

55

Dzieje się tak, gdy deklarujesz klasę więcej niż raz na stronie. Możesz to naprawić, opakowując tę ​​klasę instrukcją if (jak poniżej) lub możesz umieścić ją w osobnym pliku i użyć require_once()zamiast include().

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

5
It's class_exists ('TestClass') === false lub! class_exist ('TestClass')
Jens A. Koch

2
W komentarzu @ Jens-AndréKoch brakuje „s” w drugim przykładzie -> to jest class_exists('TestClass') === falselub!class_exists('TestClass')
furins

Prawdziwe. Dzięki za zwrócenie uwagi. Nie można już edytować ... limit czasu.
Jens A. Koch

Dzięki za tę logikę.
Frank

21

Użyj include_once();- dzięki temu Twoje kody zostaną uwzględnione tylko raz.


15

Stanie się tak, jeśli użyjemy którejkolwiek z wbudowanych klas w bibliotece php. Użyłem nazwy klasy jako katalogu i otrzymałem ten sam błąd. Jeśli pojawi się błąd, najpierw upewnij się, że nazwa klasy, której używasz, nie jest jedną z klas wbudowanych.


Tutaj jest dla mnie złota odpowiedź - nawet nie sądziłem, że PHP może mieć taką samą nazwę klasy jak ja!
Jamie M

12

Ten błąd może również wystąpić, jeśli zdefiniujesz __constructmetodę więcej niż raz.


2
To powinien być komentarz do już zaakceptowanej i bardzo pozytywnej odpowiedzi
Jarosław

8

Czasami dzieje się tak z powodu błędów w FastCGI PHP.

Spróbuj go ponownie uruchomić. W Ubuntu jest to:

service php-fastcgi restart

Ok, to rozwiązanie, ale nie rozwiązuje problemu. W moim przypadku problem pojawia się losowo raz lub dwa razy w miesiącu. :(
SkaJess

@SkaJess - możesz dodać polecenie restartu do crontab, aby restartować co godzinę. brudny - ale zapewni, że maksymalny czas przestoju Twojej witryny wyniesie 1 godzinę.
luchaninov

@how - nie jest to dla mnie dobre rozwiązanie, ponieważ php w ciągu dnia spada. Myślę, że w taki sposób, że codziennie w nocy dodam polecenie restartu. W drugiej kolejności rozważę aktualizację IIS i PHP.
SkaJess

6

Miałem ten sam problem podczas używania w autoloadnastępujący sposób:

<?php

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


__autoload("MyClass1");

$obj = new MyClass1();

?>

aw drugiej klasie:

namespace testClassNamespace;


class MyClass1
{

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

Rozwiązaniem jest zachowanie zgodności przestrzeni nazw, w moim przykładzie namespace testClassNamespace;w obu plikach.


3

Tylko dodawanie;

Ten błąd może również wystąpić, jeśli przez pomyłkę umieścisz funkcję w innej funkcji.


3

Wydaje się, że PHP 5.3 (myślę że starsze wersje także) ma problem z tą samą nazwą w różnych przypadkach. Więc miałem ten problem, gdy miał klasę Login i interfejs, który implementuje LogIn. Po zmianie nazwy LogIn na Log_In problem został rozwiązany.


3

Po prostu zrób jedną rzecz, gdy dołączasz lub wymagasz nazwy pliku, a mianowicie class.login.php. Możesz to załączyć w ten sposób:

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

W ten sposób nigdy nie zgłasza błędu.


2

Ta funkcja wydrukuje stos informujący, skąd został wywołany:

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>';
}

Wywołaj tę funkcję u góry pliku zawierającego twoją klasę.

Czasami wydrukuje się tylko raz, mimo że Twoja klasa jest uwzględniana dwa lub więcej razy. Dzieje się tak, ponieważ PHP faktycznie analizuje wszystkie klasy najwyższego poziomu w pliku przed wykonaniem jakiegokolwiek kodu i natychmiast zgłasza błąd krytyczny. Aby temu zaradzić, zawiń swoją deklarację klasy if(true) { ... }, co przeniesie twoją klasę o jeden poziom niżej w zakresie. Następnie powinieneś uzyskać dwa ślady przed krytycznymi błędami PHP.

Powinno to pomóc w znalezieniu miejsca, w którym Twoja klasa jest wielokrotnie uwzględniana w złożonym projekcie.


1

Czy korzystałeś z Zend Framework? Ja też mam ten sam problem.
Rozwiązałem to, komentując ten następujący wiersz w config/application.ini:

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

Mam nadzieję, że to Ci pomoże.


1

Innym możliwym winowajcą jest kontrola źródła i nierozwiązane konflikty. SVN może spowodować, że ta sama klasa pojawi się dwukrotnie w pliku kodu powodującym konflikt; dwie alternatywne wersje tego („moja” i „ich”).


1

Napotkałem ten sam problem: nowsza wersja php nie radzi sobie tak samo z wieloma włączeniami tego samego pliku (jako biblioteki), więc teraz muszę zmienić wszystkie moje dołączenia przez niektóre include_once.

Lub te sztuczki mogą pomóc, jeśli nie masz zbyt wielu zajęć w swojej bibliotece ...

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

1

Miałem ten sam problem „Błąd krytyczny PHP: nie można ponownie zadeklarować klasy XYZ.php”.

Mam dwa katalogi, takie jak controlleri, modeli przesłałem przez pomyłkę XYZ.php w obu katalogach. (Więc plik o tej samej nazwie powoduje problem).

Pierwsze rozwiązanie:

Znajdź w całym projekcie i upewnij się, że masz tylko jedną klasę XYZ.php.

Drugie rozwiązanie:

Dodaj przestrzeń nazw do swojej klasy, aby móc używać tej samej nazwy klasy.


0

napotkałem ten sam problem. dowiedziałem się, że sprawa była nazwą klasy. poradziłem sobie z tym, zmieniając nazwę. stąd rozwiązanie problemu.


0

W rzeczywistości oznacza to, że klasa jest już zadeklarowana na stronie i próbujesz ją odtworzyć.

Oto prosta technika.

Rozwiązałem problem w następujący sposób. Mam nadzieję, że to ci trochę pomoże.

if(!class_exists("testClassIfExist"))
{
    require_once("testClassIfExist.php");
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.