Почему опустить тег закрытия?

Я продолжаю читать, это плохая практика использовать закрывающий тег PHP ?> В конце файла. Проблема заголовка кажется несущественной в следующем контексте (и пока это единственный хороший аргумент):

Современные версии PHP устанавливают флаг output_buffering в php.ini. Если включена выходная буферизация, вы можете установить HTTP-заголовки и куки файлы после вывода HTML-кода, поскольку возвращаемый код не отправляется в браузер немедленно.

Каждая книга хорошей практики и вики начинаются с этого "правила", но никто не приводит веских причин. Есть ли еще одна веская причина, чтобы пропустить конечный тег PHP?

Ответ 1

Отправка заголовков раньше обычного курса может иметь далеко идущие последствия. Ниже приведены лишь некоторые из них, которые мне вспомнились в данный момент:

  1. Хотя текущие версии PHP могут иметь буферизацию вывода, фактические рабочие серверы, на которых вы будете развертывать свой код, гораздо важнее, чем любые машины для разработки или тестирования. И они не всегда стремятся следовать последним тенденциям PHP сразу.

  2. У вас могут быть головные боли из-за необъяснимой потери функциональности. Скажем, вы реализуете какой-то платежный шлюз и перенаправляете пользователя на определенный URL после успешного подтверждения платежным процессором. Если произойдет какая-либо ошибка PHP, даже предупреждение или окончание лишней строки, платеж может остаться необработанным, а пользователю все равно может показаться, что счет не выставлен. Это также одна из причин, по которой ненужное перенаправление является злым, и если оно используется, его следует использовать с осторожностью.

  3. Вы можете получить ошибки типа "Загрузка страницы отменена" в Internet Explorer, даже в самых последних версиях. Это связано с тем, что AJAX response/json include содержит что-то, чего он не должен содержать из-за лишних концов строк в некоторых файлах PHP, как я встречал несколько дней назад.

  4. Если у вас есть загрузка файлов в вашем приложении, они тоже могут сломаться из-за этого. И вы можете не заметить этого даже спустя годы, поскольку специфическая привычка загрузки зависит от сервера, браузера, типа и содержимого файла (и, возможно, некоторых других факторов, с которыми я не хочу утомлять вас).

  5. Наконец, многие PHP-фреймворки, включая Symfony, Zend и Laravel (об этом нет упоминания в рекомендациях по кодированию, но это следует их примеру) и Стандарт PSR-2 (пункт 2.2) требует пропуска закрывающего тега. Само руководство по PHP (1,2), Wordpress, Drupal и многие другие программы PHP, я полагаю, советую сделать это. Если вы просто соблюдаете стандарт (и настраиваете для своего кода PHP-CS-Fixer), вы можете забыть об этом. В противном случае вам всегда нужно помнить об этом.

Бонус: несколько ошибок (на самом деле один), связанных с этими двумя персонажами:

  1. Даже некоторые известные библиотеки могут содержать лишние окончания строк после ?>. Например, Smarty, даже самые последние версии веток 2. * и 3. * имеют это. Так что, как всегда, следите за сторонним кодом. Бонус в бонусе: регулярное выражение для удаления ненужных окончаний PHP: замените (\s*\?>\s*)$ пустым текстом во всех файлах, которые содержат код PHP.

Ответ 2

Причина, по которой вы должны оставить закрывающий тег php (?>), заключается в том, что программист не случайно отправляет дополнительные символы новой строки.

Причина, по которой вам не следует оставлять тег закрытия php, заключается в том, что она вызывает дисбаланс в тегах php, и любой программист с половиной ума может не забыть добавлять лишнее пространство.

Итак, для вашего вопроса:

Есть ли еще одна веская причина пропустить конечный тег php?

Нет, нет другой веской причины пропустить конечные теги php.

Я закончу несколько аргументов, чтобы не беспокоить закрывающий тег:

  • Люди всегда могут ошибаться, какими бы умными они ни были. Придерживаясь практики, которая уменьшает количество возможных ошибок, есть хорошая идея. (IMHO) хорошая идея.

  • PHP не является XML. PHP не должен придерживаться строгих стандартов XML, чтобы быть хорошо написанными и функциональными. Если недопустимый закрывающий тег вас раздражает, вы можете использовать закрывающий тег, это не правило в виде кавычки так или иначе.

