Why would one omit the close tag?
我一直在读,在文件末尾使用php close标记
Modern versions of PHP set the output_buffering flag in php.ini
If output buffering is enabled, you can set HTTP headers and cookies after outputting HTML because the returned code is not sent to the browser immediately.
每一本好的实践书和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修复程序),那么您可以忽略这个问题。否则,你将永远需要记住这个问题。
奖励:与这两个字符相关的几个gotchas(实际上是一个):
不使用php结束标记(
你不应该离开php结束标记的原因是因为它导致了php标记的不平衡,任何一个半脑子的程序员都可以记住不要添加额外的空白。
所以对于你的问题:
Is there another good reason to skip the ending php tag?
不,没有其他好的理由跳过结束的PHP标记。
我将以一些不干扰结束标记的参数结束:
人们总是能够犯错误,不管他们有多聪明。坚持减少可能的错误数量的做法是一个好主意。
PHP不是XML。PHP不需要遵守XML严格的标准,以保证良好的编写和功能。如果一个丢失的结束标记让你很烦恼,你可以使用一个结束标记,这不是一个在石头规则中设置的方法。
这是一个新手的编码风格建议,用意很好,并由手册建议。好的。
然而,避开
?> 只解决了一些已经发送的常见报头(原始输出、物料清单、通知等)及其后续问题。好的。php实际上包含了一些魔力,可以在
?> 结束令牌之后吃掉单个换行符。尽管这有着历史性的问题,并且使新来的人仍然容易受到不稳定的编辑的影响,而且在江户十一号(0)之后,在其他空白处毫不留情地摇摆不定。好的。在风格上,一些开发人员更喜欢将
和 ?> 视为sgml标记/xml处理指令,这意味着尾随的结束标记的平衡一致性。(顺便说一句,这对于依赖连接类很有用,包括通过文件自动加载来替代效率低下的文件。)好的。有点不寻常的是,打开的
被描述为phps shebang(并且对于binfmt_misc完全可行),从而验证了相应的结束标记的冗余性。好的。 传统的PHP语法指南强制执行
?> 和最近的(psr-2)同意省略之间存在明显的建议差异。(记录在案:Zend框架假定一个比另一个并不意味着它固有的优越性。人们错误地认为专家们被吸引到了笨拙的API的目标受众。好的。
SCMS和现代IDE提供了内置的解决方案,主要减轻了近距离的标签保护。好的。
禁止使用
常规?> close tag也称为
T_CLOSE_TAG ,即"close token"。好的。它包含了更多的化身,因为PHPS神奇的新品饮食:好的。
?>akbd(Unix linefeed)好的。
?>
akbd(回车,经典Mac)好的。?>
akbdakbd(cr/lf,on dos/win)好的。但是,PHP不支持Unicode Combo LineBreak neL(U+0085)。好的。
早期的PHP版本有IIRC编译INS限制了平台不可知性(FI甚至只是使用
> 作为关闭标记),这可能是关闭标记避免的历史渊源。好的。通常被忽略,但在php7删除它们之前,常规的xykb
开放令牌可以有效地与很少使用的xykb 作为奇数关闭令牌配对。好的。 "硬结束标记"甚至不是一个——只是用这个术语来比喻而已。但是,从概念和使用角度来看,
__halt_compiler 应被视为密切标志。好的。1
2__HALT_COMPILER();
?>它基本上让标记器放弃任何代码或纯HTML部分。特别是法老的残桩利用了这个,或者它与
?> 的冗余组合,如图所示。好的。同样,void
return; 在include脚本中也不经常被替换,从而使任何带有尾随空格的?> 无效。好的。然后有各种各样的软/人造的结束标记变体;不太知名的和seldomly使用的,但通常每个注释掉的标记:好的。
简单间距xykb
// ? > ,避免phps标记器检测。好的。或者用花哨的Unicode代替
// ﹖﹥ (U+FE56小问号,U+FE65小角括号),regexp可以掌握。好的。
这对PHP来说都毫无意义,但对于不了解或半了解的PHP外部工具包来说,这两种工具都有实际的用途。同样,
cat 连接的脚本出现在脑海中,产生的// ? > 连接将保留以前的文件分区。好的。
因此,有上下文相关但实际可行的替代方法来替代必须的结束标记省略。好的。
phptags tag tidier
https://fossil.include-once.org/phptags/Ok.
它通常可用于第三方代码的
phptags --warn --whitespace *.php
它还处理
它不是一个标签…
但如果你拥有它,你就有可能在它之后有空白。
如果您随后将其用作文档顶部的include,则可能会在尝试发送HTTP头之前插入空白(即内容),这是不允许的。
不让结束的
该文件对php有效(不是语法错误),正如@david dorward所说,它允许在
例如,
1 2 3 4 5 6 7 | <? header("Content-type: image/png"); $img = imagecreatetruecolor ( 10, 10); imagepng ( $img); ?> [space here] [break line here] |
不会有效。
但是
1 2 3 4 |
威尔。
这一次,你必须懒惰才能安全。
根据文档,如果结束标记位于文件末尾,则最好省略它,原因如下:
If a file is pure PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script.
PHP手册>语言参考>基本语法>PHP标记
嗯,有两种方法来看待它。
如果您相信第一个路由,那么所有PHP文件都需要结束标记。如果忽略它们,将创建一个无效的XML文件。再说一次,如果没有打开
如果您相信第二条路线,这将为两种类型的
- 仅包含代码的文件(例如库文件)
- 包含本机XML和代码的文件(例如模板文件)
基于此,仅代码文件可以在没有结束
但我知道你在想什么。你在想这有什么关系,你永远不会直接呈现一个PHP文件,所以谁在乎它是不是有效的XML。好吧,如果你正在设计一个模板,那就很重要了。如果它是有效的XML/HTML,普通的浏览器将不会显示PHP代码(它被视为注释)。因此,您可以模拟出模板,而无需在其中运行PHP代码…
我不是说这很重要。这只是一个观点,我不认为表达太频繁,所以有什么更好的地方来分享它…
就个人而言,我不会关闭库文件中的标记,但会关闭模板文件中的标记…我认为这是一个个人偏好(和编码准则)的基础上比任何困难…
嗯,我知道原因,但我不能说明:
For files that contain only PHP code, the closing tag (
?> ) is never
permitted. It is not required by PHP,
and omitting it prevents the
accidental injection of trailing white
space into the response.
来源:http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html
除了已经说过的所有内容之外,我还将加入另一个原因,那对于我们调试来说是一个巨大的痛苦。
Apache2.4.6和php 5.4,当关闭的
以下是Apache抛出的错误:
1 |
"是否还有另一个跳过结束php标记的好理由(头问题除外)?
在生成二进制输出、csv数据或其他非html输出时,不希望无意中输出无关的空白字符。
赞成的意见
- 与其他语言一样,关闭任何打开的标记是合乎逻辑的。不仅是x(ht)ml标签,还有花括号、括号…
- 对初学者来说不那么困惑。
欺骗
- 避免在结束标记后添加不经意的空白,因为它会破坏header()函数的行为…有些编辑器或ftp客户机/服务器也会自动更改文件结尾(至少是其默认配置)。
- php手册说结束标记是可选的,Zend甚至禁止它。
结论
我会说,支持省略标记的参数看起来更强大(header()+这是php/zend的"建议")。我承认在语法一致性方面,这不是我见过的最"漂亮"的解决方案,但是还有什么更好的呢?
由于我的问题被标记为这一个的副本,我认为可以出于某些需要,发布为什么不省略结束标记
- 完整的处理指令语法(
php源是有效的sgml文档,可以用sgml解析器进行解析和处理,而不会出现问题。如果有其他限制,它也可以是有效的XML/XHTML。
没有什么可以阻止您编写有效的XML/HTML/SGML代码。PHP文档知道这一点。Excerpt:
Note: Also note that if you are embedding PHP within XML or XHTML you will need to use the < ?php ?> tags to remain compliant with standards.
当然,php语法不是严格的sgml/xml/html,您创建的文档不是sgml/xml/html,就像您可以将html转换为xhtml以实现XML兼容或不兼容一样。
在某些时候,您可能希望连接源。如果通过省略关闭
?> 标记引入了不一致性,那么这就不像简单地执行cat source1.php source2.php 那么简单了。如果没有
?> ,就很难判断文档是留在php escape模式还是php ignore模式(pi tag)中(可能已打开或未打开)。如果您始终将文档保留在php忽略模式下,生活会更轻松。这就像处理格式良好的HTML文档,而不是处理带有未闭合、嵌套不良标记等的文档一样。 似乎有些像Dreamweaver这样的编辑可能会对pi保持打开状态有问题[1]。
有两种可能使用的PHP代码:
案例1。结束标记完全没用,在这种情况下,我只想看到1(一)个php open标记,没有(零)个结束标记。这是一个很好的实践,因为它使代码清晰,并将逻辑与表示分离。对于表示案例(2),有些人发现关闭所有标签(甚至是经过php处理的标签)是很自然的,这会导致混淆,因为php实际上有两个单独的用例,不应该混合使用:逻辑/微积分和表示
如果我正确理解了这个问题,它必须与输出缓冲以及这可能对结束/结束标记的影响有关。我不确定这是一个完全正确的问题。问题是,输出缓冲区并不意味着所有内容在发送到客户机之前都保存在内存中。这意味着有些内容是。
程序员可以有目的地刷新缓冲区或输出缓冲区,所以PHP中的输出缓冲区选项真的会改变结束标记对编码的影响吗?我会争辩说不是。
也许这就是为什么大多数答案都回到了个人风格和语法。