Dlaczego ktoś miałby pominąć tag close?

I Continue reading it is poor practice to use the PHP close tag ?> at the end of the file. Problem z nagłówkiem wydaje się nieistotny w następującym kontekście (i jest to jedyny dobry argument do tej pory):

Współczesne wersje PHP ustawiają flagę output_buffering w php.ini Jeśli bufor wyjściowy jest włączony, możesz ustawić nagłówki HTTP i pliki cookie po wysłaniu html, ponieważ zwrócony kod nie jest natychmiast wysyłany do przeglądarki.

Every good practice book and wiki zaczyna się od tej "zasady", ale nikt nie daje dobrych powodów. czy jest inny dobry powód, aby pominąć kończący się tag php?

Author: Paracetamol, 2010-12-10

14 answers

Chociaż nie pamiętam żadnego innego powodu, wysyłanie nagłówków wcześniej niż normalnie może mieć daleko idące konsekwencje. Poniżej kilka z nich, które akurat w tej chwili przyszły mi do głowy:

  1. Podczas gdy obecne wydania PHP mogą mieć włączone buforowanie wyjściowe, rzeczywiste serwery produkcyjne , na których będziesz wdrażał swój kod, są o wiele ważniejsze niż jakiekolwiek maszyny programistyczne lub testujące. I nie zawsze podążają za najnowszymi trendami PHP natychmiast.

  2. Możesz mieć bóle głowy z powodu niewytłumaczalnego utraty funkcjonalności . Powiedzmy, że wdrażasz jakąś bramę płatności i przekierowujesz użytkownika do określonego adresu URL po pomyślnym potwierdzeniu przez procesor płatności. Jeśli wystąpi jakiś błąd PHP, nawet ostrzeżenie lub przekroczenie linii, płatność może pozostać nieprzetworzona, a użytkownik może nadal wydawać się nieobciążony. Jest to również jeden z powodów, dla których niepotrzebne przekierowanie jest złe i jeśli przekierowanie ma być używane, należy go stosować ostrożnie.

  3. W przeglądarce Internet Explorer mogą pojawić się błędy typu "anulowane ładowanie strony", nawet w najnowszych wersjach. Dzieje się tak dlatego, że AJAX response/JSON include zawiera coś, czego nie powinien zawierać, z powodu nadmiaru zakończeń linii w niektórych plikach PHP, tak jak spotkałem się kilka dni temu.

  4. Jeśli masz jakieś pliki do pobrania w swojej aplikacji, mogą one również się zepsuć, z tego powodu. I możesz tego nie zauważyć, nawet po latach, ponieważ specyficzny nawyk łamania pobierania zależy od serwera, przeglądarki, rodzaju i zawartości pliku (i ewentualnie kilku innych czynników, którymi nie chcę cię zanudzać).

  5. Wreszcie, wiele frameworków PHP w tym Symfony, Zend i Laravel (nie ma o tym wzmianki w coding guidelines, ale jest to zgodne z kombinezonem) i PSR-2 standard (pozycja 2.2) wymagają pominięcia znacznika zamykającego. Instrukcja PHP itself (1,2), Wordpress, Drupal i wiele innych programów PHP, jak sądzę, radzę to zrobić. Jeśli po prostu nabierasz zwyczaju podążania za standardem (i konfiguracją PHP-CS-Fixer dla swojego kodu) możesz zapomnieć o problemie. W przeciwnym razie zawsze będziesz musiał zachować problem w swoim umyśle.

Bonus: kilka gotchów (aktualnie jeden) związanych z tymi 2 postaciami:

  1. nawet niektóre dobrze znane biblioteki mogą zawierać nadmiar linii zakończenia po ?>. Przykładem jest Smarty, nawet najnowsze wersje obu 2.* i 3./ align = "left" / Więc, jak zawsze, uważaj na kod stron trzecich . Bonus w bonus: Wyrażenie regularne do usuwania niepotrzebnych zakończeń PHP: zastąp (\s*\?>\s*)$ pustym tekstem we wszystkich plikach zawierających kod PHP.
 290