Ответ 3

Это рекомендация стиля кодирования новичка, из лучших побуждений и советов руководства.

  • Eschewing ?> Однако решает лишь небольшую часть общих заголовков, уже отправленных причин (необработанный вывод, спецификация, уведомления и т.д.) И их последующих проблем.

  • PHP на самом деле содержит некоторое волшебство съедать одиночные разрывы строк после ?> Закрывающего токена. Хотя это имеет исторические проблемы и оставляет новичков по-прежнему восприимчивыми к нестабильным редакторам и неосознанно перетасовывает их в другие пробелы после ?>.

  • Стилистически некоторые разработчики предпочитают рассматривать <?php и ?> Как теги SGML/инструкции по обработке XML, что подразумевает согласованность баланса в трейлинг-маркере. (Что, кстати, полезно для включения в класс, связанный с зависимостями, чтобы вытеснить неэффективную автозагрузку файлов.)

  • Несколько необычно открытие <?php характеризуется как PHP-шебанг (и полностью выполнимый для binfmt_misc), тем самым проверяя избыточность соответствующего закрывающего тега.

  • Существует очевидное несоответствие между классическими руководствами по синтаксису PHP, предписывающими ?>\n и более поздними (PSR-2), согласующимися с упущением.
    (Для справки: Zend Framework, постулирующий одно над другим, не подразумевает присущего ему превосходства. Это ошибочное мнение, что эксперты были привлечены к целевой аудитории громоздких API).

  • SCM и современные IDE предоставляют встроенные решения, в основном облегчающие работу с близкими тегами.

Отказ от любого использования тега ?> Close просто задерживает объяснение базового поведения PHP и семантики языка, чтобы избежать нечастых проблем. Это все еще практично для совместной разработки программного обеспечения из-за различий в квалификации участников.

Закрыть варианты тегов

  • Регулярный ? > закрывающий тег также известен как T_CLOSE_TAG, или таким образом "закрыть маркер".

  • Он включает в себя еще несколько воплощений из-за того, что PHP использует волшебную новую строку:

    ? > \n (перевод строки Unix)

    ? > \r (возврат каретки, классические MAC)

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

    PHP не поддерживает перевод строки Unicode NEL (U + 0085).

    Ранние версии PHP имели компиляции IIRC, которые несколько ограничивали агностицизм платформы (FI даже просто использовал > качестве маркера закрытия), что является вероятным историческим источником избегания закрытия тегов.

  • Часто пропускается, но до тех пор, пока PHP7 не удалит их, обычный открывающий токен <?php может быть корректно связан с редко используемым </script> в качестве нечетного закрывающего токена.

  • " Жесткий закрывающий тег " - даже не один - просто придумал этот термин для аналогии. __halt_compiler использования __halt_compiler должен быть распознан как близкий токен.

    __HALT_COMPILER();
    ?>
    

    Который в основном имеет токенайзер, отбрасывающий любой код или простые разделы HTML после этого. В частности, заглушки PHAR используют это или его избыточную комбинацию с ?> Как показано.

  • Аналогично return; пустота return; нередко заменять в сценариях включения, переводя любые ?> с конечным пробелом в неэффективные.

  • Тогда есть все виды мягких/искусственных вариаций меток закрытия; менее известные и редко используемые, но обычно по закомментированным токенам:

    • Простой интервал // ? >, чтобы избежать обнаружения токенайзером PHP.

    • Или причудливые Unicode заменяет // ﹖﹥ (МАЛЕНЬКИЙ ВОПРОС U + FE56, U + FE65 КРОНШТЕЙН МАЛОГО УГЛА), который может понять регулярное выражение.

    Оба ничего не значат для PHP, но могут иметь практическое применение для неосознаваемых PHP или полуосознающих внешних инструментариев. Снова в голову приходят сценарии cat -joined, в результате чего //? > <?php //? > <?php конкатенации, которые встраивают - сохраняют прежнее разделение файла.

Таким образом, существуют контекстно-зависимые, но практические альтернативы упущению обязательного закрывающего тега.

