Я продолжаю читать, что плохо использовать практику тега PHP close ?>
В конце файла. Проблема заголовка кажется несущественной в следующем контексте (и это единственный хороший аргумент до сих пор):
Современные версии PHP устанавливают флаг output_buffering в php.ini. Если буферизация вывода включена, вы можете установить заголовки HTTP и файлы cookie после вывода html, потому что возвращенный код не сразу отправляется в браузер.
- Установка таймаута Curl в PHP
- laravel - получить параметры из запроса http
- PHP cURL: HTTP-заголовки показывают 302 и файлы cookie, файлы cookie сохраняются и отправляются, появляются одни и те же заголовки?
- Является ли моя реализация HTTP Conditional Ответы на PHP в порядке?
- Может ли PHP-скрипт обмануть браузер, считая, что HTTP-запрос завершен?
Каждая книга хорошей практики и wiki начинается с этого «правила», но никто не дает веских оснований. Есть ли еще одна веская причина пропустить окончание php-тега?
Хотя я не могу вспомнить другую причину, отправка заголовков раньше обычного курса может иметь далеко идущие последствия. Ниже приведены лишь некоторые из них, которые пришли мне в голову:
Хотя текущие выпуски PHP могут иметь выходную буферизацию, фактические серверы, на которых вы будете развертывать свой код, гораздо важнее любых машин разработки или тестирования. И они не всегда склонны следовать последним тенденциям PHP сразу.
У вас могут быть головные боли по поводу необъяснимой потери функциональности . Скажем, вы реализуете какой-то платежный шлюз и перенаправляете пользователя на определенный URL после успешного подтверждения платежным процессором. Если произойдет некоторая ошибка PHP, даже предупреждение или избыточное завершение строки, платеж может остаться необработанным, и пользователь может по-прежнему казаться неисполненным. Это также одна из причин того, что ненужное перенаправление является злым, и если перенаправление должно использоваться, его следует использовать с осторожностью.
В браузере Internet Explorer могут возникать ошибки «Загрузка страницы», даже в самых последних версиях. Это связано с тем, что ответ AJAX / json содержит то, что он не должен содержать, из-за избыточных окончаний строк в некоторых файлах PHP, так же, как я встречался несколько дней назад.
Из-за этого у вас могут быть загружены файлы в вашем приложении. И вы можете этого не заметить, даже после нескольких лет, поскольку конкретная привычка к загрузке зависит от сервера, браузера, типа и содержимого файла (и, возможно, некоторых других факторов, которые я не хочу вас утомлять) ,
Наконец, многие фреймворки PHP, в том числе Symfony , Zend и Laravel (об этом не упоминается в руководстве по кодированию, но оно следует за костюмом), а стандарт PSR-2 (пункт 2.2) требует пропуска закрывающего тега. PHP-руководство ( 1 , 2 ), WordPress , Drupal и многие другие PHP-программы, я думаю, советую сделать это. Если вы просто привыкли следовать стандарту (и настраивать PHP-CS-Fixer для своего кода), вы можете забыть проблему. В противном случае вам всегда нужно держать проблему в своем уме.
Бонус: несколько gotchas (фактически в настоящее время один), связанных с этими двумя символами:
?>
. Примером является Smarty, даже самые последние версии обеих ветвей 2. * и 3. * имеют это. Поэтому, как всегда, смотрите на сторонний код . Бонус в бонусе: регулярное выражение для удаления ненужных завершений PHP: замените (\s*\?>\s*)$
пустым текстом во всех файлах, содержащих PHP-код. Причина, по которой вам следует оставить закрывающий тег php ( ?>
), Заключается в том, что программист не случайно отправляет лишние символы новой строки.
Причина, по которой вам не следует оставлять тег закрытия php, заключается в том, что она вызывает дисбаланс в тегах php, и любой программист с половиной ума может не забыть добавлять лишнее пространство.
Так что для вашего вопроса:
Есть ли еще одна веская причина пропустить окончание php-тега?
Нет, нет другой веской причины пропустить финальные теги php.
Я закончу с некоторыми аргументами, чтобы не беспокоиться с закрывающим тегом:
Люди всегда могут ошибаться, какими бы утонченными они ни были. Придерживаясь практики, которая уменьшает количество возможных ошибок, (ИМХО) хорошая идея.
PHP не является XML. PHP не должен придерживаться строгих стандартов XML, чтобы быть хорошо написанными и функциональными. Если недопустимый закрывающий тег вас раздражает, вам разрешено использовать закрывающий тег, это не правило, установленное в кадре, так или иначе.
Это рекомендация стиля кодирования новичков , благие намерения и рекомендации руководства .
Eschewing ?>
Однако решает только прокладку общих заголовков, уже отправленных причин (исходный вывод, спецификация , уведомления и т. Д.) И их последующие проблемы.
PHP на самом деле содержит некоторую магию, чтобы съесть одиночные разрывы строк после закрывающего токена ?>
. Хотя это имеет исторические проблемы и оставляет новичков по-прежнему восприимчивыми к шелушащимся редакторам и неосведомленно перетасовываются в другие пробелы после ?>
.
Стилистически некоторые разработчики предпочитают рассматривать <?php
и ?>
Как SGML-теги / инструкции обработки XML, подразумевая согласованность баланса конечного закрытого токена. (Какой из них, полезен для класса сопряжения зависимостей, включает в себя вытеснение неэффективной файловой автозагрузки).
Чаще всего открытие <?php
характеризуется как phs shebang (и полностью выполнимо для binfmt_misc ), тем самым подтверждая избыточность соответствующего тега close.
Существует очевидное несоответствие между классическими инструкциями синтаксиса PHP, которые определяют ?>\n
а более поздние (PSR-2) соглашаются на упущение.
(Для записи: Zend Framework, постулирующая один над другим, не подразумевает ее присущего превосходства. Это неправильное представление о том, что эксперты привлекались к / целевой аудитории громоздких API).
SCM и современные IDE предоставляют встроенные решения, в основном облегчающие тщательное наблюдение за тегами.
Отказ от использования тега ?>
Close просто задерживает объяснение базового поведения обработки PHP и семантики языка, чтобы избежать нерешенных проблем. Практически все равно для совместной разработки программного обеспечения из-за различий в квалификации участников.
Регулярно ? > close tag также известен как T_CLOSE_TAG
или, таким образом, «close token».
Он включает в себя еще несколько воплощений, из-за того, что магия новой строки PHP:
? > \ n (Unix linefeed)
? > \ r (возврат каретки, классические MAC)
? > \ r \ n (CR / LF, на DOS / Win)
Однако PHP не поддерживает Unicode combo linebreak NEL (U + 0085).
Ранние версии PHP имели несколько компиляций IIRC, ограничивающих платформу-агностицизм (FI даже просто используется >
как близкий маркер), что является вероятным историческим происхождением закрытия тегов.
Часто игнорируется, но до тех пор, пока PHP7 не удалит их , обычный токен открытия <?php
может быть справедливо сопряжен с редко используемым </script>
как нечетным закрывающим токеном .
« Трудный тег тега » даже не один – просто сделал этот термин для аналогии. Однако __halt_compiler
должен распознаваться как близкий токен.
__HALT_COMPILER(); ?>
В основном в этом случае токенизатор отбрасывает любой код или обычные HTML-разделы. В частности, PHAR-заглушки используют это или его избыточную комбинацию с ?>
Как показано.
Также return;
пустота return;
редко заменяют включенные скрипты, рендеринг любых ?>
с завершающим пробелом неэффективен.
Тогда есть все виды мягких / искусственных тегов; менее известные и редко используемые, но обычно за пропущенные токены:
Простой интервал // ? >
// ? >
для предотвращения обнаружения с помощью токенизатора PHP.
Или причудливые заменители Unicode // ﹖﹥
(U + FE56 SMALL QUESTION MARK, U + FE65 SMALL ANGLE BRACKET), которые может использовать регулярное выражение.
Оба ничего не значат для PHP , но могут иметь практическое применение для PHP-неосведомленных или полусознательных внешних наборов инструментов. Снова появляются сценарии, связанные с кодами, с результатом // ? > <?php
// ? > <?php
которые inline-сохранить прежнее разделение файлов.
Таким образом, существуют контекстно-зависимые, но практические альтернативы императивному закрытию тегов без тегов.
Ручная няня ?>
Теги тегов не очень современны в любом случае. Для этого всегда были инструменты автоматизации (даже если только sed / awk или regex-oneliners). В частности:
Значок тегов phptags
https://fossil.include-once.org/phptags/
Как правило, можно использовать для --unclose
php-тегов для стороннего кода или, скорее, просто исправить любые (и все) фактические проблемы с пробелами / спецификациями:
phptags --warn --whitespace *.php
Он также обрабатывает – --long
преобразование тегов и т. Д. Для совместимости во время выполнения / конфигурации.
Это не тег …
Но если у вас есть это, вы рискуете иметь пробел после него.
Если вы затем используете его как включенный в верхней части документа, вы можете вставить в него пустое пространство (то есть контент), прежде чем пытаться отправить HTTP-заголовки … которые не разрешены.
Очень полезно не закрывать ?>
.
Файл остается действительным для 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 );
будем.
На этот раз вы должны быть ленивы, чтобы быть в безопасности .
Ну, есть два способа взглянуть на это.
.php
представляет собой не что иное, как XML-файл, который так просто анализируется на PHP-код. .php
МОГУТ быть действительными файлами XML, но они не обязательно должны быть. Если вы считаете, что первый маршрут, то все файлы PHP требуют закрытия тегов конца. Чтобы опустить их, вы создадите недопустимый XML-файл. Опять же, без объявления открытия <?xml version="1.0" charset="latin-1" ?>
, Вы все равно не будете иметь действительный файл XML … Так что это не главная проблема …
Если вы считаете второй маршрут, который открывает дверь для двух типов файлов .php
:
Исходя из этого, файлы только для кода в порядке заканчиваются без закрывающего тега ?>
. Но файлы XML-кода не подходят для завершения без закрытия ?>
Поскольку это приведет к аннулированию XML.
Но я знаю, о чем вы думаете. Вы думаете, что это имеет значение, вы никогда не будете делать PHP-файл напрямую, поэтому кто заботится о том, является ли он действительным XML. Ну, это имеет значение, если вы разрабатываете шаблон. Если это действительный XML / HTML, обычный браузер просто не отобразит PHP-код (это рассматривается как комментарий). Таким образом, вы можете издеваться над шаблоном без необходимости запуска PHP-кода внутри …
Я не говорю, что это важно. Это просто мнение, которое я не вижу слишком часто, поэтому какое лучшее место для его распространения …
Лично я не закрываю теги в библиотечных файлах, но делаю в файлах шаблонов … Я думаю, что это личное предпочтение (и руководство по кодированию) основано больше всего на свете …
В соответствии с документами предпочтительнее опустить закрывающий тег, если он находится в конце файла по следующей причине:
Если файл является чистым PHP-кодом, желательно опустить закрывающий тег PHP в конце файла. Это предотвращает случайные пробелы или новые строки, добавляемые после тега закрытия PHP, что может вызвать нежелательные эффекты, потому что PHP начнет буферизацию вывода, когда программист не хочет отправлять какой-либо вывод в этой точке скрипта.
– http://php.net/manual/en/language.basic-syntax.phptags.php
Ну, я знаю причину, но я не могу показать это:
Для файлов, содержащих только код PHP, закрывающий тег (
?>
) Никогда не разрешается. Он не требуется PHP, и его исключение предотвращает случайное впрыскивание пробега в пробе.
Источник: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html
В дополнение ко всему, что уже было сказано, я собираюсь добавить еще одну причину, которая была огромной болью для нас, чтобы отлаживать.
Apache 2.4.6 с PHP 5.4 действительно является ошибкой сегментации на наших производственных машинах, когда за закрывающим тегом php
есть пустое пространство. Я просто потратил несколько часов, пока я, наконец, не сузил ошибку с помощью strace .
Вот ошибка, которую Apache выбрасывает:
[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
Я бы сказал, что аргументы в пользу исключения тега выглядят сильнее (помогает избежать большой головной боли с заголовком () + это рекомендация PHP / Zend "). Я признаю, что это не самое «прекрасное» решение, которое я когда-либо видел с точки зрения согласованности синтаксиса, но что может быть лучше?
«Есть еще одна веская причина (кроме проблемы с заголовком), чтобы пропустить конечный тег php?»
Вы не хотите непреднамеренно выводить посторонние символы пробела при создании двоичного вывода, CSV- данных или других не-HTML-выходных данных.
Поскольку мой вопрос был отмечен как дубликат этого, я думаю, что это нормально, чтобы опубликовать сообщение, почему НЕ пропускать закрывающий тег ?>
Может быть по каким-то причинам желаемым.
<?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 (возможно, был открыт PI-тег <?php
или нет). Жизнь проще, если вы постоянно оставляете свои документы в режиме игнорирования PHP. Это похоже на работу с хорошо отформатированными HTML-документами по сравнению с документами с незакрытыми, плохо вложенными тегами и т. Д.
Кажется, что некоторые редакторы, такие как Dreamweaver, могут иметь проблемы с открытием PI [1] .
Если я правильно понял вопрос, это связано с выходной буферизацией и влиянием, которое это может иметь на теги закрытия / окончания. Я не уверен, что это вполне правильный вопрос. Проблема заключается в том, что выходной буфер не означает, что весь контент хранится в памяти перед отправкой его клиенту. Это означает, что часть контента есть.
Программист может запрограммировать сброс буфера или выходного буфера, поэтому опция выходного буфера в PHP действительно влияет на то, как закрывающий тег влияет на кодирование? Я бы сказал, что это не так.
И, возможно, именно поэтому большинство ответов вернулись к личному стилю и синтаксису.
Существует 2 возможных варианта использования php-кода:
в случае 1. закрывающий тег полностью не полезен, также я хотел бы увидеть только один (один) открытый тег php и NO (ноль) закрывающий тег в таком случае. Это хорошая практика, поскольку он делает код чистым и отделяет логику от презентации. В случае с презентацией (2.) некоторые из них обнаруживают, что естественно закрыть теги (даже обработанные PHP), что приводит к путанице, поскольку PHP имеет фактически 2 отдельных варианта использования, которые не следует смешивать: логика / исчисление и презентация