Author: Halil Özgür,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-10 12:17:55

Powodem, dla którego powinieneś zostawić znacznik zamykający php (?>) jest to, że programista nie wysyła przypadkowo dodatkowych znaków nowej linii.

Powodem, dla którego nie powinieneś opuszczać znacznika zamykającego php jest to, że powoduje on nierównowagę w znacznikach php i każdy programista z pół umysłem może pamiętać, aby nie dodawać dodatkowych białych spacji.

Więc dla Twojego pytania:

Czy jest inny dobry powód, aby pominąć kończący się tag php?

Nie, Nie ma innego dobry powód, aby pominąć kończące się tagi php.

Skończę z kilkoma argumentami za nie zawracaniem sobie głowy tagiem zamykającym:

  1. Ludzie są zawsze w stanie popełnić błędy, bez względu na to, jak mądrzy są. Przestrzeganie praktyki, która zmniejsza liczbę możliwych błędów jest (IMHO) dobrym pomysłem.

  2. PHP to nie XML. PHP nie musi przestrzegać ścisłych standardów XMLs, aby być dobrze napisane i funkcjonalne. Jeśli brakujący znacznik zamykający Cię denerwuje, możesz użyć zamykanie znacznika, to nie jest zasada ustawiona w kamieniu w ten czy inny sposób.

 112
Author: zzzzBov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-15 19:09:41

Jest to rekomendacja stylu kodowania dla początkujących , z dobrymi intencjami i doradzana przez instrukcję .

  • Eschewing ?> rozwiązuje jednak tylko ściek wspólnego nagłówków już wysłanych causes (raw output, BOM, notices, itp.) i ich następczych problemów.

  • PHP faktycznie zawiera magię, która pożera pojedyncze przerwy po tokenie zamykającym ?>. Choć to ma problemy historyczne i pozostawia nowo przybyłych wciąż podatnych na łuszczące się Edytory i nieświadomie tasujące inne białe spacje po ?>.

  • Stylistycznie niektórzy programiści wolą wyświetlać <?php i ?> jako instrukcje przetwarzania znaczników SGML / XML, sugerując spójność balansu końcowego tokena zamknięcia. (Które btw, jest użyteczne dla klasy conjoining, która obejmuje zastąpienie nieefektywnego autoloadowania plików po plikach.)

  • Nieco nietypowo Otwarcie <?php jest charakteryzuje się jako PHPs shebang (i w pełni wykonalne dla binfmt_misc), potwierdzając tym samym redundancję odpowiadającego znacznika close.

  • Istnieje oczywista rozbieżność pomiędzy klasycznymi podręcznikami składni PHP i bardziej ostatnimi (PSR-2) zgadzającymi się na pominięcie.
    (Dla przypomnienia: Zend Framework postulowanie jednego nad drugim nie oznacza jego wrodzonej wyższości. To błędne przekonanie, że eksperci byli rysowane do / grupy docelowej nieporęcznych interfejsów API).

  • SCMs i nowoczesne IDE zapewniają wbudowane rozwiązania głównie łagodzące bliską opiekę tagów.

Zniechęcanie do używania znacznika ?> close jedynie opóźnia wyjaśnienie podstawowych zachowań przetwarzania PHP i semantyki języka, aby uniknąć rzadkich problemów. To jest praktyczny nadal do współpracy rozwoju oprogramowania ze względu na różnice biegłości w uczestnikach.