Ручная няня тегов ?> Close не очень современна в любом случае. Для этого всегда были инструменты автоматизации (даже если это просто sed/awk или regex-oneliners). Особенно:

тег phptags более аккуратный
wnAS9.gif
https://fossil.include-once.org/phptags/

Как правило, они могут использоваться для --unclose php-тегов для стороннего кода или, скорее, просто для устранения любых (и всех) реальных проблем с пробелами/спецификациями:

  • phptags --warn --whitespace *.php

Он также выполняет --long тегов --long и т.д. Для совместимости во время выполнения/конфигурации.

Ответ 4

Это не тег...

Но если у вас есть это, вы рискуете иметь пробел после него.

Если вы затем используете его как включенный в верхней части документа, вы можете вставить в него пустое пространство (т.е. контент), прежде чем пытаться отправить HTTP-заголовки... что не разрешено.

Ответ 5

Очень полезно не закрывать ?>.

Файл остается действительным для PHP (не синтаксическая ошибка), а как @David Dorward говорит, что он позволяет избежать наличия пробела/прерывания (все, что может отправить заголовок в браузер) после ?>.

Например,

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

не будет действительным.

Но

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10 );
    imagepng ( $img );

будет.

На этот раз вы должны быть ленивы, чтобы быть в безопасности.

Ответ 6

Согласно документации, предпочтительно пропустить закрывающий тег, если он находится в конце файла, по следующей причине:

Если файл представляет собой чистый код PHP, предпочтительно пропустить закрывающий тег PHP в конце файла. Это предотвращает случайный пробел или добавление новых строк после закрывающего тега PHP, что может вызвать нежелательные эффекты, поскольку PHP начнет буферизацию вывода, когда программист не намерен отправлять какие-либо выходные данные в этот момент в сценарии.

Руководство по PHP> Справочник по языку> Основной синтаксис> Теги PHP

Ответ 7

Ну, есть два способа взглянуть на него.

  • PHP-код - это не что иное, как набор инструкции по обработке XML, и поэтому любой файл с расширением .php является не более чем XML файл, который так просто анализируется для кода PHP.
  • PHP просто так делится форматом инструкции обработки XML для его открывающих и закрывающих тегов. Исходя из этого, файлы с расширениями .php МОГУТ быть действительными файлами XML, но они не обязательно должны быть.

Если вы верите в первый маршрут, то для всех файлов PHP требуются закрывающие теги конца. Чтобы опустить их, вы создадите недопустимый XML файл. Опять же, без объявления открытия <?xml version="1.0" charset="latin-1" ?>, вы все равно не будете иметь действительный XML файл... Так что это не главная проблема...

Если вы считаете, что второй маршрут открывает дверь для двух типов файлов .php:

  • Файлы, содержащие только код (например, файлы библиотеки)
  • Файлы, содержащие собственный XML, а также код (например, файлы шаблонов)

Исходя из этого, файлы с кодом только для завершения, без закрывающего тега ?>. Но файлы XML-кода заканчиваются без закрытия ?>, поскольку это приведет к аннулированию XML.

Но я знаю, о чем вы думаете. Вы думаете, что это имеет значение, вы никогда не будете делать PHP файл напрямую, так что кому это нужно, если он действительный XML. Ну, это имеет значение, если вы разрабатываете шаблон. Если это действительно XML/HTML, обычный браузер просто не отобразит PHP-код (он рассматривается как комментарий). Таким образом, вы можете издеваться над шаблоном без необходимости запуска PHP-кода внутри...

Я не говорю, что это важно. Это просто мнение, которое я не вижу слишком часто, поэтому какое лучшее место для его распространения...

Лично я не закрываю теги в библиотечных файлах, но делаю в файлах шаблонов... Я думаю, что это личное предпочтение (и руководство по кодированию) основано больше всего на чем-то...

Ответ 8

Ну, я знаю причину, но я не могу ее показать:

Для файлов, содержащих только PHP-код, закрывающий тег (?>) никогда разрешенный. PHP не требуется, и его исключение предотвращает случайное впрыскивание заднего белого цвета пространство в ответ.

