Błędy parsowania / składni PHP; i jak je rozwiązać

652

Wszyscy napotykają błędy składniowe. Nawet doświadczeni programiści tworzą literówki. Dla początkujących jest to tylko część procesu uczenia się. Jednak często interpretacja komunikatów o błędach, takich jak:

Błąd analizy PHP: błąd składni, nieoczekiwany „{” w index.php w linii 20

Nieoczekiwany symbol nie zawsze jest prawdziwym winowajcą. Ale numer wiersza daje przybliżone pojęcie, od czego zacząć szukać.

Zawsze patrz na kontekst kodu . Błąd składni często chowa się w wymienionych lub w poprzednich linii kodu . Porównaj swój kod z przykładami składni z podręcznika.

Chociaż nie każdy przypadek pasuje do drugiego. Istnieją jednak ogólne kroki w celu rozwiązania błędów składniowych . Te odniesienia podsumowały typowe pułapki:

Ściśle powiązane odniesienia:

I:

Podczas gdy Stack Overflow jest również mile widziany dla początkujących programistów, jest on głównie ukierunkowany na profesjonalne pytania programistyczne.

  • Odpowiedź na wszystkie błędy kodowania i wąskie literówki jest w większości nie na temat.
  • Zanim opublikujesz prośby o poprawienie składni, poświęć trochę czasu na wykonanie podstawowych kroków .
  • Jeśli nadal musisz to zrobić, pokaż swoją inicjatywę rozwiązywania problemów, próbuj poprawek i swój proces przemyślenia na temat tego, co wygląda lub może być złe.

Jeżeli twój przeglądarka wyświetla komunikaty o błędach, takie jak „Błąd składni: niedozwolony znak”, to tak naprawdę nie jestzwiązane, ale - błąd składniowy .


Błędy składniowe zgłaszane w kodzie dostawcy: Na koniec należy wziąć pod uwagę, że jeśli błąd składniowy nie został zgłoszony podczas edycji bazy kodu, ale po instalacji lub aktualizacji pakietu zewnętrznego dostawcy, może to wynikać z niezgodności wersji PHP, więc sprawdź wymagania dostawcy w stosunku do platformy Ustawiać.

mario
źródło
1
To nie wystarcza danych, aby być odpowiedzią, ale można napisać analizator z parsekit_compile_string i umieścić na nim bardziej przyjazne odpowiedzi. Jeśli zostanie zintegrowany z twoim IDE, może to być bardzo pouczające.
Owen Beresford,
4
Wkładasz w to imponującą ilość pracy. Szacunek dla tego. Prawdopodobnie bardzo dobrze dla nauczycieli uczy się szybkie wskazywanie błędów lub dla tych, którzy tworzą IDE lub wdrażają szybkie poprawki. Jednak IDE wykonają już za ciebie większość tej pracy, jak sugeruje @Panique. Ponadto w wielu przypadkach dobrym pomysłem jest rozpoczęcie od nowa od zera.
allprog
1
@ Fred-ii- Myślę, że większość przyczyn jest podobnych do T_IF / T_FOREACH / ...bloku. Chociaż chciałem skompilować bardziej niestandardowe podsumowanie dla pytań IF / ELSE / ELSEIF.
mario
1
@mario Nie wiem, jak to sformułować, ale czy te pytania i odpowiedzi mogą być nieco przepisane i bardziej uporządkowane? (komentarz temp)
Rizier123
2
Wiesz, chciałbym mieć tę listę, kiedy uczyłem się PHP lata temu. Bardzo pomocne, szczególnie dla początkujących.
Chipster

Odpowiedzi:

291

Jakie są błędy składniowe?

PHP należy do języków programowania w stylu C i imperatywnych . Ma sztywne reguły gramatyczne, których nie może odzyskać po napotkaniu niewłaściwie umieszczonych symboli lub identyfikatorów. Nie może odgadnąć twoich zamiarów kodowania.

Streszczenie składni definicji funkcji

Najważniejsze wskazówki

Istnieje kilka podstawowych środków ostrożności, które zawsze możesz podjąć:

  • Użyj właściwego wcięcia kodu lub zastosuj dowolny wzniosły styl kodowania. Czytelność zapobiega nieprawidłowościom.

  • Użyj IDE lub edytora dla PHP z podświetlaniem składni . Co również pomaga w równoważeniu nawiasów / nawiasów.

    Oczekiwany: średnik

  • Przeczytaj odniesienia do języka i przykłady w instrukcji. Dwa razy, aby stać się nieco biegłym.

Jak interpretować błędy analizatora składni

Typowy komunikat o błędzie składni brzmi:

Parse error: syntax error, unexpected T_STRING , oczekując ' ;' w file.php na linii 217

Która zawiera listę możliwych lokalizacji błędu składniowego. Zobacz wspomnianą nazwę pliku i numer linii .

Moniker takie jakT_STRING wyjaśnia symbol który parser / tokenizer nie może przetworzyć w końcu. Jednak niekoniecznie jest to przyczyną błędu składniowego.

Ważne jest, aby spojrzeć na poprzednie linie kodu . Często błędy składniowe to po prostu wpadki, które miały miejsce wcześniej. Numer wiersza błędu jest dokładnie tam, gdzie parser ostatecznie zrezygnował z przetworzenia wszystkiego.

Rozwiązywanie błędów składniowych

Istnieje wiele podejść do zawężania i naprawiania czkawek składniowych.

  • Otwórz wspomniany plik źródłowy. Spójrz na wspomnianą linię kodu .

    • W przypadku niekontrolowanych ciągów i niewłaściwie rozmieszczonych operatorów zwykle znajduje się winowajcę.

    • Przeczytaj linię od lewej do prawej i wyobraź sobie, co robi każdy symbol.

  • Bardziej regularnie musisz także patrzeć na poprzednie wiersze .

    • W szczególności brakuje brakujących ;średników na końcach / instrukcjach poprzedniego wiersza. (Przynajmniej z punktu widzenia stylu).

    • Jeśli {bloki kodu }są niepoprawnie zamknięte lub zagnieżdżone, może być konieczne zbadanie jeszcze bardziej kodu źródłowego. Użyj odpowiedniego wcięcia kodu, aby to uprościć.

  • Spójrz na kolorowanie składni !

    • Ciągi, zmienne i stałe powinny mieć różne kolory.

    • Operatorzy +-*/.powinni również mieć wyraźne zabarwienie. W przeciwnym razie mogą znajdować się w niewłaściwym kontekście.

    • Jeśli zauważysz, że zabarwienie sznurka rozciąga się zbyt daleko lub zbyt krótko, oznacza to, że masz nieskryty lub brakujący znacznik zamknięcia "lub 'sznurka.

    • Posiadanie obok siebie dwóch znaków interpunkcyjnych w tym samym kolorze może również oznaczać problemy. Zazwyczaj operatorzy samotny, jeśli nie jest to ++, --czy nawiasy następujące operatora. Dwa ciągi / identyfikatory bezpośrednio po sobie są niepoprawne w większości kontekstów.

  • Biała spacja jest twoim przyjacielem . Postępuj zgodnie z dowolnym stylem kodowania.

  • Tymczasowo przerywaj długie linie.

    • Możesz dowolnie dodawać znaki nowej linii między operatorami lub stałymi i łańcuchami. Analizator składni następnie skonkretyzuje numer linii pod kątem błędów analizy. Zamiast patrzeć na bardzo długi kod, możesz wyizolować brakujący lub źle umieszczony symbol składni.

    • Podziel złożone ifinstrukcje na odrębne lub zagnieżdżone ifwarunki.

    • Zamiast długich wzorów matematycznych lub łańcuchów logicznych użyj zmiennych tymczasowych, aby uprościć kod. (Bardziej czytelny = mniej błędów).

    • Dodaj nowe linie między:

      1. Kod, który możesz łatwo zidentyfikować jako poprawny,
      2. Części, których nie jesteś pewien,
      3. I linie, na które narzeka parser.

      Partycjonowanie bloków długiego kodu naprawdę pomaga zlokalizować źródło błędów składniowych.

  • Komentuj obraźliwy kod.

    • Jeśli nie możesz wyizolować źródła problemu, zacznij komentować (a tym samym tymczasowo usuwać) bloki kodu.

    • Jak tylko pozbyłeś się błędu analizy, znalazłeś źródło problemu. Przyjrzyj się bliżej.

    • Czasami chcesz tymczasowo usunąć pełne bloki funkcji / metody. (W przypadku niedopasowanych nawiasów klamrowych i błędnie wciętego kodu.)

    • Jeśli nie możesz rozwiązać problemu ze składnią, spróbuj przepisać skomentowane sekcje od zera .

  • Jako nowicjusz unikaj niektórych mylących konstrukcji składni.

    • ? :Operator warunków trójskładnikowych może kompaktować kod i jest rzeczywiście przydatny. Ale nie poprawia to czytelności we wszystkich przypadkach. Preferuj proste ifstwierdzenia, gdy nie są sprawdzone.

    • Alternatywna składnia PHP ( if:/ elseif:/ endif;) jest powszechna dla szablonów, ale prawdopodobnie łatwiejsza do naśladowania niż normalne bloki {kodu }.

  • Najczęstsze błędy nowoprzybyłych to:

    • Brakujące średniki ;do kończenia instrukcji / linii.

    • Niedopasowane cytaty ciągów "lub 'cytaty nieskalowane wewnątrz.

    • Zapomniani operatorzy, w szczególności dla .konkatenacji łańcuchów .

    • Niezrównoważone (nawiasy ). Policz je w zgłoszonej linii. Czy jest ich tyle samo?

  • Nie zapominaj, że rozwiązanie jednego problemu ze składnią może odkryć następny.

    • Jeśli sprawisz, że jeden problem zniknie, a inne pojawią się w poniższym kodzie, przeważnie jesteś na dobrej drodze.

    • Jeśli po edycji nowego błędu składniowego pojawia się w tym samym wierszu, wówczas próba zmiany była prawdopodobnie błędem. (Nie zawsze jednak.)

  • Przywróć kopię zapasową wcześniej działającego kodu, jeśli nie możesz go naprawić.

    • Przyjęcie systemu wersjonowania kodu źródłowego. Zawsze możesz wyświetlić diffuszkodzoną i ostatnią działającą wersję. Co może być pouczające o tym, na czym polega problem ze składnią.
  • Niewidzialne zbłąkane znaki Unicode : W niektórych przypadkach musisz użyć hekseditora lub innego edytora / przeglądarki na swoim źródle. Niektórych problemów nie można znaleźć na podstawie samego kodu.

    • Spróbuj grep --color -P -n "\[\x80-\xFF\]" file.phpjako pierwszy środek znaleźć symbole inne niż ASCII.

    • W szczególności BOMy, spacje o zerowej szerokości lub spacje nierozdzielające oraz inteligentne cytaty regularnie mogą znaleźć drogę do kodu źródłowego.

  • Zadbaj o to, jaki rodzaj łamania linii jest zapisywany w plikach.

    • PHP po prostu honoruje \nnowe linie, a nie \rzwroty karetki.

    • Co czasami stanowi problem dla użytkowników MacOS (nawet w systemie OS X w przypadku źle skonfigurowanych edytorów).

    • Często pojawia się tylko jako problem, gdy używane są jednowierszowe //lub #komentarze. /*...*/Komentarze wielowierszowe rzadko zakłócają analizator składni, gdy łamanie wierszy jest ignorowane.

  • Jeśli błąd składniowy nie jest przesyłany przez Internet : Zdarza się, że masz błąd składniowy na swoim komputerze. Ale opublikowanie tego samego pliku w Internecie już go nie pokazuje. Co może oznaczać tylko jedną z dwóch rzeczy:

    • Patrzysz na zły plik!

    • Lub twój kod zawiera niewidzialny zbłąkany Unicode (patrz wyżej). Możesz łatwo się dowiedzieć: po prostu skopiuj kod z formularza internetowego do edytora tekstu.

  • Sprawdź swoją wersję PHP . Nie wszystkie konstrukcje składniowe są dostępne na każdym serwerze.

    • php -v dla interpretera wiersza poleceń

    • <?php phpinfo(); dla tego wywołanego przez serwer WWW.


    To niekoniecznie jest to samo. W szczególności podczas pracy z frameworkami będziesz je dopasowywać.

  • Nie używaj zastrzeżonych słów kluczowych PHP jako identyfikatorów funkcji / metod, klas lub stałych.

  • Próba i błąd to ostatnia deska ratunku.

Jeśli wszystko inne zawiedzie, zawsze możesz google wyświetlić komunikat o błędzie. Symbole składniowe nie są tak łatwe do wyszukiwania (sam przepełnienie stosu jest indeksowane przez SymbolHound chociaż ). Dlatego może minąć kilka kolejnych stron, zanim znajdziesz coś istotnego.

Dalsze przewodniki:

Biały ekran śmierci

Jeśli witryna jest po prostu pusta, przyczyną jest zazwyczaj błąd składniowy. Włącz ich wyświetlanie za pomocą:

  • error_reporting = E_ALL
  • display_errors = 1

Na php.iniogół lub przez.htaccess dla mod_php, a nawet .user.iniz konfiguracjami FastCGI.

Włączenie go w uszkodzonym skrypcie jest za późno, ponieważ PHP nie może nawet zinterpretować / uruchomić pierwszego wiersza. Szybkim obejściem jest utworzenie skryptu opakowania, powiedz test.php:

<?php
   error_reporting(E_ALL);
   ini_set("display_errors", 1);
   include("./broken-script.php");

Następnie wywołaj błąd, uzyskując dostęp do tego skryptu opakowania.

Pomaga także włączyć PHP error_logi przeglądać serwer WWW,error.log gdy skrypt ulega awarii przy odpowiedziach HTTP 500.

mario
źródło
error_reporting(E_ALL | E_STRICT);dla wcześniejszych wersji PHP
Geo
2
Niektóre środowiska IDE (jak NetBeans) obsługują nie tylko podświetlanie składni, ale także formatowanie kodu. Jeśli nauczysz się prawidłowo formatować swój kod i poprosić IDE o ponowne sformatowanie na wszelki wypadek, możesz od czasu do czasu złapać trudne do wykrycia problemy, takie jak niedopasowane nawiasy klamrowe.
Josep Valls
115

Myślę, że ten temat jest całkowicie przesadzony / skomplikowany. Korzystanie z IDE jest sposobem na całkowite uniknięcie błędów składniowych. Powiedziałbym nawet, że praca bez IDE jest trochę nieprofesjonalna. Dlaczego? Ponieważ nowoczesne IDE sprawdzają składnię po każdym wpisanym znaku. Kiedy kodujesz, a cała linia zmienia kolor na czerwony, a duże ostrzeżenie pokazuje dokładny typ i dokładną pozycję błędu składni, wtedy absolutnie nie ma potrzeby szukania innego rozwiązania.

Używanie IDE do sprawdzania składni oznacza:

(Skutecznie) nigdy więcej nie napotkasz błędów składniowych, po prostu dlatego, że widzisz je poprawnie podczas pisania. Poważnie.

Doskonałe IDE z kontrolą składni (wszystkie z nich są dostępne dla systemów Linux, Windows i Mac):

  1. NetBeans [bezpłatny]
  2. PHPStorm [199 USD]
  3. Eclipse with PHP Plugin [bezpłatny]
  4. Sublime [80 USD] (głównie edytor tekstu, ale z możliwością rozszerzenia za pomocą wtyczek, takich jak PHP Parser Parser )
Sliq
źródło
2
To jest oczywiście. Jednak, jeśli odświeżysz tutaj IDE, czy możesz nieco rozwinąć, gdzie różnią się pod względem składni? Sublime to głównie edytor, a nie IDE; ale potem bardziej ładna i zgryźliwa; robi przede wszystkim podświetlanie składni, ale jest również możliwe przy dopasowywaniu nawiasów. Łatwo na przykład natychmiast wykrywa błędy T_CONSTANT_AND_ENCAPSED, w przeciwieństwie do PHPStorm; która jednak robi więcej kwadratowych linii dla błędów wbudowanych. Wskazówki składniowe NetBeans były bardziej tajemnicze niż nawet PHP (raczej relistingowanie dozwolonych konstrukcji). Czy możesz podzielić się swoim doświadczeniem na temat zalet / wad; jest twoim ulubionym Eclipse / PDT lub ...?
Mario
@mario Myślę, że naprawdę interesujesz się tym tematem, więc naprawdę nie chcę tutaj mówić nic złego, ale cały kod, który napisałem (i moi koledzy z zespołu, przyjaciele, którzy kodują, partnerzy niezależni) nigdy nie został wykonany z błędem składni. Myślę więc, że przynajmniej kontrola składni Netbeans / PHPStorm jest niezwykle potężna. Ale może źle odczytałem twoje pytanie. Daj mi kilka godzin ...;)
Sliq
Twoja odpowiedź jest już na miejscu. Pasuje do 99% naszych pytań. Jednak w kontekście tutaj chciałbym rozważyć kompromis, w którym IDE zapewnia bardziej przyjazne dla początkujących podpowiedzi . Prawdopodobnie jest to dla nas niewielkie, kolorystyka i linie są wystarczające, jeśli jesteś wystarczająco zorientowany. Ale przypuszczam, że różnice mogą być bardziej znaczące dla początkujących.
Mario
Czasami IDE nie jest wykonalną opcją. Na przykład szybkie edytowanie motywu lub wtyczki WordPress. Tak, mógłbym skopiować cały kod do IDE, ale potem muszę go otworzyć, wkleić wszystko tam, ustawić nagłówki i całą resztę marnowania czasu, kiedy mam nadzieję na szybką edycję. Teraz, jeśli opracowujesz nowe funkcje lub zaczynasz od zera, to tak, zrób to w środowisku IDE. Nie pożałujesz, że poświęciłeś trochę czasu na rozpoczęcie konfiguracji.
1934286
Widzę IDE jako zwiastun, a nie tylko zestaw narzędzi. Może nie jest to POPRAWIONE, ale może pomóc w znalezieniu błędów składniowych i zapobieganiu im. Wiele odpowiedzi tutaj mówi, że jeśli utrzymujesz swój kod w czystości, masz mniejszą szansę na popełnienie błędu i łatwiej go dostrzec. Cóż, dzięki automatycznemu wcięciu, podpowiedziom do kodu, zmiennemu występowaniu, automatycznie zamykającym się nawiasom klamrowym i automatycznemu formatowaniu oszczędza mi wiele literówek dziennie i jest główną zaletą, dlaczego używam jednego. Nie liczy się to wszystko poza zakresem tego pytania (debugger, złącze bazy danych, diagram uml itp.) IDE pozwoli Ci zaoszczędzić czas i zapobiegnie nie tylko błędom składni.
Louis Loudog Trottier
58