Zamknij odmiany znaczników

  • Regular ?> close tag jest również znany jako T_CLOSE_TAG, lub w ten sposób "Zamknij token".

  • [[25]} składa się z kilku kolejnych wcieleń, z powodu magii PHPs newline eating:

    ?>\n (Unix linefeed)

    ?>\r (powóz return, klasyczny MACs)

    ?>\r\n (CR/ LF, na DOS/Win)

    PHP nie obsługuje linebreak combo UnicodeNEL (U + 0085).

    Wczesne wersje PHP miały Kompilacje IIRC ograniczające nieco platformę-agnostycyzm (FI nawet używało > jako znacznika Bliskiego), co jest prawdopodobnym historycznym źródłem unikania znaczników bliskich.

  • Często pomijane, ale do PHP7 usuwa je , zwykły <?php otwarcie tokena może być prawomocnie sparowane z rzadko używanym </script> jako nieparzysty token zamknięcia .

  • "hard close tag " nie jest nawet jednym -- po prostu wymyślił to określenie dla analogii. Koncepcyjnie i użytkowo __halt_compiler powinien być jednak rozpoznawany jako close token.

    __HALT_COMPILER();
    ?>
    

    Który w zasadzie ma tokenizer odrzuca każdy kod lub zwykłe sekcje HTML. W poszczególne stuby PHAR wykorzystują to, lub jego nadmiarową kombinację z ?>, Jak przedstawiono.

  • Podobnie czy void return; rzadko zastępuje Skrypty include, renderując dowolne ?> z końcowymi białymi spacjami noneffective.

  • Potem są wszelkiego rodzaju soft / faux bliskie odmiany tagów; mniej znane i używane, ale zwykle nakomentowane tokeny:

    • Prosty odstęp // ? > aby uniknąć wykrycia przez tokenizer PHPs.

    • Lub fantazyjne zamienniki Unicode// ﹖﹥ (U + FE56 mały znak zapytania, u + FE65 mały Kątownik), który może uchwycić Wyrażenie regularne.

    Oba nic nie znaczą dla PHP , ale mogą mieć praktyczne zastosowania dla nieświadomych lub pół-świadomych zewnętrznych zestawów narzędzi. Ponownie cat - przychodzą na myśl połączone skrypty, z wynikowymi // ? > <?php konkatenacjami, które w linii-zachowują poprzedni plik sekcja.

Istnieją więc zależne od kontekstu, ale praktyczne alternatywy dla imperatywnego pominięcia znacznika close.

Ręczne opiekowanie się ?> close tags nie jest zbyt współczesne. Zawsze były do tego narzędzia automatyzacji (nawet jeśli tylko sed / awk lub regex-oneliners). W szczególności:

Tag Phptags

https://fossil.include-once.org/phptags/

Które mogłyby zazwyczaj używane do --unclose znaczników php dla kodu stron trzecich, a raczej po prostu naprawiać wszelkie (i wszystkie) rzeczywiste problemy z białymi spacjami/BOM:

  • phptags --warn --whitespace *.php

Obsługuje również konwersję znaczników --long itp. dla zgodności runtime/configuration.

 51
Author: mario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:48

It isn ' t a tag ...

Ale jeśli go masz, ryzykujesz, że po nim pojawi się biała spacja.

Jeśli użyjesz go jako nagłówka na górze dokumentu, możesz wstawić białą spację (tj. zawartość) przed próbą wysłania nagłówków HTTP ... co jest niedozwolone .

 16
Author: Quentin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-10 16:02:45

To całkiem przydatne, aby nie dopuścić do zamknięcia ?>.

Plik pozostaje ważny dla PHP (nie jest to błąd składni) i jak powiedział @ David Dorward pozwala uniknąć białych spacji / linii podziału (wszystkiego, co może wysłać nagłówek do przeglądarki) po ?>.

Na przykład,

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10);
    imagepng ( $img);
?>
[space here]
[break line here]

Nie będzie ważne.

Ale

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10 );
    imagepng ( $img );
Will. Choć raz musisz być leniwy, by być bezpiecznym.
 12
Author: Shikiryu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-19 15:46:40

Zgodnie z docs, lepiej jest pominąć znacznik zamykający, jeśli znajduje się na końcu pliku z następującego powodu:

Jeśli plik jest czystym kodem PHP, lepiej jest pominąć znacznik zamykający PHP na końcu pliku. Zapobiega to przypadkowemu dodawaniu spacji lub nowych linii po znaczniku zamykającym PHP, co może powodować niepożądane efekty, ponieważ PHP rozpocznie buforowanie wyjścia, gdy programista nie ma zamiaru wysyłać żadnego wyjścia w tym momencie scenariusz.