Источник: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html

Ответ 9

В дополнение ко всему, что уже было сказано, я собираюсь добавить еще одну причину, которая была огромной болью для нас, чтобы отлаживать.

Apache 2.4.6 с PHP 5.4 действительно ошибки сегментации на наших производственных машинах, когда пустое место за закрывающим тегом php. Я просто потратил несколько часов, пока я, наконец, не сузил ошибку с помощью strace.

Вот ошибка, которую генерирует Apache:

[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)

Ответ 10

"Есть ли еще одна веская причина (кроме проблемы с заголовком), чтобы пропустить конечный тег php?"

Вы не хотите непреднамеренно выводить посторонние символы пробела при генерации двоичного вывода, CSV или другие не-HTML-данные.

Ответ 11

Pros

Против

Заключение

Я бы сказал, что аргументы в пользу исключения тега выглядят сильнее (помогает избежать большой головной боли с header() + это рекомендация PHP/Zend "). Я признаю, что это не самое" прекрасное" решение, которое я когда-либо видел с точки зрения согласованности синтаксиса, но что может быть лучше?

Ответ 12

Поскольку мой вопрос был отмечен как дубликат этого, я думаю, что это O.K. для публикации, почему НЕ опускание закрывающего тега ?> может быть по каким-либо причинам.

  • С полным инструкцией по обработке Синтаксис (<?php ... ?>) PHP-источник - это действительный документ SGML, который может быть проанализирован и обработан без проблем с синтаксическим анализатором SGML. С дополнительными ограничениями он может быть действительным и XML/XHTML.

Ничто не мешает вам писать правильный код XML/HTML/SGML. документация по PHP знает об этом. Выдержки:

Примечание. Также обратите внимание, что если вы внедряете PHP в XML или XHTML, вам нужно будет использовать <? php? > , чтобы оставаться совместимыми со стандартами.

Конечно, синтаксис PHP не является строгим SGML/XML/HTML, и вы создаете документ, который не является SGML/XML/HTML, так же, как вы можете превратить HTML в XHTML в соответствие с XML или нет.

  • В какой-то момент вам может понадобиться конкатенация источников. Это будет не так просто, как просто сделать cat source1.php source2.php, если у вас есть несогласованность, введенная путем исключения закрывающих тегов ?>.

  • Без ?> сложнее сказать, был ли документ оставлен в режиме эвакуации PHP или в режиме игнорирования PHP (возможно, был открыт IP-адрес <?php или нет). Жизнь проще, если вы постоянно оставляете свои документы в режиме игнорирования PHP. Это похоже на работу с хорошо отформатированными HTML-документами по сравнению с документами с незакрытыми, плохо вложенными тегами и т.д.

  • Кажется, что некоторые редакторы, такие как Dreamweaver, могут иметь проблемы с PI, оставленные открытыми [1].

Ответ 13

Если я правильно понимаю вопрос, это связано с выходной буферизацией и влиянием, которое это может иметь на теги закрытия/окончания. Я не уверен, что это вполне правильный вопрос. Проблема заключается в том, что выходной буфер не означает, что весь контент хранится в памяти перед отправкой его клиенту. Это означает, что часть содержимого.

Программист может запрограммировать сброс буфера или выходного буфера, поэтому опция вывода буфера в PHP действительно влияет на то, как закрывающий тег влияет на кодирование? Я бы сказал, что это не так.

И, возможно, именно поэтому большинство ответов вернулись к личным стилям и синтаксису.

Ответ 14

Существует 2 возможных варианта использования php-кода:

  • PHP-код, такой как определение класса или определение функции
  • Использовать PHP как язык шаблонов (т.е. в представлениях)

в случае 1. закрывающий тег полностью не полезен, также я хотел бы увидеть только один (один) открытый тег php и замыкающий тег NO (zero) в таком случае. Это хорошая практика, поскольку он делает код чистым и отделяет логику от презентации. В случае с презентацией (2.) некоторые из них обнаруживают, что естественно закрыть теги (даже обработанные PHP), что приводит к путанице, поскольку PHP имеет фактически 2 отдельных варианта использования, которые не следует смешивать: логика/исчисление и презентация