Зачем опускать закрывающий тег?
Я продолжаю читать, что использование закрывающего тега PHP ?> в конце файла — плохая практика. Проблема заголовка кажется неуместной в следующем контексте (и пока это единственный хороший аргумент):
Современные версии PHP устанавливают флаг output_buffering в php.ini. Если буферизация вывода включена, вы можете установить заголовки HTTP и файлы cookie после вывода HTML, поскольку возвращаемый код не отправляется в браузер сразу.
Все хорошие практические книги и вики начинаются с этого «правила», но никто не предлагает веских причин. Есть ли еще одна веская причина пропустить закрывающий тег PHP?
13 ответов
Отправка заголовков раньше обычного может иметь далеко идущие последствия. Ниже приведены лишь некоторые из них, которые пришли мне в голову в данный момент:
В то время как в текущих выпусках PHP может быть включена буферизация вывода, фактические производственные серверы , на которых вы будете развертывать свой код, гораздо важнее, чем любые машины для разработки или тестирования. И они не всегда стремятся сразу же следовать последним трендам PHP.
У вас могут возникнуть головные боли из-за необъяснимой потери функциональности . Скажем, вы внедряете какой-то платежный шлюз и перенаправляете пользователя на определенный URL-адрес после успешного подтверждения обработчиком платежей. Если произойдет какая-то ошибка PHP, даже предупреждение или завершение лишней строки, платеж может остаться необработанным, и пользователю может показаться, что счет не выставлен. Это также одна из причин, почему ненужное перенаправление является злом, и если перенаправление должно использоваться, его следует использовать с осторожностью.
Вы можете получить ошибку типа «Загрузка страницы отменена» в Internet Explorer, даже в самых последних версиях. Это связано с тем, что ответ AJAX / json include содержит что-то, чего он не должен содержать из-за лишних окончаний строк в некоторых файлах PHP, с чем я столкнулся несколько дней назад.
Если в вашем приложении есть загрузки файлов , из-за этого они тоже могут прерваться. И вы можете не заметить этого даже спустя годы, поскольку конкретная привычка к прерыванию загрузки зависит от сервера, браузера, типа и содержимого файла (и, возможно, некоторых других факторов, которыми я не хочу вас утомлять) .
Наконец, многие фреймворки PHP, включая Symfony, Zend и Laravel (в рекомендации по кодированию, но он следует их примеру) и Стандарт PSR-2 (пункт 2.2) требует опустить закрывающий тег. Само руководство по PHP (1, 2), WordPress, Drupal и многие другие программы PHP, я думаю, советуют это сделать. Если вы просто привыкли следовать стандарту (и настроили PHP-CS-Fixer для ваш код) вы можете забыть о проблеме. В противном случае вам всегда нужно будет держать эту проблему в уме.
Бонус: несколько ошибок (на данный момент одна), связанных с этими двумя персонажами:
- Даже некоторые известные библиотеки могут содержать лишние окончания строк после ?> . Примером является Smarty, даже самые последние версии веток 2. * и 3. * имеют это. Итак, как всегда, следите за сторонним кодом . Бонус в качестве бонуса: регулярное выражение для удаления ненужных окончаний PHP: замените (\s*\?>\s*)$ пустым текстом во всех файлах, содержащих код PHP.
Причина, по которой вы должны оставить закрывающий тег php ( ?> ), заключается в том, чтобы программист случайно не отправил лишние символы новой строки.
Причина, по которой вы не должны оставлять закрывающий тег php, заключается в том, что он вызывает дисбаланс в тегах php, и любой программист со слабым умом может помнить, что не следует добавлять лишние пробелы.
Так что для вашего вопроса:
Есть ли еще одна веская причина пропустить конечный тег php?
Нет, нет другой веской причины пропускать конечные теги php.
Я закончу некоторыми аргументами, чтобы не беспокоиться о закрывающем теге:
Люди всегда могут ошибаться, какими бы умными они ни были. Придерживаться практики, которая снижает количество возможных ошибок, (ИМХО) — хорошая идея.
PHP — это не XML. PHP не обязательно должен придерживаться строгих стандартов XML, чтобы быть хорошо написанным и функциональным. Если отсутствующий закрывающий тег вас раздражает, вам разрешено использовать закрывающий тег, это не так или иначе неукоснительное правило.
Согласно документам, предпочтительно опустить закрывающий тег, если он находится в конце файла по следующей причине:
Если файл представляет собой чистый код PHP, предпочтительно не указывать закрывающий тег PHP в конце файла. Это предотвращает случайный пробел или добавление новых строк после закрывающего тега PHP, что может вызвать нежелательные эффекты, поскольку PHP начнет буферизацию вывода, когда программист не намерен отправлять какие-либо выходные данные в этот момент в сценарии.
Очень полезно не пропускать закрывающий ?> .
Файл остается действительным для PHP (не является синтаксической ошибкой), и, как сказал @David Dorward, он позволяет избежать пробелов / разрывов (всего, что может отправлять заголовок в браузер) после ?> .
Не будет действительным.
На этот раз вы должны быть ленивыми, чтобы быть защищенным .
Что ж, я знаю причину, но не могу ее показать:
Для файлов, содержащих только код PHP, закрывающий тег ( ?> ) никогда не разрешенный. Это не требуется для PHP, и его пропуск предотвращает случайная инъекция оставшегося белого пробел в ответ.
Что ж, есть два взгляда на это.
- Код PHP — это не что иное, как набор инструкций по обработке XML, и, следовательно, любой файл с расширением .php является не чем иным, как файлом XML, который случайно анализируется на предмет наличия кода PHP.
- Так получилось, что PHP использует формат инструкций по обработке XML для своих тегов open и close. Исходя из этого, файлы с расширениями .php МОГУТ быть допустимыми файлами XML, но это не обязательно.
Если вы верите в первый маршрут, то все файлы PHP требуют закрывающих закрывающих тегов. Если их пропустить, будет создан недопустимый файл XML. С другой стороны, без открывающего объявления <?xml version=»1.0″ charset=»latin-1″ ?> у вас все равно не будет действительного XML-файла . Так что это не главная проблема .
Если вы верите во второй путь, это открывает дверь для двух типов файлов .php :
- Файлы, содержащие только код (например, файлы библиотеки)
- Файлы, содержащие собственный XML, а также код (например, файлы шаблонов)
Исходя из этого, файлы, содержащие только код, могут заканчиваться без закрывающего тега ?> . Но файлы XML-кода не могут заканчиваться без закрытия ?> , поскольку это сделало бы XML недействительным.
Но я знаю, о чем вы думаете. Вы думаете, какое это имеет значение, вы никогда не собираетесь рендерить файл PHP напрямую, так что кого волнует, действительный ли это XML. Что ж, это имеет значение, разрабатываете ли вы шаблон. Если это действительный XML / HTML, обычный браузер просто не будет отображать PHP-код (он обрабатывается как комментарий). Таким образом, вы можете смоделировать шаблон без необходимости запускать PHP-код внутри .
Я не говорю, что это важно. Это просто точка зрения, которую я не вижу слишком часто, так что где лучше поделиться ею .
Лично я не закрываю теги в файлах библиотеки, но делаю это в файлах шаблонов . Я думаю, что это личные предпочтения (и рекомендации по кодированию), основанные больше, чем что-либо сложное .
В дополнение ко всему, что уже было сказано, я собираюсь указать еще одну причину, по которой нам было очень трудно отлаживать.
Apache 2.4.6 с PHP 5.4 на самом деле приводит к сбою сегментации на наших производственных машинах, когда за закрытием остается пустое место Тег php . Я потратил впустую часы, пока наконец не решил проблему с помощью strace.
Вот ошибка, которую выдает Apache:
«Есть ли еще одна веская причина (кроме проблемы с заголовком), чтобы пропустить конечный тег php?»
Вы не хотите непреднамеренно выводить лишние символы пробела при генерации двоичного вывода, данных CSV, или другой вывод, отличный от HTML.
- Было бы логично закрыть любой открытый тег , как и с другими языками. Не только теги X (HT) ML, но и фигурные скобки, скобки . .
- Избегает головной боли при добавлении случайных пробелов после закрывающего тега, поскольку это нарушает поведение функции header () . Некоторые редакторы или FTP-клиенты / серверы также могут автоматически изменять конец файлов (по крайней мере, это их конфигурация по умолчанию). , а Zend даже запрещает это.
Вывод
Я бы сказал, что аргументы в пользу исключения тега выглядят убедительнее (помогает избежать большой головной боли с помощью header () + это «рекомендация» PHP / Zend). Я признаю, что это не самое «красивое» решение, которое я когда-либо видел с точки зрения согласованности синтаксиса, но что может быть лучше?
Поскольку мой вопрос был отмечен как дубликат этого, я думаю, что все в порядке. по некоторым причинам может быть желательно опубликовать, почему НЕ опущен закрывающий тег ?> .
- С полным синтаксисом инструкций обработки ( <?php . ?> ) источником PHP является действительный документ SGML, который можно без проблем анализировать и обрабатывать с помощью синтаксического анализатора SGML. С дополнительными ограничениями он также может быть допустимым XML / XHTML.
Ничто не мешает вам написать корректный код XML / HTML / SGML. Об этом известно в документации PHP. Отрывок:
Примечание. Также обратите внимание, что если вы встраиваете PHP в XML или XHTML, вам нужно будет использовать теги , Чтобы соответствовать стандартам.
Конечно, синтаксис PHP не является строгим SGML / XML / HTML, и вы создаете документ, который не является SGML / XML / HTML, точно так же, как вы можете преобразовать HTML в XHTML, чтобы он был совместим с XML или нет.
В какой-то момент вы можете захотеть объединить источники. Это будет не так просто, как просто выполнить cat source1.php source2.php , если у вас есть несогласованность, вызванная отсутствием закрывающих тегов ?> .
Без ?> труднее определить, был ли документ оставлен в режиме выхода PHP или в режиме игнорирования PHP (тег PI <?php мог быть открыт или нет). Жизнь станет проще, если вы будете постоянно оставлять свои документы в режиме игнорирования PHP. Это похоже на работу с хорошо отформатированными HTML-документами по сравнению с документами с незакрытыми, плохо вложенными тегами и т. Д.
Похоже, что у некоторых редакторов, таких как Dreamweaver, могут возникнуть проблемы с открытием PI [1].
Если я правильно понимаю вопрос, это связано с буферизацией вывода и влиянием, которое это может иметь на закрытие / завершение тегов. Я не уверен, что это вполне обоснованный вопрос. Проблема в том, что выходной буфер не означает, что весь контент хранится в памяти перед отправкой его клиенту. Это означает, что часть контента есть.
Программист может целенаправленно очистить буфер или выходной буфер, поэтому действительно ли параметр выходного буфера в PHP влияет на то, как закрывающий тег влияет на кодирование? Я бы сказал, что это не так.
И, возможно, именно поэтому большинство ответов вернулось к личному стилю и синтаксису.
Но если он у вас есть, вы рискуете остаться после него пустым пространством.
Если вы затем используете его в качестве включения в верхней части документа, вы можете в конечном итоге вставить пробел (то есть контент) перед попыткой отправить заголовки HTTP… что не разрешено.
Есть 2 варианта использования php-кода:
- Код PHP, такой как определение класса или определение функции
- Используйте PHP в качестве языка шаблонов (например, в представлениях)
В случае 1. закрывающий тег совершенно бесполезен, также я хотел бы видеть только 1 (один) открытый тег php и NO (ноль) закрывающий тег в таком случае. Это хорошая практика, поскольку она делает код чистым и отделяет логику от представления. Для случая презентации (2.) некоторые обнаружили, что естественно закрыть все теги (даже те, которые обрабатываются PHP), что приводит к недоразумениям, поскольку PHP фактически имеет 2 отдельных варианта использования, которые не следует смешивать: логика / исчисление. и презентация
Почему не работает код в <? и ?>. Как включить поддержку сокращённых тегов в PHP. Что означает <?=
Закрывающий тег не является обязательным. Тем не менее, закрывающий тег может использоваться когда заканчивается PHP код и начинается, например, HTML код.
Пары <?php и ?> могут использоваться в одном файле несколько раз, отделяя PHP код от HTML кода.
Важная вещь, которую нужно знать про закрывающий тег ?>: он выбросит вас из PHP в HTML даже если он закомментирован с помощью //. Однако комментарий /* */ справляется — тег ?> теряет своё специальное значение. Помните об этой интересной особенности, поскольку при комментировании блоков кода, вы можете столкнуться с необычной ситуацией, когда ?> продолжит работу не смотря на то, что вы этого не ожидаете.
В некоторых старых скриптах или старых учебниках вы можете встретить примеры PHP кода, помещённого между тегов <? и ?>.
Если вы поместите какой-то PHP код между этих тегов, то почти наверняка веб-браузер просто ничего не отобразит с новой версией PHP.
Почему не работает код в <? и ?>
В современных версиях PHP поддержка коротких тегов по умолчанию отключена. Причина в появлении формата XML, взгляните на следующую строку: <?xml version="1.0"?>
Эта строка содержит теги PHP, хотя на самом деле это элемент XML разметки. Чтобы избежать такой двусмысленности, сокращённые теги отключены, но их поддержку можно снова включить!
Как включить поддержку сокращённых тегов в PHP
В файле php.ini имеется директива:
она определяет, разрешается ли короткая форма записи (<? ?>) тегов PHP. Если вы хотите использовать PHP совместно с XML, вы можете отключить эту опцию, чтобы беспрепятственно использовать <?xml ?>. В противном случае, вы можете отобразить это при помощи PHP, например: <?php echo '<?xml version="1.0"?>'; ?>. Если же эта опция отключена, вы должны использовать длинную форму открывающего тега PHP (<?php ?>).
Больше не работают <% и %> и <script language="php">
В PHP 7 удалена поддержка тегов ASP <% и %>, а также <script language="php">.
Что означает <?= в PHP
Конструкция <?= означает буквально
Пример её использования, не вызывающий синтаксическую ошибку:
Отделение PHP и HTML кода
Все, что находится вне пары открывающегося и закрывающегося тегов, игнорируется интерпретатором PHP, у которого есть возможность обрабатывать файлы со смешанным содержимым. Это позволяет PHP-коду быть встроенным в документы HTML, к примеру, для создания шаблонов.
Это работает так, как и ожидается, потому что когда интерпретатор PHP встречает закрывающие теги ?>, он просто начинает выводить все что найдёт (за исключением сразу следующего символа перевода строки) пока не встретит другой открывающий тег за исключением случая с содержащимся внутри кода условным оператором, в котором интерпретатор определяет результат условия перед принятием решения что пропустить. Ознакомьтесь со следующим примером.
Продвинутое изолирование с использованием условий:
В этом примере PHP пропускает блоки, где условие не соблюдается. Даже несмотря на то, что они находятся вне пары открывающих/закрывающих тегов, PHP пропустит их в соответствии с условием, так как интерпретатор PHP будет перепрыгивать через блоки, содержащиеся внутри условия, которое не соблюдается.
При выводе больших блоков текста выход из режима синтаксического разбора PHP обычно более эффективен, чем отправка текста с помощью функций echo или print.
Выход из HTML также применяется к другим управляющим операторам:
При выполнении приведённого выше фрагмента кода, мы получаем следующий вывод:
Разделение инструкций
Как в C или Perl, PHP требует окончания инструкций точкой запятой в конце каждой инструкции. Закрывающий тег блока PHP-кода автоматически применяет точку с запятой; т.е. нет необходимости ставить точку с запятой в конце последней строки блока с PHP-кодом. Закрывающий тег блока "поглотит" немедленно следующий за ним переход на новую строку, если таковой будет обнаружен.
Замечание: закрывающий тег PHP-блока в конце файла не является обязательным, и в некоторых случаях его опускание довольно полезно, например, при использовании include или require, так, что нежелательные пробелы не останутся в конце файла и вы все еще сможете добавить http-заголовки после подключения к ответу сервера. Это также удобно при использовании буферизации вывода, где также нежелательно иметь пробелы в конце частей ответа, сгенерированного подключаемыми файлами.
Синтаксис и теги PHP
В php можно использовать четыре разные пары открывающих и закрывающих тегов. Вот список тегов.
- Синтаксис по умолчанию
- Короткие открытые теги
- Теги HTML-скрипта
- Теги стиля ASP
Синтаксис по умолчанию
Синтаксис по умолчанию начинается с «<? Php» и заканчивается «?>».
Пример:
Короткие открытые теги
Короткие теги начинаются с «<?» и заканчивается на «?>». Короткие теги стиля доступны только в том случае, если они включены в конфигурационном файле php.ini на серверах.
Пример:
Теги HTML-скрипта
Теги HTML-скрипта выглядят так:
У некоторых редакторов, таких как редактор Front Page, есть собственная проблема, связанная с аварийной ситуацией, и указанный скрипт эффективен для ее решения.
Теги стиля ASP
Теги стиля ASP начинаются с «<%» и заканчиваются на «%>». Теги стиля ASP доступны только в том случае, если они включены в конфигурационном файле php.ini на серверах.
Пример:
Примечание: приведенные выше два тега и примеры приведены только для справки, но больше не используются на практике.
Разделение операторов PHP
В PHP операторы заканчиваются точкой с запятой (;), например C или Perl. Закрывающий тег блока кода PHP автоматически подразумевает точку с запятой, нет необходимости использовать точку с запятой, заканчивающую последнюю строку блока PHP.
Правила разделения операторов
- точка с запятой
- И / ИЛИ
- закрывающий тег PHP
Действительные коды
В приведенном выше примере присутствуют точка с запятой (;) и закрывающий тег PHP.
В приведенном выше примере после последней инструкции не ставится точка с запятой (;), но присутствует закрывающий тег PHP.
В приведенном выше примере в последней инструкции есть точка с запятой (;), но нет закрывающего тега PHP.
Чувствительность к регистру PHP
В PHP определяемые пользователем функции, классы, ключевые слова основного языка (например, if, else, while, echo и т. Д.) Не чувствительны к регистру. Поэтому три выражения echo в следующем примере равны.
Пример — 1
С другой стороны, все переменные чувствительны к регистру.
Рассмотрим следующий пример. Только первый оператор отображает значение в виде $ amount, потому что $ amount, $ AMOUNT, $ amoUNT — это три разные переменные.
Пример — 2
Нечувствительность к пробелам в PHP
В целом, пробелы не видны на экране, включая пробелы, символы табуляции и символы конца строки, то есть возврат каретки. В PHP пробелы не имеют значения при кодировании. Вы можете разбить один оператор строки на любое количество строк или количество отдельных операторов вместе в одной строке.
Следующие два примера одинаковы:
Пример:
Пример: предварительная нечувствительность к пробелам
Пример: нечувствительность к пробелам с табуляцией и пробелами
В следующем примере пробелы и табуляции используются в числовой операции, но в обоих случаях $ xyz возвращает одно и то же значение.
PHP: однострочные и многострочные комментарии
Однострочный комментарий
PHP поддерживает следующие два разных способа комментирования.
# Это однострочный комментарий.
// Это еще один способ однострочного комментария.
Пример:
Многострочные комментарии
PHP поддерживает 'C', стиль комментариев. Комментарий начинается с пары символов / * и заканчивается парой символов * /.
/ * Это тестирование с несколькими комментариями,
и эти строки будут игнорироваться
во время исполнения * /
Пример:
Многострочные комментарии не могут быть вложенными
Первый PHP-скрипт
Вот первый PHP-скрипт, который будет отображать «Hello World . » в веб-браузере.
Теги говорят веб-серверу обрабатывать все внутри тегов как PHP-код для запуска. Код очень прост. Он использует встроенную функцию PHP «echo» для отображения текста «Hello World . » на веб-странице. Все, что находится вне этих тегов, отправляется прямо в браузер.
Иллюстрированная презентация
Сочетание PHP и HTML
Синтаксис PHP применим только внутри тегов PHP.
PHP может быть встроен в HTML и размещен в любом месте документа.
Когда PHP встроен в документы HTML и PHP анализирует этот документ, он интерпретирует раздел, заключенный в открывающий тег (<? Php) и закрывающий тег (?>) PHP, и игнорирует остальные части документа.
PHP и HTML видны вместе в следующем примере.
Практика здесь онлайн:
Предыдущий: Установить WAMP
Далее: Переменные PHP