Niespodziewany [

Obecnie nieoczekiwany [nawias tablicowy jest często spotykany w nieaktualnych wersjach PHP. Składnia krótki tablica jest dostępna od PHP > = 5,4 . Obsługiwane są tylko starsze instalacje array().

$php53 = array(1, 2, 3);
$php54 = [1, 2, 3];
         

Dereferencje wyników funkcji tablic również nie są dostępne dla starszych wersji PHP:

$result = get_whatever()["key"];
                      

Odwołanie - co oznacza ten błąd w PHP? - „Błąd składni, nieoczekiwany \[ pokazuje najczęstsze i praktyczne obejścia.

Chociaż zawsze lepiej jest po prostu zaktualizować instalację PHP. W przypadku wspólnych planów hostingu najpierw sprawdź, czy np. SetHandler php56-fcgiMożna użyć do włączenia nowszego środowiska wykonawczego.

Zobacz też:

BTW, są też preprocesory i down-konwertery składni PHP 5.4 jeśli jesteś naprawdę przywiązany do starszych i wolniejszych wersji PHP.

Inne przyczyny nieoczekiwanych[ błędów składniowych

Jeśli nie jest to niezgodność wersji PHP, to często jest to zwykła pomyłka literowa lub błąd składni nowicjusza:

  • Nie możesz używać deklaracji / wyrażeń właściwości tablic w klasach , nawet w PHP 7.

    protected $var["x"] = "Nope";
                  
  • Często mylone [jest otwieranie nawiasów klamrowych {lub nawiasów (.

    foreach [$a as $b)
            

    Lub nawet:

    function foobar[$a, $b, $c] {
                   
  • Lub próbujemy wyzerować stałe (przed PHP 5.6) jako tablice:

    $var = const[123];
           

    Przynajmniej PHP interpretuje to constjako stałą nazwę.

    Jeśli chciałeś uzyskać dostęp do zmiennej tablicowej (co jest tutaj typową przyczyną), dodaj wiodący $sigil - tak więc staje się $varname.

  • Próbujesz użyć globalsłowa kluczowego na elemencie tablicy asocjacyjnej. To nie jest poprawna składnia:

    global $var['key'];


Nieoczekiwany ] zamykający nawias kwadratowy

Jest to nieco rzadsze, ale zdarzają się również wypadki składniowe z kończącym się ]wspornikiem tablicy .

  • Ponownie niedopasowania z )nawiasami lub }nawiasami klamrowymi są powszechne:

    function foobar($a, $b, $c] {
                              
  • Lub próbujemy zakończyć tablicę tam, gdzie jej nie ma:

    $var = 2];

    Co często występuje w deklaracjach tablic wieloliniowych i zagnieżdżonych .

    $array = [1,[2,3],4,[5,6[7,[8],[9,10]],11],12]],15];
                                                 

    Jeśli tak, użyj IDE do dopasowania nawiasów, aby znaleźć przedwczesne ]zamknięcie tablicy. Przynajmniej użyj więcej odstępów i znaków nowej linii, aby ją zawęzić.

Mario
źródło
Link powyżej konwertuje składnię PHP 5.4 github.com/IonutBajescu/short-arrays-to-long-arrays powyżej jest uszkodzony.
Danimal Reks
46

Nieoczekiwany T_VARIABLE

„Nieoczekiwany T_VARIABLE” oznacza, że ​​istnieje dosłowna $variablenazwa, która nie pasuje do bieżącej struktury wyrażeń / instrukcji.

celowo abstrakcyjny / niedokładny operator + schemat zmiennej $

  1. brakujący średnik

    Najczęściej wskazuje brakujący średnik w poprzednim wierszu. Zmienne przypisania następujące po instrukcji są dobrym wskaźnikiem, gdzie szukać:

           
    func1()
    $var = 1 + 2;     # parse error in line +2
  2. Łączenie ciągów

    Częstym nieszczęściem są konkatenacje łańcuchów z zapomnianym .operatorem:

                                   
    print "Here comes the value: "  $value;

    Przy okazji powinieneś preferować interpolację łańcuchów (podstawowe zmienne w podwójnych cudzysłowach), gdy tylko to poprawia czytelność. Co pozwala uniknąć problemów ze składnią.

    Interpolacja ciągów to podstawowa funkcja języka skryptowego . Nie ma wstydu w korzystaniu z niego. Zignoruj ​​wszelkie zalecenia mikrooptymalizacji, aby zmienna .konkatenacja była szybsza . To nie jest.

  3. Brakujące operatory wyrażeń

    Oczywiście ten sam problem może pojawić się w innych wyrażeniach, na przykład operacjach arytmetycznych:

               
    print 4 + 7 $var;

    PHP nie może zgadnąć , czy zmienna powinna zostać dodana, odjęta lub porównana itp.

  4. Listy

    To samo dotyczy list składniowych, takich jak w populacjach tablic, w których analizator składni wskazuje również oczekiwany przecinek, ,na przykład:

                                          
    $var = array("1" => $val, $val2, $val3 $val4);

    Lub listy parametrów funkcji:

                                    
    function myfunc($param1, $param2 $param3, $param4)

    Równoważnie widzisz to z listlub globaloświadczenia, lub gdy brakuje ;średnik w forpętli.

  5. Deklaracje klasowe

    Ten błąd analizatora składni występuje również w deklaracjach klas . Możesz przypisywać tylko stałe statyczne, a nie wyrażenia. Zatem parser narzeka na zmienne jako przypisane dane:

    class xyz {      
        var $value = $_GET["input"];

    Niedopasowane }zamykające się nawiasy klamrowe mogą w szczególności prowadzić tutaj. Jeśli metoda zostanie zakończona zbyt wcześnie (użyj poprawnego wcięcia!), Wówczas zmienna zbłąkana jest często umieszczana w treści deklaracji klasy.

  6. Zmienne po identyfikatorach

    Nigdy nie możesz mieć zmiennej bezpośrednio podążającej za identyfikatorem :

                 
    $this->myFunc$VAR();

    Przy okazji jest to częsty przykład, w którym intencją było użycie zmiennych zmiennych . W tym przypadku $this->{"myFunc$VAR"}();na przykład wyszukiwanie właściwości zmiennej .

    Należy pamiętać, że stosowanie zmiennych zmiennych powinno być wyjątkiem. Nowo przybyli często próbują używać ich zbyt swobodnie, nawet jeśli tablice byłyby prostsze i bardziej odpowiednie.

  7. Brakuje nawiasów po konstrukcjach językowych

    Hasty wpisując może prowadzić do zapomnianej otwierania lub zamykania nawiasu dla ifi fororaz foreachsprawozdania:

           
    foreach $array as $key) {

    Rozwiązanie: dodaj brakujące otwarcie (między instrukcją a zmienną.

                          
    if ($var = pdo_query($sql) {
         $result = 

    Kędzierzawy {klamra nie otworzy blok kodu, bez zamykania ifwyraz z )pierwszym nawiasem zamykającym.

  8. W przeciwnym razie nie oczekuje warunków

         
    else ($var >= 0)

    Rozwiązanie: Usuń warunki elselub użyj elseif.

  9. Potrzebujesz wsporników do zamknięcia

         
    function() uses $var {}

    Rozwiązanie: dodaj nawiasy kwadratowe $var.

  10. Niewidoczne białe znaki

    Jak wspomniano w odpowiedzi na odniesienie do „Niewidocznego zbłąkanego Unicode” (takiego jak niełamliwa spacja ), możesz również zobaczyć ten błąd w przypadku niczego niepodejrzewającego kodu, takiego jak:

    <?php
                              
    $var = new PDO(...);

    Jest to dość powszechne na początku plików i w przypadku kopiowania i wklejania kodu. Sprawdź za pomocą hekseditora, czy twój kod nie wydaje się zawierać problemu ze składnią.

Zobacz też

Mario
źródło
32

Nieoczekiwany T_CONSTANT_ENCAPSED_STRING
Nieoczekiwany T_ENCAPSED_AND_WHITESPACE

Nieporęczne nazwy T_CONSTANT_ENCAPSED_STRINGi T_ENCAPSED_AND_WHITESPACEodnoszą się do cytowanych literałów"string" .

Są używane w różnych kontekstach, ale problem ze składnią jest dość podobny. T_ENCAPSED… ostrzeżenia pojawiają się w kontekście podwójnie cytowanych ciągów, podczas gdy ciągi T_CONSTANT… są często mylone w prostych wyrażeniach lub instrukcjach PHP.

  1. Niepoprawna interpolacja zmiennych

    I najczęściej pojawia się w przypadku niepoprawnej interpolacji zmiennych PHP:

                                   
    echo "Here comes a $wrong['array'] access";

    Cytowanie kluczy tablic jest koniecznością w kontekście PHP. Ale w ciągach podwójnie cytowanych (lub HEREDOC) jest to błąd. Analizator składniowy narzeka na zawarty pojedynczy cytat 'string', ponieważ zwykle oczekuje tam literalnego identyfikatora / klucza.

    Mówiąc dokładniej, w przypadku podwójnych cudzysłowów w odniesieniu do tablic można stosować prostą składnię w stylu PHP2

    echo "This is only $valid[here] ...";

    Zagnieżdżone tablice lub głębsze odwołania do obiektów wymagają jednak złożonej składni wyrażeń kręconych :

    echo "Use {$array['as_usual']} with curly syntax.";

    W razie wątpliwości jest to zwykle bezpieczniejsze w użyciu. Często jest to nawet uważane za bardziej czytelne. A lepsze IDE faktycznie używają do tego wyraźnego kolorowania składni.

  2. Brak konkatenacji

    Jeśli ciąg znaków występuje po wyrażeniu, ale nie zawiera konkatenacji lub innego operatora, zobaczysz, że PHP narzeka na literał ciągu:

                           
    print "Hello " . WORLD  " !";

    Chociaż jest to oczywiste dla ciebie i dla mnie, PHP po prostu nie zgadnie, że łańcuch miał być tam dołączony.

  3. Mylące ciągi znaków cytatów

    Ten sam błąd składniowy występuje przy myleniu ograniczników ciągu . Ciąg rozpoczynający się od pojedynczego 'lub podwójnego "cudzysłowu również kończy się tym samym.

                    
    print "<a href="' . $link . '">click here</a>";
          ⌞⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟

    Ten przykład zaczął się od podwójnych cudzysłowów. Ale podwójne atrybuty były również przeznaczone dla atrybutów HTML. Zamierzony operator konkatenacji w obrębie został jednak zinterpretowany jako część drugiego ciągu w pojedynczych cudzysłowach.

    Wskazówka : Ustaw edytor / IDE, aby używał lekko wyraźnego kolorowania ciągów pojedynczych i podwójnych. (Pomaga także logice aplikacji preferować np. Ciągi cudzysłowów dla wyników tekstowych i ciągi cudzysłowów tylko dla wartości podobnych do stałych).

    Jest to dobry przykład, w którym nie powinieneś wyrwać się z podwójnych cudzysłowów. Zamiast tego po prostu użyj odpowiednich \"znaków ucieczki dla cytatów atrybutów HTML:

    print "<a href=\"{$link}\">click here</a>";

    Chociaż może to również prowadzić do pomyłek w składni, wszystkie lepsze IDE / edytory ponownie pomagają, inaczej kolorując cytowane znaki.

  4. Brak cytatu otwierającego

    Równie zapomniane jest otwieranie "/ 'cytowanie przepisu na błędy parsera:

                   
     make_url(login', 'open');

    Tutaj ', 'stałoby się literałem łańcuchowym po słowie, kiedy oczywiście loginmiał być parametrem łańcuchowym.

  5. Listy tablic

    Jeśli przegapisz ,przecinek w bloku tworzenia tablicy, analizator składni zobaczy dwa kolejne ciągi:

    array(               
         "key" => "value"
         "next" => "....",
    );

    Pamiętaj, że ostatni wiersz może zawsze zawierać dodatkowy przecinek, ale przeoczenie jednego z nich jest niewybaczalne. Które trudno odkryć bez podświetlania składni.

  6. Listy parametrów funkcji

    To samo dotyczy wywołań funkcji :

                             
    myfunc(123, "text", "and"  "more")
  7. Uciekające sznurki

    Częstą odmianą są po prostu zapomniane terminatory łańcuchowe:

                                    
    mysql_evil("SELECT * FROM stuffs);
    print "'ok'";
          ⇑

    Tutaj PHP skarży się na dwa dosłowne ciągi znaków bezpośrednio za sobą. Ale prawdziwą przyczyną jest oczywiście niezamknięty poprzedni ciąg.

Zobacz też

mario
źródło
27

Nieoczekiwany T_STRING

T_STRINGjest trochę mylące. Nie odnosi się do cytowanego "string". Oznacza to, że napotkano surowy identyfikator. Może to wahać się od baresłów po resztki CONSTANTlub nazwy funkcji, zapomniane ciągi bez cudzysłowu lub dowolny zwykły tekst.

  1. Błędnie napisane struny

    Ten błąd składniowy występuje jednak najczęściej w przypadku źle napisanych wartości ciągu. Każde nieskalowane i zbłąkane "lub 'cytat utworzy nieprawidłowe wyrażenie:

                                     
     echo "<a href="http://example.com">click here</a>";

    Podświetlanie składni sprawi, że takie błędy będą bardzo oczywiste. Ważne jest, aby pamiętać o używaniu ukośników odwrotnych do unikania \"podwójnych cudzysłowów lub \'pojedynczych cudzysłowów - w zależności od tego, który został użyty jako ciąg znaków .

    • Dla wygody powinieneś preferować pojedyncze pojedyncze cudzysłowy, gdy wypisujesz zwykły HTML z podwójnymi cudzysłowami.
    • Jeśli chcesz interpolować zmienne, użyj ciągów z podwójnym cudzysłowem, ale uważaj na unikanie dosłownych "podwójnych cudzysłowów.
    • Aby uzyskać dłuższy wynik, preferuj wielokrotność echo/ printlinie zamiast ucieczki do środka i na zewnątrz. Jeszcze lepiej zastanów się nad sekcją HEREDOC .

    Innym przykładem jest użycie wpisu PHP w kodzie HTML wygenerowanym za pomocą PHP:

    $text = '<div>some text with <?php echo 'some php entry' ?></div>'

    Dzieje się tak, gdy $textjest duży z wieloma liniami, a programista nie widzi całej wartości zmiennej PHP i skupia się na kawałku kodu zapominając o jego źródle. Przykładem jest tutaj

    Zobacz także Jaka jest różnica między ciągami pojedynczymi i podwójnymi w PHP? .

  2. Niezamknięte sznurki

    Jeśli przegapisz zamknięcie," błąd składniowy zwykle pojawia się później. Ciąg niezakończony często zużywa trochę kodu, aż do następnej zamierzonej wartości ciągu:

                                                           
    echo "Some text", $a_variable, "and some runaway string ;
    success("finished");
             ⇯

    T_STRINGParser może wówczas protestować nie tylko dosłownie . Inną częstą odmianą jest Unexpected '>'niecytowany dosłowny HTML.

  3. Nieprogramowe ciągi znaków

    Jeśli skopiujesz i wkleisz kod z bloga lub strony internetowej, czasami kończy się to błędnym kodem. Cytaty typograficzne nie są tym, czego oczekuje PHP:

    $text = Something something..’ + these ain't quotes”;

    Cytaty typograficzne / inteligentne są symbolami Unicode. PHP traktuje je jako część sąsiedniego tekstu alfanumerycznego. Na przykład ”thesejest interpretowany jako stały identyfikator. Ale każdy kolejny literał tekstu jest następnie postrzegany przez parser jako słowo puste / T_STRING.

  4. Brakujący średnik; jeszcze raz

    Jeśli w poprzednich wierszach znajduje się nieokreślone wyrażenie, wówczas każda następująca instrukcja lub konstrukcja języka jest postrzegana jako surowy identyfikator:

           
    func1()
    function2();

    PHP po prostu nie może wiedzieć, czy zamierzasz uruchamiać dwie funkcje po kolei, czy chcesz pomnożyć ich wyniki, dodać je, porównać, czy tylko uruchomić jedną ||lub drugą.

  5. Krótkie otwarte tagi i <?xml nagłówki w skryptach PHP

    To raczej rzadkie. Ale jeśli włączone są short_open_tags, nie można rozpocząć skryptów PHP od deklaracji XML :

          
    <?xml version="1.0"?>

    PHP to zobaczy <?i odzyska dla siebie. Nie zrozumie, do czego xmlprzeznaczona była błąka. Będzie interpretowany jako stały. Ale versionbędzie to postrzegane jako kolejna dosłowność / stała. A ponieważ analizator składni nie może zrozumieć dwóch kolejnych literałów / wartości bez operatora wyrażenia pomiędzy nimi, będzie to błąd analizatora składni.

  6. Niewidoczne znaki Unicode

    Najbardziej ohydną przyczyną błędów składniowych są symbole Unicode, takie jak spacja nierozdzielająca . PHP dopuszcza znaki Unicode jako nazwy identyfikatorów. Jeśli otrzymasz skargę analizatora składni T_STRING dotyczącą całkowicie nie podejrzanego kodu, takiego jak:

    <?php
        print 123;

    Musisz przełamać inny edytor tekstu. Lub nawet heksitor. To, co wygląda tutaj na spacje i znaki nowej linii, może zawierać niewidoczne stałe. IDE oparte na Javie są czasem nieświadome, że BOM UTF-8 jest zniekształcone, spacje o zerowej szerokości, separatory akapitów itp. Spróbuj ponownie wszystko, usuń białe spacje i dodaj z powrotem normalne spacje.

    Możesz to zawęzić, dodając zbędne ;separatory instrukcji na początku każdej linii:

    <?php
        ;print 123;

    Dodatkowy ;średnik przekształci poprzedni niewidoczny znak w niezdefiniowane stałe odwołanie (wyrażenie jako instrukcja). Co w zamian powoduje, że PHP wydaje pomocne informacje.

  7. Brak znaku $ przed nazwami zmiennych

    Zmienne w PHP są reprezentowane przez znak dolara, po którym następuje nazwa zmiennej.

    Znak dolara ( $) jest znakiem, który oznacza identyfikator jako nazwę zmiennej. Bez tego znaku identyfikatorem może być słowo kluczowe języka lub stała .

    Jest to częsty błąd, gdy kod PHP został „przetłumaczony” z kodu napisanego w innym języku (C, Java, JavaScript itp.). W takich przypadkach deklaracja typu zmiennej (gdy oryginalny kod został napisany w języku używającym zmiennych typowanych) może również wymknąć się i spowodować ten błąd.

  8. Znaki cudzysłowu

    Jeśli używasz \ciągu, ma to specjalne znaczenie. Nazywa się to „ znakiem ucieczki ” i zwykle mówi parserowi, aby dosłownie wziął następną postać.

    Przykład: echo 'Jim said \'Hello\'';wydrukujeJim said 'hello'

    Jeśli unikniesz cytatu zamykającego łańcucha, cytat zamykający zostanie przyjęty dosłownie, a nie zgodnie z przeznaczeniem, tj. Jako cytat do wydrukowania jako część łańcucha, a nie zamknięcie łańcucha. Będzie to wyświetlane jako błąd analizy często po otwarciu następnego ciągu lub na końcu skryptu.

    Bardzo częsty błąd przy określaniu ścieżek w systemie Windows: "C:\xampp\htdocs\"jest nieprawidłowy. Trzeba "C:\\xampp\\htdocs\\".

Mario
źródło
18

Niespodziewany (

Nawiasy otwierające zwykle podążają za konstrukcjami języka, takimi jak if/ foreach/ for/ array/ listlub rozpoczynają wyrażenie arytmetyczne. Są niepoprawne pod względem składniowym po "strings"poprzednim (), samotnym $i w niektórych typowych kontekstach deklaracji.

  1. Parametry deklaracji funkcji

    Rzadsze występowanie tego błędu polega na próbie użycia wyrażeń jako domyślnych parametrów funkcji . To nie jest obsługiwane, nawet w PHP7:

    function header_fallback($value, $expires = time() + 90000) {

    Parametry w deklaracji funkcji mogą być tylko wartościami literalnymi lub wyrażeniami stałymi. W przeciwieństwie do wywołań funkcji, z których można swobodnie korzystać whatever(1+something()*2)itp.

  2. Wartości domyślne właściwości klasy

    To samo dotyczy deklaracji członków klasy , w których dozwolone są tylko wartości literalne / stałe, a nie wyrażenia:

    class xyz {                   
        var $default = get_config("xyz_default");

    Umieść takie rzeczy w konstruktorze. Zobacz także Dlaczego atrybuty PHP nie pozwalają na funkcje?

    Jeszcze raz zauważ, że PHP 7 dopuszcza var $xy = 1 + 2 +3;tam tylko stałe wyrażenia.

  3. Składnia JavaScript w PHP

    Użycie JavaScript lub składni jQuery nie będzie działać w PHP z oczywistych powodów:

    <?php      
        print $(document).text();

    Kiedy tak się dzieje, zwykle oznacza niezakończony ciąg poprzedzający; i dosłowne <script>sekcje przeciekające do kontekstu kodu PHP.

  4. isset (()), pusty, klucz, następny, bieżący

    Zarówno isset()i empty()są język Zabudowy, a nie funkcje. Muszą uzyskać bezpośredni dostęp do zmiennej . Jeśli przypadkowo dodasz za dużo nawiasów, możesz utworzyć wyrażenie:

              
    if (isset(($_GET["id"]))) {

    To samo dotyczy dowolnej konstrukcji języka, która wymaga niejawnego dostępu do nazwy zmiennej. Te wbudowane elementy są częścią gramatyki języka, dlatego nie pozwalają na dodatkowe nawiasy dekoracyjne.

    Funkcje na poziomie użytkownika, które wymagają odwołania do zmiennej - ale otrzymują przekazany wynik wyrażenia - zamiast tego prowadzą do błędów w czasie wykonywania.


Niespodziewany )

  1. Brak parametru funkcji

    Nie można wstawiać przecinków jako ostatniego w wywołaniu funkcji . PHP oczekuje tam wartości i narzeka na wczesne zamykanie )nawiasów.

                  
    callfunc(1, 2, );

    Przecinek końcowy jest dozwolony tylko w array()lub list()konstruuje.

  2. Niedokończone wyrażenia

    Jeśli zapomnisz coś w wyrażeniu arytmetycznym, wówczas parser się poddaje. Ponieważ jak należy to interpretować:

                   
    $var = 2 * (1 + );

    A jeśli nawet zapomnisz o zamknięciu ), otrzymasz skargę na nieoczekiwany średnik.

  3. Foreach as constant

    W przypadku zapomnianych $prefiksów zmiennych w instrukcjach sterujących zobaczysz:

                           
    foreach ($array as wrong) {

    PHP tutaj czasami mówi, że ::zamiast tego oczekiwał . Ponieważ zmienna class :: $ mogła spełnić oczekiwane wyrażenie zmiennej $.


Niespodziewany {

Nawiasy klamrowe {i }otaczają bloki kodu. A błędy składniowe na ich temat zwykle wskazują na nieprawidłowe zagnieżdżenie.

  1. Niezrównane podwyrażenia w pliku if

    Najczęściej niezrównoważony (i) jest przyczyną, gdy parser narzeka na {zbyt wczesne pojawienie się nawiasu otwierającego . Prosty przykład:

                                  
    if (($x == $y) && (2 == true) {

    Policz nawiasy lub użyj IDE, które Ci w tym pomogą. Nie pisz też kodu bez spacji. Liczy się czytelność.

  2. {i} w kontekście wyrażenia

    W wyrażeniach nie można używać nawiasów klamrowych. Jeśli pomylisz nawiasy i nawiasy, nie będzie to zgodne z gramatyką języka:

               
    $var = 5 * {7 + $x};

    Istnieje kilka wyjątków od konstrukcji identyfikatora, takich jak lokalna zmienna zasięgu ${references}.

  3. Zmienne zmienne lub wyrażenia zmienne kręcone

    To jest dość rzadkie. Ale możesz także otrzymywać {i }analizować skargi dotyczące złożonych wyrażeń zmiennych:

                          
    print "Hello {$world[2{]} !";

    Chociaż istnieje większe prawdopodobieństwo nieoczekiwanego }w takich sytuacjach.


Niespodziewany }

Gdy }pojawia się „nieoczekiwany ” błąd, blok kodu jest zbyt wcześnie zamykany.

  1. Ostatnia instrukcja w bloku kodu

    Może się to zdarzyć dla każdego nieskończonego wyrażenia.

    A jeśli ostatni wiersz w bloku funkcji / kodu nie ma końcowego ;średnika:

    function whatever() {
        doStuff()
    }            

    W tym przypadku analizator składni nie może stwierdzić, czy być może nadal chcesz dodać + 25;wynik funkcji lub coś innego.

  2. Nieprawidłowe zagnieżdżenie bloku / zapomniane {

    Czasami zobaczysz ten błąd analizatora składni, gdy blok kodu został }zamknięty zbyt wcześnie lub zapomniałeś otwarcia {nawet:

    function doStuff() {
        if (true)    
            print "yes";
        }
    }   

    W powyższym fragmencie ifnie miał otwierającego {nawiasu klamrowego. W ten sposób zamykający }poniżej stał się zbędny. I dlatego następne zamknięcie }, które było przeznaczone dla tej funkcji, nie było związane z oryginalnym otwierającym {nawiasami klamrowymi.

    Takie błędy są jeszcze trudniejsze do znalezienia bez odpowiedniego wcięcia kodu. Użyj IDE i dopasowania do nawiasów.


Nieoczekiwany {, oczekiwany(

Konstrukcje językowe wymagające nagłówka warunku / deklaracji i bloku kodu wywołują ten błąd.

  1. Listy parametrów

    Na przykład źle zadeklarowane funkcje bez listy parametrów są niedozwolone:

                     
    function whatever {
    }
  2. Warunki instrukcji kontroli

    I nie możesz również mieć stanu ifbez warunków .

      
    if {
    }

    Co oczywiście nie ma sensu. To samo dotyczy zwykłych podejrzanych, for/ foreach, while/ doitd.

    Jeśli masz ten konkretny błąd, zdecydowanie powinieneś poszukać kilku ręcznych przykładów.

Mario
źródło
1
Szukałem odpowiedzi na moje pytanie w tym poście, ale znalazłem odpowiedź na problem - „Nieoczekiwany {”, dlatego chciałem podzielić się z moją odpowiedzią - dla mnie problemem było kodowanie z podziałem linii - jakoś niektóre z moich pliki używały podziałów linii Macintosha, ale kiedy zmieniłem je na podział wierszy systemu Windows - mój problem (na localhost (WAMP) wszystko działa, ale na linux webserver dont) został rozwiązany.
Edgars Aivars,
@EdgarsAivars Dziękujemy za komentarz! Podziały linii specyficzne dla platformy są w rzeczywistości rzadkim i trudnym problemem. Prawdopodobnie wymienię to również tutaj. (Zostało to właśnie wspomniane na bok w innej odpowiedzi referencyjnej .)
Mario
Odkryłem, że otrzymywanie nieoczekiwanego} było spowodowane tym, że fragment mojego kodu używał krótkiego znacznika php <? zamiast <? php - zajęło mi chwilę znalezienie tego, ponieważ działał on na innych serwerach.
c7borg
14

Nieoczekiwany koniec $

Kiedy PHP mówi o „nieoczekiwanym $end”, oznacza to, że Twój kod zakończył się przedwcześnie. (Komunikat jest nieco mylący, gdy jest interpretowany dosłownie. Nie chodzi o zmienną o nazwie „$ end”, jak czasami przyjmują nowi użytkownicy. Odnosi się do „końca pliku”,. EOF)

Przyczyna: Niezrównoważone {i }dla bloków kodu / i deklaracji funkcji lub klas.

To prawie zawsze o brakującym }nawias klamrowy zamknąć poprzednie bloki kodu.

  • Ponownie użyj odpowiedniego wcięcia, aby uniknąć takich problemów.

  • Użyj IDE z dopasowaniem do nawiasów, aby dowiedzieć się, gdzie }jest błąd. W większości IDE i edytorów tekstowych znajdują się skróty klawiaturowe:

    • NetBeans, PhpStorm, Komodo: Ctrl[iCtrl]
    • Eclipse, Aptana: CtrlShiftP
    • Atom, Sublime: Ctrlm- Zend StudioCtrlM
    • Geany, Notepad ++: CtrlB- Joe: CtrlG- Emacs: C-M-n- Vim:%

Większość IDE podkreśla również pasujące nawiasy klamrowe, nawiasy i nawiasy. Co sprawia, że ​​dość łatwo jest sprawdzić ich korelację:

Dopasowywanie nawiasów w IDE

Wyrażenia nieskończone

A Unexpected $endbłąd składni / parser może również wystąpić do wyrażenia niezakończony lub oświadczeń:

  • $var = func(1, ?>EOF

Najpierw spójrz na koniec skryptów. Trailing ;jest często zbędny dla ostatniej instrukcji w dowolnym skrypcie PHP. Ale powinieneś go mieć. Właśnie dlatego, że zawęża takie problemy ze składnią.

Wcięte markery HEREDOC

Innym częstym zjawiskiem jest łańcuchy HEREDOC lub NOWDOC . Znacznik kończący jest ignorowany w przypadku wiodących spacji, tabulatorów itp .:

print <<< END
    Content...
    Content....
  END;
# ↑ terminator isn't exactly at the line start

Dlatego parser zakłada, że ​​ciąg HEREDOC będzie kontynuowany do końca pliku (stąd „Nieoczekiwany $ end”). Prawie wszystkie środowiska IDE i edytory wyróżniające składnię sprawią, że będzie to oczywiste lub ostrzeżenie o tym.

Znaki cudzysłowu

Jeśli używasz \ciągu, ma to specjalne znaczenie. Nazywa się to „ znakiem ucieczki ” i zwykle mówi parserowi, aby dosłownie wziął następną postać.

Przykład: echo 'Jim said \'Hello\'';wydrukujeJim said 'hello'

Jeśli unikniesz cytatu zamykającego łańcucha, cytat zamykający zostanie przyjęty dosłownie, a nie zgodnie z przeznaczeniem, tj. Jako cytat do wydrukowania jako część łańcucha, a nie zamknięcie łańcucha. Będzie to wyświetlane jako błąd analizy często po otwarciu następnego ciągu lub na końcu skryptu.

Bardzo częsty błąd przy określaniu ścieżek w systemie Windows: "C:\xampp\htdocs\"jest nieprawidłowy. Trzeba "C:\\xampp\\htdocs\\".

Alternatywna składnia

Nieco rzadziej można zobaczyć ten błąd składniowy podczas korzystania z alternatywnej składni bloków instrukcji / kodu w szablonach. Używanie if:i else:brakujące endif;na przykład.

Zobacz też:

Mario
źródło
14

Nieoczekiwany T_IF
Nieoczekiwany T_ELSEIF
Nieoczekiwany T_ELSE
Nieoczekiwany T_ENDIF

Warunkowe bloki sterujące if, elseifi elsewykonaj prostą strukturę. Gdy napotkasz błąd składniowy, najprawdopodobniej jest to po prostu nieprawidłowe zagnieżdżanie bloku → z brakującymi {nawiasami klamrowymi }- lub o jeden za dużo.

wprowadź opis zdjęcia tutaj

  1. Brak {lub z }powodu nieprawidłowego wcięcia

    Niedopasowane nawiasy klamrowe są wspólne dla gorzej sformatowanego kodu, takiego jak:

    if((!($opt["uniQartz5.8"]!=$this->check58)) or (empty($_POST['poree']))) {if
    ($true) {echo"halp";} elseif((!$z)or%b){excSmthng(False,5.8)}elseif (False){

    Jeśli Twój kod wygląda tak, zacznij od nowa! W przeciwnym razie będzie to niemożliwe do naprawienia dla ciebie lub kogokolwiek innego. Nie ma sensu pokazywać tego w Internecie, aby poprosić o pomoc.

    Będziesz w stanie to naprawić tylko wtedy, gdy będziesz mógł wizualnie śledzić zagnieżdżoną strukturę i relację warunków warunkowych if / else i ich {bloków kodu }. Użyj swojego IDE, aby sprawdzić, czy wszystkie są sparowane.

    if (true) {
         if (false) {
                  
         }
         elseif ($whatever) {
             if ($something2) {
                 
             } 
             else {
                 
             }
         }
         else {
             
         }
         if (false) {    //   a second `if` tree
             
         }
         else {
             
         }
    }
    elseif (false) {
        
    }

    Każde podwójne } }zamknie nie tylko gałąź, ale poprzednią strukturę warunków. Dlatego trzymaj się jednego stylu kodowania; nie mieszaj i nie dopasowuj zagnieżdżonych drzew if / else.

    Oprócz spójności okazuje się, że pomocne jest również uniknięcie długich warunków. Użyj zmiennych tymczasowych lub funkcji, aby uniknąć nieczytelnych if-wyrażeń.

  2. IF nie można używać w wyrażeniach

    Zaskakująco częstym błędem nowicjusza jest próba użycia ifinstrukcji w wyrażeniu, na przykład instrukcji print:

                       
    echo "<a href='" . if ($link == "example.org") { echo 

    Co oczywiście jest nieważne.

    Możesz użyć trójkowego warunkowego , ale uważaj na wpływ na czytelność.

    echo "<a href='" . ($link ? "http://yes" : "http://no") . "</a>";

    W przeciwnym razie przerwij takie konstrukcje wyjściowe: użyj wielu ifs i echos .
    Jeszcze lepiej, użyj zmiennych tymczasowych i umieść swoje warunkowe przed:

    if ($link) { $href = "yes"; } else { $href = "no"; }
    echo "<a href='$href'>Link</a>";

    Zdefiniowanie funkcji lub metod dla takich przypadków również często ma sens.

    Bloki kontrolne nie zwracają „wyników”

    Teraz jest to mniej powszechne, ale kilku programistów próbuje nawet traktować iftak, jakby mogło zwrócić wynik :

    $var = if ($x == $y) { "true" };

    Który jest strukturalnie identyczny z użyciem ifw obrębie ciągu konkatenacji / wyrażenia.

    • Ale struktury kontrolne (jeśli / foreach / while) nie mają „rezultatu” .
    • Dosłowny ciąg „true” również byłby tylko nieważnym stwierdzeniem.

    Musisz użyć przypisania w bloku kodu :

    if ($x == $y) { $var = "true"; }

    Alternatywnie skorzystaj z ?:trójskładnikowego porównania.

    If in If

    Nie można zagnieżdżaćif warunku:

                        
    if ($x == true and (if $y != false)) { ... }

    Co jest oczywiście zbędne, ponieważ and(lub or) już umożliwia porównywanie łańcuchowe.

  3. Zapomniane ;średniki

    Jeszcze raz: każdy blok kontrolny musi być instrukcją. Jeśli poprzedni fragment kodu nie jest zakończony średnikiem, to jest to gwarantowany błąd składniowy:

                    
    $var = 1 + 2 + 3
    if (true) {  }

    Przy okazji, ostatni wiersz w {…}bloku kodu również potrzebuje średnika.

  4. Średnik za wcześnie

    Prawdopodobnie błędem jest obwinianie określonego stylu kodowania, ponieważ pułapkę tę zbyt łatwo przeoczyć:

                
    if ($x == 5);
    {
        $y = 7;
    }
    else           
    {
        $x = -1;    
    }

    Co dzieje się częściej, niż można sobie wyobrazić.

    • Po zakończeniu if ()wyrażenia za; jego pomocą zostanie wykonana instrukcja void. ;Staje się pusta {}sama w sobie!
    • {…}Ten sposób blok zostaje odłączony od if, i zawsze uruchamiane.
    • Więc elsenie ma już związku z otwartą ifkonstrukcją, dlatego doprowadziłoby to do nieoczekiwanego błędu składniowego T_ELSE.

    Co również wyjaśnia podobnie subtelną odmianę tego błędu składniowego:

    if ($x) { x_is_true(); }; else { something_else(); };

    Gdzie ;po bloku kodu {…}kończy się cały if konstrukt, elseskładnia gałęzi składniowo.

  5. Nie używa bloków kodu

    Składniowo dozwolone jest pomijanie nawiasów klamrowych {}dla bloków kodu w if/ elseif/ elseoddziałach. Który niestety jest stylem składni bardzo powszechnym dla niewersjonowanych koderów. (Przy fałszywym założeniu pisanie lub czytanie było szybsze).

    Jest jednak bardzo prawdopodobne, że spowoduje to przekroczenie składni. Wcześniej czy później dodatkowe instrukcje znajdą się w gałęziach if / else:

    if (true)
        $x = 5;
    elseif (false)
        $x = 6;
        $y = 7;     
    else
        $z = 0;

    Ale faktycznie korzysta bloki kodu, ty masz napisać {... }je jako takie!

    Nawet doświadczeni programiści unikają składni bez ramienia lub przynajmniej rozumieją to jako wyjątek od reguły.

  6. Else / Elseif w złej kolejności

    Oczywiście jedną rzeczą do przypomnienia jest porządek warunkowy .

    if ($a) {  }
    else {  }
    elseif ($b) {  }
    

    Możesz mieć tyle elseifs, ile chcesz, ale musisz elseiść ostatni . Tak to jest.

  7. Deklaracje klasowe

    Jak wspomniano powyżej , nie można mieć instrukcji sterujących w deklaracji klasy:

    class xyz {
        if (true) {
            function ($var) {}
        }

    W takich przypadkach albo zapomniałeś definicji funkcji , albo }zbyt wcześnie ją zamknąłeś .

  8. Nieoczekiwany T_ELSEIF / T_ELSE

    Podczas mieszania PHP i HTML zamykanie }dla if/elseifmusi być w tym samym bloku PHP, <?php ?>co następny elseif/else. To wygeneruje błąd jak zamknięcie }na te ifpotrzeby, aby być częścią elseif:

    <?php if ($x) { ?>
        html
    <?php } ?>
    <?php elseif ($y) { ?>
        html
    <?php } ?>

    Prawidłowa forma <?php } elseif:

    <?php if ($x) { ?>
        html
    <?php } elseif ($y) { ?>
        html
    <?php } ?>

    Jest to mniej więcej odmiana nieprawidłowego wcięcia - przypuszczalnie często oparta na złych intencjach kodowania.
    Nie można zacierać innych instrukcji między tokenami ifi elseif/ / elsetokenami strukturalnymi:

    if (true) {
    }
    echo "in between";    
    elseif (false) {
    }
    ?> text <?php      
    else {
    }

    Albo może wystąpić tylko w {…}blokach kodu, a nie między tokenami struktury kontroli.

    • To i tak nie miałoby sensu. To nie jest tak, że był jakiś „niezdefiniowany” stan, kiedy PHP przeskakuje między ifi elsegałęziami.
    • Musisz zdecydować, gdzie należy wydrukować wyciągi / lub czy trzeba je powtórzyć w obu gałęziach.

    Nie możesz także rozdzielić if / else pomiędzy różne struktury kontrolne:

    foreach ($array as $i) {
        if ($i) {  }
    }
    else {  }

    Nie ma związku składniowego między ifi else. Zakres foreachleksykalny kończy się na }, więc ifkontynuacja struktury nie ma sensu .

  9. T_ENDIF

    Jeśli skarży się na nieoczekiwany T_ENDIF, używasz alternatywnego stylu składni if:elseif:else:endif;. O czym powinieneś pomyśleć dwa razy.

    • Częstą pułapką jest mylenie niesamowicie podobnego :jelita grubego dla ;średnika . (Objęte „Wczesnym średnikiem”)

    • Ponieważ wcięcie jest trudniejsze do śledzenia w plikach szablonów, tym bardziej, gdy używasz alternatywnej składni - jest prawdopodobne, endif;że nie pasuje żaden if:.

    • Użycie } endif; jest podwójnym if terminatorem.

    Podczas gdy „nieoczekiwany koniec $” jest zwykle ceną za zapomniane zamknięcie }klamry.

  10. Przypisanie a porównanie

    Nie jest to więc błąd składniowy, ale warto wspomnieć w tym kontekście:

           
    if ($x = true) { }
    else { do_false(); }

    To nie jest porównanie ==/ ===, ale =zadanie . Jest to dość subtelne i z łatwością poprowadzi niektórych użytkowników do bezradnej edycji całych bloków warunków. Najpierw uważaj na niezamierzone zadania - zawsze, gdy napotkasz błąd logiczny / złe zachowanie.

mario
źródło
11

Nieoczekiwany T_IS_EQUAL
Nieoczekiwany T_IS_GREATER_OR_EQUAL
Nieoczekiwany T_IS_IDENTICAL
Nieoczekiwany T_IS_NOT_EQUAL
Nieoczekiwany T_IS_NOT_IDENTICAL
Nieoczekiwany T_IS_SMALLER_OR_EQUAL
Nieoczekiwany <
Nieoczekiwany>

Operatory porównania, takie jak ==, >=, ===, !=, <>, !==i <=czy <, a >przede wszystkim powinny być używane tylko w wyrażeniach takich jak ifwyrażeń. Jeśli parser narzeka na nie, często oznacza to nieprawidłowe parowanie lub niedopasowane ( )pareny wokół nich.

  1. Grupowanie Parens

    W szczególności w przypadku ifstwierdzeń z wieloma porównaniami należy uważać, aby poprawnie policzyć nawias otwierający i zamykający :

                            
    if (($foo < 7) && $bar) > 5 || $baz < 9) { ... }
                          

    Tutaj ifwarunek tutaj został już zakończony przez)

    Gdy porównania stają się wystarczająco złożone, często pomaga podzielić je na wiele i zagnieżdżone ifkonstrukcje.

  2. isset () mieszane z porównywaniem

    Częstym nowicjuszem jest to, że pitfal próbuje łączyć isset()lub empty()porównywać:

                            
    if (empty($_POST["var"] == 1)) {

    Lub nawet:

                        
    if (isset($variable !== "value")) {

    To nie ma sensu PHP, bo isseti emptysą konstrukcje językowe, które akceptują tylko nazwy zmiennych. Nie ma sensu porównywanie wyników, ponieważ wynik jest tylko / już wartością logiczną.

  3. Mylące >=większe lub równe z =>operatorem tablicy

    Obaj operatorzy wyglądają nieco podobnie, więc czasami się mylą:

             
    if ($var => 5) { ... }

    Trzeba tylko pamiętać, że ten operator porównania nazywa się „ większy lub równy ”, aby uzyskać właściwy wynik.

    Zobacz także: Struktura instrukcji If w PHP

  4. Nic do porównania

    Nie można także łączyć dwóch porównań, jeśli dotyczą one tej samej nazwy zmiennej:

                     
    if ($xyz > 5 and < 100)

    PHP nie może wywnioskować, że chciałeś ponownie porównać zmienną początkową. Wyrażenia są zwykle parowane zgodnie z pierwszeństwem operatora , więc do czasu ich <wyświetlenia pozostanie tylko wynik boolowski z oryginalnej zmiennej.

    Zobacz także: nieoczekiwany T_IS_SMALLER_OR_EQUAL

  5. Łańcuchy porównawcze

    Nie można porównywać ze zmienną z rzędem operatorów:

                      
     $reult = (5 < $x < 10);

    Trzeba to podzielić na dwa porównania, każde przeciw $x.

    W rzeczywistości jest to bardziej przypadek wyrażeń z czarnej listy (ze względu na równoważne powiązanie operatora). Jest poprawny pod względem składniowym w kilku językach w stylu C, ale PHP również nie interpretowałby tego jako oczekiwany łańcuch porównania.

  6. Nieoczekiwany >
    Nieoczekiwany<

    Większe >lub mniejsze niż <operatory nie mają niestandardowej T_XXXnazwy tokenizera. I chociaż można je zgubić jak wszystkie inne, częściej parser narzeka na nie za błędnie napisane ciągi i maskowany HTML:

                            
    print "<a href='z">Hello</a>";
                     ↑

    Sprowadza się to "<a href='z"do porównania łańcucha >ze stałą literalną, Helloa następnie do kolejnego <porównania. A przynajmniej tak to widzi PHP. Rzeczywistą przyczyną i błędem składni było przedwczesne "zakończenie łańcucha .

    Nie można również zagnieżdżać znaczników startowych PHP:

    <?php echo <?php my_func(); ?>

Zobacz też:

mario
źródło
11

Nieoczekiwany T_IF
Nieoczekiwany T_FOREACH
Nieoczekiwany T_FOR
Nieoczekiwany T_WHILE
Nieoczekiwany T_DO
Nieoczekiwany T_ECHO

Kontrola konstruuje takie jak if, foreach, for, while, list, global, return, do, print, echomogą być stosowane tylko jako stwierdzeń. Zwykle same przebywają na linii.

  1. Średnik; gdzie jesteś?

    Całkiem ogólnie rzecz biorąc, czy pominąłeś średnik w poprzedniej linii, jeśli parser skarży się na instrukcję sterującą:

                 
    $x = myfunc()
    if (true) {

    Rozwiązanie: spójrz na poprzednią linię; dodaj średnik.

  2. Deklaracje klasowe

    Innym miejscem, w którym ma to miejsce, są deklaracje klas . W sekcji klasy można wyświetlić tylko listę inicjalizacji właściwości i sekcji metod. Nie może tam znajdować się żaden kod.

    class xyz {
        if (true) {}
        foreach ($var) {}

    Takie błędy składniowe często pojawiają się w przypadku nieprawidłowo zagnieżdżonych {i }. W szczególności, gdy bloki kodu funkcji zostały zamknięte zbyt wcześnie.

  3. Instrukcje w kontekście wyrażeń

    Większość konstrukcji językowych można używać tylko jako instrukcji . Nie należy ich umieszczać w innych wyrażeniach:

                       
    $var = array(1, 2, foreach($else as $_), 5, 6);

    Podobnie nie możesz używać ifw ciągach znaków, wyrażeniach matematycznych ani gdzie indziej:

                   
    print "Oh, " . if (true) { "you!" } . " won't work";
    // Use a ternary condition here instead, when versed enough.

    W przypadku ifwarunków osadzania w konkretnym wyrażeniu często chcesz użyć ?:oceny trójskładnikowej .

    To samo dotyczy for, while, global, echooraz w mniejszym stopniu list.

              
    echo 123, echo 567, "huh?";

    Natomiast print()jest językiem wbudowanym, który może być używany w kontekście wyrażeń. (Ale rzadko ma to sens).

  4. Zastrzeżone słowa kluczowe jako identyfikatory

    Nie można także używać konstruktorów języka doani ifinnych języków dla funkcji zdefiniowanych przez użytkownika ani nazw klas. (Być może w PHP 7. Ale nawet wtedy nie byłoby wskazane.)

Mario
źródło
7

Niespodziewany '?'

Jeśli próbujesz użyć zerowego operatora koalescencyjnego ??w wersji PHP wcześniejszej niż PHP 7, pojawi się ten błąd.

<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP

Nieoczekiwany „?”, Oczekiwanie zmiennej

Podobny błąd może wystąpić w przypadku typów zerowalnych, jak w:

function add(?int $sum): ?int {

Co ponownie oznacza, że ​​używana jest nieaktualna wersja PHP (wersja CLI php -vlub wersja związana z serwerem WWW phpinfo();).

John Conde
źródło
5

Nieoczekiwany T_LNUMBER

Token T_LNUMBERodnosi się do „długiego” / numeru.

  1. Niepoprawne nazwy zmiennych

    W PHP i większości innych języków programowania zmienne nie mogą zaczynać się od liczby. Pierwszy znak musi być alfabetyczny lub podkreślić.

    $1   // Bad
    $_1  // Good

    *

    • Dość często pojawia się użycie preg_replace-placeholder "$1"w kontekście PHP:

      #                         ↓            ⇓  ↓
      preg_replace("/#(\w+)/e",  strtopupper($1) )

      Gdzie należy oddzwonić. (Teraz /eflaga wyrażeń regularnych jest przestarzała. Ale czasami jest nadal niewłaściwie używana w preg_replace_callbackfunkcjach.)

    • To samo ograniczenie identyfikatora dotyczy właściwości obiektu , btw.

             
      $json->0->value
    • Podczas gdy tokenizer / parser nie dopuszcza literału $1jako nazwy zmiennej, można użyć ${1}lub ${"1"}. Który jest obejściem składniowym dla niestandardowych identyfikatorów. (Najlepiej myśleć o tym jak o wyszukiwaniu lokalnego zasięgu. Ale ogólnie: w takich przypadkach preferuj zwykłe tablice!)

    • Zabawnie, ale bardzo niezalecany, parser PHPs pozwala na identyfikatory Unicode; takie, które $➊byłyby ważne. (W przeciwieństwie do literału 1).

  2. Wpis tablicy bezpańskiej

    W przypadku deklaracji tablicowych może wystąpić również nieoczekiwany długi czas - w przypadku braku ,przecinków:

    #            ↓ ↓
    $xy = array(1 2 3);

    Lub podobnie wywołania funkcji i deklaracje oraz inne konstrukcje:

    • func(1, 2 3);
    • function xy($z 2);
    • for ($i=2 3<$z)

    Tak więc zwykle jest jedna z ;lub ,brakująca do oddzielenia list lub wyrażeń.

  3. Błędnie cytowany HTML

    I znowu źle napisane ciągi są częstym źródłem pomyłek:

    #                 ↓ ↓          
    echo "<td colspan="3">something bad</td>";

    Takie przypadki należy traktować mniej więcej tak, jak Nieoczekiwane błędy T_STRING .

  4. Inne identyfikatory

    Ani funkcji, klas, ani przestrzeni nazw nie można nazwać zaczynając od liczby:

             
    function 123shop() {

    Prawie tak samo jak w przypadku nazw zmiennych.

Mario
źródło
2

Nieoczekiwany „=”

Może to być spowodowane niepoprawnymi znakami w nazwie zmiennej. Nazwy zmiennych muszą być zgodne z następującymi regułami:

Nazwy zmiennych podlegają tym samym regułom, co inne etykiety w PHP. Prawidłowa nazwa zmiennej zaczyna się od litery lub znaku podkreślenia, po którym następuje dowolna liczba liter, cyfr lub znaków podkreślenia. Jako wyrażenie regularne byłoby to wyrażone następująco: „[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0-9_ \ x7f- \ xff] * '

John Conde
źródło
Dobry dodatek John.
Funk Forty Niner,
1

Nieoczekiwany „kontynuuj” (T_CONTINUE)

continuejest instrukcją (jak dla lub jeśli) i musi wyglądać na samodzielną. Nie można go używać jako części wyrażenia. Częściowo dlatego, że kontynuacja nie zwraca wartości, ale w wyrażeniu każde podwyrażenie musi dawać pewną wartość, więc ogólne wyrażenie skutkuje wartością. Na tym polega różnica między wyrażeniem a wyrażeniem.

Oznacza to, że continuenie można go użyć w trójkowej instrukcji ani w żadnej instrukcji wymagającej wartości zwracanej.

Nieoczekiwana „przerwa” (T_BREAK)

To samo dotyczy break;oczywiście. Nie jest to również użyteczne w kontekście wyrażeń, ale ścisłe stwierdzenie (na tym samym poziomie co foreachlub ifbloku).

Nieoczekiwany „powrót” (T_RETURN)

Teraz może to być bardziej zaskakujące return, ale jest to również instrukcja blokowa . Zwraca wartość (lub NULL) do wyższego zakresu / funkcji, ale nie ocenia się jako samo wyrażenie. → To znaczy: nie ma sensu tego robićreturn(return(false);;

Mario
źródło
1

Niespodziewany '.'

Może się to zdarzyć, jeśli próbujesz użyć operatora splat ( ...) w nieobsługiwanej wersji PHP.

... po raz pierwszy stał się dostępny w PHP 5.6 do przechwytywania zmiennej liczby argumentów dla funkcji:

function concatenate($transform, ...$strings) {
    $string = '';
    foreach($strings as $piece) {
        $string .= $piece;
    }
    return($transform($string));
}

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");
// This would print:
// I'D LIKE 6 APPLES

W PHP 7.4 możesz użyć go do wyrażeń Array .

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
John Conde
źródło
0

Nieoczekiwany „koniec” (T_ENDWHILE)

Składnia używa dwukropka - jeśli nie ma dwukropka, wystąpi powyższy błąd.

<?php while($query->fetch()): ?>
 ....
<?php endwhile; ?>

Alternatywą dla tej składni jest użycie nawiasów klamrowych:

<?php while($query->fetch()) { ?>
  ....
<?php } ?>

http://php.net/manual/en/control-structures.while.php

mplungjan
źródło
0

Komunikat o błędzie, który się zaczyna, Parse error: syntax error, unexpected ':'może być spowodowany błędnym zapisaniem statycznego odwołania klasy Class::$Variablejako Class:$Variable.

David Spector
źródło