Podręcznik PHP > indeks językowy > Podstawowa składnia > znaczniki PHP

 10
Author: Asaph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-17 19:39:51

Są dwa sposoby patrzenia na to.

  1. kod PHP jest niczym więcej niż zestawem instrukcji przetwarzania XML, a zatem każdy plik z rozszerzeniem .php jest niczym więcej niż plikiem XML, który tak się składa, że jest przetwarzany dla kodu PHP.
  2. PHP tak się składa, że dzieli format instrukcji przetwarzania XML dla swoich tagów open I close. Na tej podstawie pliki z rozszerzeniami .php mogą być poprawnymi plikami XML, ale nie muszą nimi być.

Jeśli wierzysz w pierwszą trasę, wtedy wszystkie pliki PHP wymagają zamykania znaczników końcowych. Pominięcie ich spowoduje utworzenie nieprawidłowego pliku XML. Z drugiej strony, bez deklaracji otwierającej <?xml version="1.0" charset="latin-1" ?>, nie będziesz miał poprawnego pliku XML... Więc to nie jest poważny problem...

Jeśli wierzysz w drugą drogę, która otwiera drzwi dla dwóch typów.php plików:

  • pliki zawierające tylko kod (np. pliki biblioteczne)
  • pliki zawierające natywny XML, a także kod (pliki szablonów dla przykład)

W oparciu o to, Pliki tylko z kodem mogą kończyć się bez znacznika zamykającego ?>. Ale pliki z kodem XML nie są w porządku, aby zakończyć bez zamknięcia ?>, ponieważ unieważniłoby to XML.

Ale wiem, o czym myślisz. Myślisz, co to ma znaczenie, nigdy nie będziesz renderować pliku PHP bezpośrednio, więc kogo obchodzi, czy to poprawny XML. Cóż, ma znaczenie, jeśli projektujesz szablon. Jeśli jest poprawny XML / HTML, normalna przeglądarka po prostu nie wyświetli kodu PHP (jest traktowany jak komentarz). Możesz więc wykreować szablon bez konieczności uruchamiania kodu PHP w nim... Nie mówię, że to ważne. To tylko pogląd, którego nie widzę zbyt często wyrażany, więc jakie jest lepsze miejsce, aby się nim podzielić...

Osobiście nie zamykam znaczników w plikach bibliotecznych, ale robię to w plikach szablonów... Myślę, że to osobiste preferencje (i wytyczne kodowania) oparte bardziej niż cokolwiek twardego...

 8
Author: ircmaxell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-19 15:49:40

Cóż, znam powód, ale nie mogę tego pokazać:

Dla plików zawierających tylko kod PHP, znacznik zamknięcia (?>) nigdy nie jest dozwolone. Nie jest wymagany przez PHP, i pominięcie go zapobiega / align = "left" / miejsce w klasyfikacji generalnej.

Źródło: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html

 6
Author: tawfekov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-19 15:45:04

Oprócz wszystkiego, co już zostało powiedziane, dorzucę jeszcze jeden powód, który był dla nas ogromnym bólem debugowania.

Apache 2.4.6 z PHP 5.4 faktycznie błędy segmentacji na naszych maszynach produkcyjnych, gdy jest puste miejsce za zamykającym php tagiem. Po prostu zmarnowałem godziny, aż w końcu zawęziłem błąd z strace .

Oto błąd, który rzuca Apache:

