Я продолжаю читать, это плохая практика использовать закрывающий тег PHP ?>
в конце файла. Проблема заголовка кажется неактуальной в следующем контексте (и пока это единственный хороший аргумент):
Современные версии PHP устанавливают флаг output_buffering в php.ini. Если включена выходная буферизация, вы можете установить HTTP-заголовки и куки-файлы после вывода HTML-кода, поскольку возвращаемый код не отправляется в браузер немедленно.
Каждая книга хорошей практики и вики начинаются с этого «правила», но никто не приводит веских причин. Есть ли еще одна веская причина, чтобы пропустить конечный тег PHP?
php
security
http-headers
danidacar
источник
источник
?>
ленивым?Ответы:
Отправка заголовков раньше нормального курса может иметь далеко идущие последствия. Ниже приведены лишь некоторые из них, которые пришли мне в голову в данный момент:
Хотя в текущих версиях PHP может быть включена буферизация вывода, фактические рабочие серверы, на которых вы будете развертывать свой код, гораздо важнее, чем любые машины для разработки или тестирования. И они не всегда стремятся следовать последним тенденциям PHP сразу.
У вас могут быть головные боли из-за необъяснимой потери функциональности . Скажем, вы реализуете какой-то платежный шлюз и перенаправляете пользователя на определенный URL после успешного подтверждения платежным процессором. Если произойдет какая-либо ошибка PHP, даже предупреждение или окончание лишней строки, платеж может остаться необработанным, а пользователю все равно может показаться, что счет не выставлен. Это также одна из причин, по которой ненужное перенаправление является злом, и если перенаправление должно использоваться, оно должно использоваться с осторожностью.
Вы можете получить ошибки типа «Загрузка страницы отменена» в Internet Explorer, даже в самых последних версиях. Это связано с тем, что AJAX response / 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.источник
\?>(?s:.){0,10}\Z
Краткое объяснение: changeset.hr/blog/miscellaneous/catch-near-eof-with-regex?>
: например, он соответствует-и удалит-?> Hello
в<?php echo "test"; ?> Hello
. Мы хотели бы очистить только закрытые теги.[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
.?>
, что (как и любой вывод) приводит к отправке заголовков, как только они выводятся. Нет никаких «заголовков HTML» (кроме несвязанного<header>
тега HTML5 ).Причина, по которой вы должны не использовать закрывающий тег php (
?>
), заключается в том, что программист случайно не отправляет дополнительные символы новой строки.Причина, по которой вы не должны пропускать закрывающий тег php, заключается в том, что он вызывает дисбаланс в тегах php, и любой программист с полусмысленностью может помнить, что он не должен добавлять лишние пробелы.
Итак, на ваш вопрос:
Нет, нет другой веской причины пропускать конечные теги php.
Я закончу с некоторыми аргументами, чтобы не беспокоиться с закрывающим тегом:
Люди всегда могут делать ошибки, какими бы умными они ни были. Придерживаться практики, которая уменьшает количество возможных ошибок, - (ИМХО) хорошая идея.
PHP это не XML. PHP не должен придерживаться строгих стандартов XML, чтобы быть хорошо написанным и функциональным. Если отсутствующий закрывающий тег вас раздражает, вы можете использовать закрывающий тег, так или иначе, это не правило подстановки.
источник
Это рекомендация для новичков в стиле кодирования , из лучших побуждений и рекомендаций руководства .
Отказавшись
?>
однако решает только струйка из общих заголовков уже посланных причины (добытого, BOM , уведомления и т.д.) и их последующие проблемы.PHP на самом деле содержит некоторую магию, чтобы поглотить единичные разрывы строк после
?>
закрывающего токена. Хотя это имеет исторические проблемы и оставляет новичков по-прежнему восприимчивыми к нестабильным редакторам и неосознанно перетасовывает их в другие пробелы?>
.Стилистически некоторые разработчики предпочитают рассматривать
<?php
и?>
как теги SGML / инструкции по обработке XML, подразумевая согласованность баланса в трейлинг-маркере. (Что, кстати, полезно для включения в класс, связанный с зависимостями, чтобы вытеснить неэффективную автозагрузку файлов.)Несколько необычно открытие
<?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
однако, должны быть признаны как близкий знак.Который в основном имеет токенайзер, отбрасывающий любой код или простые разделы HTML после этого. В частности, заглушки PHAR используют это или его избыточную комбинацию с
?>
изображенным изображением.Точно так же делает недействительная
return;
нечасто подставит в сценарий включает в себя, оказании любого?>
с конечными пробелами неэффективны.Тогда есть все виды мягких / искусственных вариаций меток закрытия; менее известные и редко используемые, но обычно по закомментированным токенам:
Простой интервал,
// ? >
чтобы избежать обнаружения токенайзером PHP.Или причудливые замены Юникода
// ﹖﹥
(U + FE56 МАЛЕНЬКИЙ ВОПРОСНИК, U + FE65 МАЛЕНЬКИЙ УГОЛ БРЕКЕТА), которые может понять регулярное выражение.Оба ничего не значат для PHP , но могут иметь практическое применение для неосознаваемых PHP или полуосознающих внешних инструментариев. На
cat
ум приходят вновь присоединенные скрипты, в результате чего// ? > <?php
конкатенации, которые встраивают-сохраняют прежнее разделение файла.Таким образом, существуют контекстно-зависимые, но практические альтернативы упущению обязательного закрывающего тега.
Ручная няня
?>
близких меток не очень современна в любом случае. Для этого всегда были инструменты автоматизации (даже если это просто sed / awk или regex-oneliners). В частности:Которые обычно можно использовать для
--unclose
php-тегов для стороннего кода или, скорее, просто для устранения любых (и всех) реальных проблем с пробелами / спецификациями:phptags --warn --whitespace *.php
Он также обрабатывает
--long
преобразование тегов и т. Д. Для совместимости во время выполнения / конфигурации.источник
<?php if($var): ?>Hello World<?php endif; ?>
??? Мне искренне любопытно, поскольку это не упомянуто специально.Это не тег ...
Но если он у вас есть, вы рискуете получить пробел после него.
Если вы затем используете его в качестве включения в верхней части документа, вы можете в конечном итоге вставить пробел (то есть содержимое), прежде чем пытаться отправить заголовки HTTP ... что недопустимо.
источник
<?php $i = 1; ?>
затем file2.php:<?php include 'file1.php'; header('Location: http://www.google.com');?>
phpcs
чтобы убедиться, что закрывающий тег остается от каждого моего файла, а затем я не беспокоюсь о буферизации вывода :)Это довольно полезно, чтобы не допустить закрытия
?>
.Файл остается действительным для PHP (не является синтаксической ошибкой), и, как сказал @David Dorward, он позволяет избежать пробелов / переноса строки (всего, что может отправить заголовок в браузер) после
?>
.Например,
не будет действительным
Но
буду.
На этот раз вы должны быть ленивы, чтобы быть в безопасности .
источник
?>
. безопасность не может быть хорошим словом здесь. В любом случае, это ничего не исправляет (для меня это не плохой код, чтобы предотвратить вещи,echo
здесь был бы плохой код), но / и он все еще действует. Докажите, что я не прав в этом.?>
в конец файла только php. но вам когда-нибудь приходилось исправлять ошибки, вызванные конечными пробелами? Также не все серверы настроены одинаково, особенно когда вы переходите на другой хост, обнаружение этих ошибок занимает очень много времени. Если вы хотите положить,?>
просто сделайте это, если вы также добавите немного пробела и ваша команда должна отладить, чтобы быть готовымСогласно документам , предпочтительно не указывать закрывающий тег, если он находится в конце файла, по следующей причине:
Руководство по PHP> Справочник по языку> Основной синтаксис> Теги PHP
источник
Ну, я знаю причину, но я не могу показать это:
Источник: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html
источник
Ну, есть два способа взглянуть на это.
.php
расширением - это не что иное, как XML-файл, который просто обрабатывается для PHP-кода..php
расширениями МОГУТ быть действительными файлами XML, но они не должны быть такими.Если вы верите первому маршруту, тогда все PHP-файлы требуют закрытия конечных тегов. Чтобы пропустить их, создаст недопустимый файл XML. Опять же, без вступительного
<?xml version="1.0" charset="latin-1" ?>
объявления у вас все равно не будет действительного XML-файла ... Так что это не главная проблема ...Если вы верите второму маршруту, это открывает двери для двух типов
.php
файлов:Исходя из этого, файлы только с кодом могут заканчиваться без закрывающего
?>
тега. Но файлы XML-кода не могут заканчиваться без закрытия,?>
так как это сделает недействительным XML.Но я знаю, о чем ты думаешь. Вы думаете, что это имеет значение, вы никогда не собираетесь визуализировать PHP-файл напрямую, поэтому кого волнует, является ли он действительным XML. Ну, это имеет значение, если вы разрабатываете шаблон. Если это допустимый XML / HTML, обычный браузер просто не будет отображать код PHP (он рассматривается как комментарий). Таким образом, вы можете макетировать шаблон без необходимости запуска кода PHP внутри ...
Я не говорю, что это важно. Это просто мнение, которое я не вижу выраженным слишком часто, так что может быть лучше, чтобы поделиться этим ...
Лично я не закрываю теги в файлах библиотеки, но делаю это в файлах шаблонов ... Я думаю, что это личное предпочтение (и руководство по кодированию), основанное больше, чем что-либо сложное ...
источник
В дополнение ко всему, что уже было сказано, я добавлю еще одну причину, которая доставляла нам огромную боль при отладке.
В Apache 2.4.6 с PHP 5.4 фактически возникают ошибки сегментации на наших производственных машинах, когда за закрывающим
php
тегом есть свободное место . Я просто потратил впустую часы, пока, наконец, не сузил ошибку с помощью strace .Вот ошибка, которую выдает Apache:
источник
«Есть ли еще одна веская причина (кроме проблемы с заголовком) пропустить заключительный тег php?»
Вы не хотите непреднамеренно выводить посторонние символы пробела при генерации двоичного вывода, данных CSV или других выходных данных, отличных от HTML.
источник
Pros
Cons
Вывод
Я бы сказал, что аргументы в пользу пропуска тега выглядят сильнее (помогает избежать большой головной боли с header () + это «рекомендация» PHP / Zend). Я признаю, что это не самое «красивое» решение, которое я когда-либо видел с точки зрения согласованности синтаксиса, но что может быть лучше?
источник
Так как мой вопрос был помечен как дубликат этого, я думаю, что все в порядке, чтобы опубликовать, почему НЕ опускание закрывающего тега
?>
может быть по некоторым причинам желательным.<?php ... ?>
) исходный код PHP является действительным документом SGML, который может быть проанализирован и обработан без проблем с синтаксическим анализатором SGML. С дополнительными ограничениями это может быть также действительный XML / XHTML.Ничто не мешает вам писать действительный код XML / HTML / SGML. Документация 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. закрывающий тег совершенно бесполезен, также я хотел бы видеть только 1 (один) открытый тег php и NO (нулевой) закрывающий тег в таком случае. Это хорошая практика, поскольку она делает код чистым и отделяет логику от представления. Для случая представления (2.) некоторые обнаружили, что естественно закрыть все теги (даже обработанные PHP), что приводит к путанице, поскольку на самом деле PHP имеет два отдельных варианта использования, которые не должны смешиваться: логика / исчисление и презентация
источник