Ciągle czytam, że słabą praktyką jest używanie znacznika zamykającego PHP ?>
na końcu pliku. Problem nagłówka wydaje się nieistotny w następującym kontekście (i jest to jedyny jak dotąd dobry argument):
Nowoczesne wersje PHP ustawiają flagę output_buffering w php.ini Jeśli buforowanie danych wyjściowych jest włączone, możesz ustawić nagłówki HTTP i pliki cookie po wyprowadzeniu HTML, ponieważ zwracany kod nie jest natychmiast wysyłany do przeglądarki.
Każda książka dobrych praktyk i wiki zaczyna się od tej „zasady”, ale nikt nie podaje dobrych powodów. Czy istnieje inny dobry powód, aby pominąć końcowy tag PHP?
php
security
http-headers
Danidacar
źródło
źródło
?>
jest leniwa?Odpowiedzi:
Wysyłanie nagłówków wcześniej niż normalny kurs może mieć daleko idące konsekwencje. Poniżej znajduje się tylko kilka z nich, które w tej chwili przyszły mi do głowy:
Chociaż obecne wersje PHP mogą mieć buforowanie danych wyjściowych, rzeczywiste serwery produkcyjne, na których będziesz wdrażać kod, są znacznie ważniejsze niż jakiekolwiek maszyny programistyczne lub testujące. I nie zawsze mają tendencję do natychmiastowego śledzenia najnowszych trendów PHP.
Możesz mieć problemy z niewytłumaczalną utratą funkcjonalności . Załóżmy, że wdrażasz jakąś bramę płatności i przekierowujesz użytkownika na określony adres 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 wydawać się niezapłacony. Jest to również jeden z powodów, dla których niepotrzebne przekierowanie jest złe, a jeśli przekierowanie ma być zastosowane, należy go używać ostrożnie.
W przeglądarce Internet Explorer mogą występować błędy typu „Ładowanie strony anulowane”, nawet w najnowszych wersjach. Wynika to z faktu, że odpowiedź AJAX / plik json 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.
Jeśli masz jakieś pliki do pobrania w swojej aplikacji, mogą się z tego powodu zepsuć. I możesz tego nie zauważyć, nawet po latach, ponieważ specyficzny nawyk pobierania zależy od serwera, przeglądarki, rodzaju i zawartości pliku (i ewentualnie innych czynników, którymi nie chcę Cię nudzić) .
Wreszcie wiele frameworków PHP, w tym Symfony , Zend i Laravel (nie ma wzmianki o tym w wytycznych dotyczących kodowania, ale podąża za nimi) i standard PSR-2 (pozycja 2.2) wymagają pominięcia znacznika zamykającego. Sam podręcznik PHP ( 1 , 2 ), Wordpress , Drupal i wiele innych programów PHP, jak sądzę, radzę to zrobić. Jeśli po prostu przyzwyczaisz się do standardowego (i instalujesz PHP-CS-Fixer dla swojego kodu), możesz zapomnieć o tym problemie. W przeciwnym razie zawsze będziesz musiał pamiętać o tym problemie.
Bonus: kilka gotch (obecnie jedna) związanych z tymi 2 postaciami:
?>
. Przykładem jest Smarty, nawet najnowsze wersje gałęzi 2. * i 3. * mają to. Jak zawsze uważaj na kod innej firmy . Bonus w premii: Wyrażenie regularne do usuwania niepotrzebnych zakończeń PHP: zamień na(\s*\?>\s*)$
pusty tekst we wszystkich plikach zawierających kod PHP.źródło
\?>(?s:.){0,10}\Z
Krótkie wyjaśnienie: changeset.hr/blog/miscellaneous/catch-near-eof-with-regex?>
: np. Pasuje?> Hello
do -i usunąłby- w<?php echo "test"; ?> Hello
. Chcemy wyczyścić tylko zamknięte tagi.[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
.?>
, która (jak każde wyjście) powoduje, że nagłówki są wysyłane, gdy tylko zostaną wyświetlone. Nie ma „nagłówków HTML” (innych niż niepowiązany<header>
znacznik HTML5 ).Powodem, dla którego powinieneś zrezygnować z tagu zamykającego php (
?>
) jest to, że programista nie wysyła przypadkowo dodatkowych znaków nowej linii.Powodem, dla którego nie powinieneś pomijać tagu zamykającego php, jest to, że powoduje on brak równowagi w tagach php, a każdy programista mający pół umysłu pamięta, aby nie dodawać dodatkowych białych znaków.
Więc na twoje pytanie:
Nie, nie ma innego dobrego powodu, aby pominąć końcowe znaczniki php.
Na zakończenie przedstawię kilka argumentów za tym, aby nie zawracać sobie głowy zamykającym tagiem:
Ludzie zawsze mogą popełniać błędy, bez względu na to, jak są mądrzy. Dobrym pomysłem jest stosowanie praktyki ograniczającej liczbę możliwych błędów.
PHP nie jest XML. PHP nie musi przestrzegać ścisłych standardów XML, aby być dobrze napisanym i funkcjonalnym. Jeśli irytuje Cię brakujący tag zamykający, możesz użyć tagu zamykającego, to nie jest reguła osadzona w taki czy inny sposób.
źródło
Jest to zalecenie dotyczące stylu kodowania dla początkujących , o dobrych intencjach i wskazane w instrukcji .
Unikanie
?>
rozwiązuje jednak tylko pewną liczbę popularnych nagłówków, które już zostały wysłane (dane wyjściowe, BOM , powiadomienia itp.) I problemy z nimi związane.PHP faktycznie zawiera trochę magii, aby pożreć pojedyncze łamanie wierszy po
?>
tokenie zamykającym. Chociaż ma to problemy historyczne i pozostawia przybyszów nadal podatnych na luźne edytory i nieświadomie tasuje w innych białych znakach później?>
.Stylistycznie niektórzy deweloperzy wolą widzenia
<?php
i?>
jako znaczniki SGML / XML przetwarzania instrukcji, co oznacza konsystencję saldo końcowe blisko żeton. (Które btw jest przydatne w przypadku klasy łączącej zależność, która zastępuje nieefektywne automatyczne ładowanie plik po pliku).Dość rzadko otwór
<?php
charakteryzuje się tym, phps shebang (w pełni możliwe za binfmt_misc ), zatwierdzając tym samym redundancję odpowiedniego blisko tag.Jest oczywiste doradztwo rozbieżność między klasycznych przewodników składni PHP upoważniającym
?>\n
i bardziej aktualna (PSR-2) uzgodnienie zaniechania.(Dla przypomnienia: postulowanie Zend Framework jeden nad drugim nie implikuje jego wewnętrznej wyższości. To błędne przekonanie, że eksperci byli przyciągani do / docelowych odbiorców nieporęcznych API).
Moduły SCM i nowoczesne środowiska IDE zapewniają wbudowane rozwiązania, które w większości pomagają w utrzymywaniu dokładnych tagów.
Zniechęcanie do używania
?>
tagu zamknięcia opóźnia jedynie wyjaśnienie podstawowych zachowań PHP i semantyki języka w celu uniknięcia rzadkich problemów. Nadal jest praktyczny w przypadku wspólnego opracowywania oprogramowania ze względu na różnice w umiejętnościach uczestników.Zamknij odmiany tagów
Regularne ?> blisko znacznik jest również znany jako
T_CLOSE_TAG
, lub w ten sposób „blisko żeton”.Zawiera jeszcze kilka inkarnacji, z powodu magicznego jedzenia nowej linii PHP :
?>\n (Unix linefeed)
?>\r (Zwrot karetki, klasyczne adresy MAC)
?>\r\n (CR / LF, na DOS / Win)
PHP nie obsługuje jednak łamania linii kombi Unicode NEL(U + 0085).
Wczesne wersje PHP zawierały kompilacje IIRC, które nieco ograniczały agnostycyzm platformy (FI był nawet używany
>
jako znacznik bliski), co jest prawdopodobnym historycznym początkiem unikania bliskiego znacznika.Często pomijane, ale dopóki PHP7 ich nie usunie , zwykły
<?php
token otwierający może zostać poprawnie sparowany z rzadko używanym</script>
jako nieparzysty token zamykający .„ Twardy ścisły tag ” nie jest nawet jeden - właśnie stworzył ten termin dla analogii. Pod względem koncepcyjnym i użytkowym
__halt_compiler
należy jednak uznać je za ścisły token.Który w zasadzie ma tokenizer, odrzuć później dowolny kod lub zwykły fragment HTML. W szczególności kody pośredniczące PHAR wykorzystują to lub jego zbędną kombinację z
?>
przedstawionymi.Podobnie pustka
return;
rzadko zastępuje skrypty włączające, co powoduje, że żadne?>
z końcowymi spacjami nie jest skuteczne.Są też wszelkiego rodzaju odmiany miękkich / sztucznych zamknięć ; rzadziej znane i rzadko używane, ale zwykle według skomentowanych tokenów:
Proste odstępy w
// ? >
celu uniknięcia wykrycia przez tokenizer PHPs.Lub wymyślne zamienniki Unicode
// ﹖﹥
(U + FE56 MAŁY PYTANIE, U + FE65 MAŁY KĄT UCHWYTU), które wyrażenie regularne może uchwycić.Obie nic nie znaczą dla PHP , ale mogą mieć praktyczne zastosowania dla nieświadomych PHP lub częściowo świadomych zewnętrznych zestawów narzędzi. Ponownie
cat
przychodzą mi na myśl skrypty// ? > <?php
połączone , z wynikowymi połączeniami, które zachowują poprzednią sekcję plików.Istnieją zatem zależne od kontekstu, ale praktyczne alternatywy dla bezwzględnego pominięcia znacznika.
Ręczna opieka nad
?>
bliskimi tagami nie jest zbyt współczesna. Zawsze były do tego narzędzia automatyzacji (nawet jeśli tylko sed / awk lub regex-oneliners). W szczególności:Które mogą być ogólnie używane do
--unclose
tagów php dla kodu innej firmy, a raczej po prostu naprawić wszelkie (i wszystkie) rzeczywiste problemy z białymi / BOM:phptags --warn --whitespace *.php
Obsługuje także
--long
konwersję tagów itp. W celu zapewnienia zgodności środowiska wykonawczego / konfiguracji.źródło
<?php if($var): ?>Hello World<?php endif; ?>
??? Jestem naprawdę ciekawy, ponieważ nie zostało to specjalnie wymienione.To nie jest tag…
Ale jeśli go masz, ryzykujesz, że będzie po nim spacja.
Jeśli następnie użyjesz go jako dołączenia u góry dokumentu, możesz skończyć wstawianiem białych znaków (tj. Treści) przed próbą wysłania nagłówków HTTP… co jest niedozwolone.
źródło
<?php $i = 1; ?>
następnie plik2.php:<?php include 'file1.php'; header('Location: http://www.google.com');?>
phpcs
aby upewnić się, że tag zamykający pozostanie z każdego z moich plików, a następnie nie martwię się o buforowanie danych wyjściowych :)Bardzo przydatne jest, aby nie dopuścić do zamknięcia
?>
.Plik pozostaje ważny dla PHP (nie jest to błąd składniowy) i, jak powiedział @David Dorward, pozwala uniknąć białych znaków / linii podziału (wszystko, co może wysłać nagłówek do przeglądarki) po
?>
.Na przykład,
nie będzie ważny.
Ale
będzie.
Tym razem musisz być leniwy, aby być bezpiecznym .
źródło
?>
. bezpieczne może nie być tutaj dobrym słowem. W każdym razie nic nie naprawia (nie jest to dla mnie zły kod, aby temu zapobiec,echo
tutaj byłby zły kod), ale / i nadal jest ważny. Udowodnij, że się mylę w tej sprawie.?>
na końcu pliku tylko php. ale czy kiedykolwiek miałeś potrzebę debugowania błędu spowodowanego przez końcowe spacje? Również nie wszystkie serwery są skonfigurowane w ten sam sposób, szczególnie gdy przenosisz się na inny host, wyłapywanie błędów jest bardzo czasochłonne. Jeśli chcesz to?>
po prostu zrób, zrób to, jeśli dodasz trochę miejsca na końcu, a Twój zespół będzie musiał debugować, aby być gotowym doZgodnie z dokumentami lepiej jest pominąć tag zamykający, jeśli znajduje się on na końcu pliku z następującego powodu:
Podręcznik PHP> Dokumentacja językowa> Podstawowa składnia> Znaczniki PHP
źródło
Znam przyczynę, ale nie mogę jej pokazać:
Źródło: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html
źródło
Są na to dwa sposoby.
.php
rozszerzeniem jest niczym więcej niż plikiem XML, który tak się składa, że jest analizowany dla kodu PHP..php
rozszerzeniami MOGĄ być poprawnymi plikami XML, ale nie muszą.Jeśli wierzysz w pierwszą trasę, wszystkie pliki PHP wymagają zamykania znaczników końcowych. Pominięcie ich spowoduje utworzenie nieprawidłowego pliku XML. Z drugiej strony, bez
<?xml version="1.0" charset="latin-1" ?>
deklaracji otwierającej , i tak nie będziesz mieć prawidłowego pliku XML ... Więc to nie jest poważny problem ...Jeśli uważasz, że druga droga otwiera drzwi do dwóch rodzajów
.php
plików:W związku z tym pliki zawierające tylko kod można zakończyć bez
?>
tagu zamykającego . Ale pliki z kodem XML nie mogą zakończyć się bez zamknięcia,?>
ponieważ spowodowałoby to unieważnienie XML.Ale wiem, co myślisz. Zastanawiasz się, co to ma znaczenie, nigdy nie będziesz renderować pliku PHP bezpośrednio, więc kogo to obchodzi, czy jest to poprawny XML. Cóż, nie ma znaczenia, czy projektujesz szablon. Jeśli jest to poprawny XML / HTML, normalna przeglądarka po prostu nie wyświetla kodu PHP (jest traktowany jak komentarz). Możesz więc wykpić szablon bez konieczności uruchamiania kodu PHP w ...
Nie mówię, że to ważne. To tylko widok, który nie jest zbyt często wyrażany, więc co lepszego miejsca, aby go udostępnić ...
Osobiście nie zamykam tagów w plikach biblioteki, ale robię to w plikach szablonów ... Myślę, że to osobiste preferencje (i wytyczne kodowania) oparte bardziej niż cokolwiek twardego ...
źródło
Oprócz wszystkiego, co już powiedziano, zamierzam przedstawić jeszcze jeden powód, dla którego debugowanie było dla nas ogromnym problemem.
Apache 2.4.6 z PHP 5.4 faktycznie powoduje błędy segmentacji na naszych maszynach produkcyjnych, gdy za
php
tagiem zamykającym jest pusta przestrzeń . Po prostu zmarnowałem godziny, aż w końcu zawęziłem błąd do strace .Oto błąd, który zgłasza Apache:
źródło
„Czy istnieje inny dobry powód (inny niż problem z nagłówkiem), aby pominąć końcowy tag php?”
Podczas generowania danych binarnych, danych CSV lub innych danych innych niż HTML nie chcesz nieumyślnie wyświetlać obcych znaków białych znaków .
źródło
Plusy
Cons
Wniosek
Powiedziałbym, że argumenty przemawiające za pominięciem tagu wyglądają na silniejsze (pomaga uniknąć dużego bólu głowy z nagłówkiem () + jest to „zalecenie” 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?
źródło
Ponieważ moje pytanie zostało oznaczone jako duplikat tego, wydaje mi się, że można opublikować komunikat, dlaczego NIE ominięcie tagu zamykającego
?>
może być z pewnych powodów pożądane.<?php ... ?>
) Źródło PHP jest poprawnym dokumentem SGML, który można analizować i przetwarzać bez problemów z parserem SGML. Z dodatkowymi ograniczeniami może być również poprawny XML / XHTML.Nic nie stoi na przeszkodzie, aby napisać prawidłowy kod XML / HTML / SGML. Dokumentacja PHP jest tego świadoma. Fragment:
Oczywiście składnia PHP nie jest ścisła SGML / XML / HTML i tworzysz dokument, który nie jest SGML / XML / HTML, podobnie jak możesz zmienić HTML na XHTML, aby był zgodny lub nie.
W pewnym momencie możesz chcieć połączyć źródła. Nie będzie to tak proste, jak po prostu zrobienie,
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 ucieczki PHP, czy w trybie ignorowania PHP (tag PI<?php
mógł zostać otwarty, czy nie). Życie jest łatwiejsze, jeśli konsekwentnie pozostawiasz swoje dokumenty w trybie ignorowania PHP. To tak jak praca z dobrze sformatowanymi dokumentami HTML w porównaniu do dokumentów z niezamkniętymi, źle zagnieżdżonymi znacznikami itp.Wygląda na to, że niektórzy redaktorzy, tacy jak Dreamweaver, mogą mieć problemy z PI pozostawionym otwartym [1] .
źródło
Jeśli dobrze rozumiem pytanie, ma to związek z buforowaniem danych wyjściowych i wpływem, jaki może to mieć na zamykanie / kończenie tagów. Nie jestem pewien, czy jest to całkowicie uzasadnione 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 niektóre treści są.
Programista może celowo opróżnić bufor lub bufor wyjściowy, więc czy opcja bufora wyjściowego w PHP naprawdę zmienia wpływ tagu zamykającego na kodowanie? Twierdziłbym, że tak nie jest.
I może dlatego większość odpowiedzi wróciła do osobistego stylu i składni.
źródło
Istnieją 2 możliwe zastosowania kodu php:
w przypadku 1. tag zamykający jest całkowicie nieużyteczny, chciałbym również zobaczyć tylko 1 (jeden) tag otwarty php i NO (zero) tag zamykający w takim przypadku. Jest to dobra praktyka, ponieważ czyści kod i oddziela logikę od prezentacji. W przypadku prezentacji (2.) niektórzy stwierdzili, że naturalne jest zamknięcie wszystkich tagów (nawet tych przetworzonych w PHP), co prowadzi do zamieszania, ponieważ PHP ma w rzeczywistości 2 osobne przypadki użycia, których nie należy mieszać: logika / rachunek i prezentacja
źródło