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

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

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

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

14 ответов


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

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

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

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

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

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

бонус: несколько gotchas (фактически в настоящее время один), связанный с этими 2 символами:

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

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

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

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

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

нет другое хорошая причина пропустить окончательные теги php.

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

  1. люди всегда способны совершать ошибки, независимо от того, насколько они умны. Придерживаться практики, которая уменьшает количество возможных ошибок, - это (ИМХО) хорошая идея.

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


это рекомендация стиля кодирования новичка, благими намерениями и советами инструкция.

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

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

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

  • несколько необычно открывающим тегом <?php характеризуется как PHPs shebang (и полностью выполнимо per binfmt_misc), тем самым проверяя резервирование соответствующего закрывающего тега.

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

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

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

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

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

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

    ?> \n (Unix linefeed)

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

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

    PHP не поддерживает Unicode комбинированный разрыв строки Нель (U+0085) однако.

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

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

  • в "тяжело закрыть тег


Это не тег...

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

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


это довольно полезно, чтобы не позволить закрытие ?> in.

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

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


Ну, есть два способа смотреть на это.

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

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

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

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

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


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

для файлов, содержащих только 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?"

вы не хотите ненароком выходной посторонние символы whitepace при создании двоичного выхода, CSV-файла data, или другой выход не-HTML.


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

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

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

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

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

  • в какой-то point вы можете объединить источники. Это будет не так просто, как просто делать cat source1.php source2.php Если у вас есть несоответствие введено, опустив закрытие ?> теги.

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

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


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

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

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


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

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

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