[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
 6
Author: Artem Russakovskii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-19 21:12:16

Plusy

Cons

Podsumowanie

Powiedziałbym, że argumenty przemawiające za pominięciem znacznika wyglądają silniej (pomaga uniknąć wielkiego bólu głowy dzięki header () + jest to "rekomendacja"PHP/Zend). Przyznaję, że nie jest to najbardziej "piękne" rozwiązanie, jakie kiedykolwiek widziałem pod względem spójności składni, ale co może być lepszego ?

 4
Author: Frosty Z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-19 08:57:16

" czy istnieje inny dobry powód (inny niż problem z nagłówkiem), aby pominąć kończący się tag php?"

Nie chcesz przypadkowo wypisywać obcych znaków białych znaków podczas generowania wyjścia binarnego, danych CSV lub innego wyjścia nie-HTML.

 4
Author: user1238364,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-19 21:10:48

Jako że moje pytanie zostało oznaczone jako DUPLIKAT tego, myślę, że dobrze jest pisać dlaczego nie pomijanie znacznika zamykającego ?> może być z pewnych powodów pożądane.

  • With complete Processing Instructions Syntax (<?php ... ?>) źródło PHP jest poprawnym dokumentem SGML, który może być parsowany i przetwarzany bez problemów z PARSEREM SGML. Z dodatkowymi ograniczeniami może być również poprawny XML / XHTML.

Nic nie stoi na przeszkodzie, aby napisać poprawny kod XML / HTML / SGML. PHP dokumentacja jest tego świadoma. Fragment:

Uwaga: zauważ również, że jeśli osadzasz PHP w XML lub XHTML będziesz musiał użyć tagi, aby zachować zgodność ze standardami.

Oczywiście składnia PHP nie jest ścisła SGML / XML / HTML i tworzysz dokument, który nie jest SGML / XML / HTML, tak jak możesz zmienić HTML w XHTML, aby był zgodny z XML lub nie.

  • W pewnym momencie możesz chcieć połączyć źródła. To nie będzie takie proste. jak po prostu zrobić cat source1.php source2.php Jeśli masz niespójność wprowadzoną przez pominięcie tagów zamykających ?>.

  • Bez ?> trudniej jest stwierdzić, czy dokument pozostał w trybie escape PHP, czy w trybie ignorowania PHP (znacznik PI <?php mógł zostać otwarty, czy nie). Życie jest łatwiejsze, jeśli konsekwentnie zostawiasz dokumenty w trybie ignorowania PHP. To tak jak praca z dobrze sformatowanymi dokumentami HTML w porównaniu z dokumentami z nie zamkniętymi, źle zagnieżdżonymi znacznikami itp.

  • Wydaje się, że niektórzy redaktorzy lubią Program Dreamweaver może mieć problemy z otwartym PI [1].

 1
Author: doc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 18:01:28

Jeśli dobrze rozumiem pytanie, ma to związek z buforowaniem wyjścia i wpływem, jaki może to mieć na tagi zamykające / kończące. Nie jestem pewien, czy to jest całkowicie słuszne pytanie. Problem polega na tym, że bufor wyjściowy nie oznacza, że cała zawartość jest przechowywana w pamięci przed wysłaniem jej do klienta. Oznacza to, że część treści jest.

Programista może celowo spłukać bufor lub bufor wyjściowy, tak więc opcja bufora wyjściowego w PHP naprawdę zmienia sposób zamykania znacznika wpływa na kodowanie? Twierdzę, że tak nie jest.

I być może dlatego większość odpowiedzi wróciła do osobistego stylu i składni.

 0
Author: Ruz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-17 17:07:39

Istnieje 2 możliwe użycie kodu php:

  1. kod PHP taki jak definicja klasy czy definicja funkcji
  2. Użyj PHP jako języka szablonów (np. w widokach)

W przypadku 1. znacznik zamykający jest całkowicie bezużyteczny, również chciałbym zobaczyć tylko 1 (jeden) php otwarty znacznik i brak (zero) znacznika zamykającego w takim przypadku. Jest to dobra praktyka, ponieważ sprawia, że kod jest czysty i oddziela logikę od prezentacji. W przypadku prezentacji (2.) niektórzy stwierdzili, że naturalne jest zamykanie wszystkich tagów (nawet PHP-przetworzone), co prowadzi do konfuzji, ponieważ PHP ma w rzeczywistości 2 oddzielne przypadki użycia, które nie powinny być mieszane: logika / rachunek i prezentacja

 0
Author: Daniele Cruciani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-31 11:47:52