"如果你的文件中只有 php 代码,那么最好省略结束括号标记"是什么意思?

2015-08-01 13:52:57 +08:00
 qinglangee

我正在学习世界上最好的语言, 教程上有句话看不太明白.
教程在这 http://learnxinyminutes.com/docs/zh-cn/php-cn/ , 就在第二行

"如果你的文件中只有php代码,那么最好省略结束括号标记"这句话是什么意思?

为什么要省略结束括号. 意思是php文件内容要这样?
<?php
echo 123

没有结束感觉很奇怪, 还是最佳实践, 试了下确实可以执行.

英文版 "<?php" 与中文版 "<?php ? >"稍有出入 . 这句话跟这个有没有关系?

PHP code must be enclosed with <?php tags
PHP必须被包围于 <?php ? > 之中

5438 次点击
所在节点    PHP
21 条回复
tanteng
2015-08-01 13:55:03 +08:00
不要奇怪,这是很正常的写法,一次纯php文件只需要<?php 开头,这是为了防止很多时候require进来的php文件末尾包含特殊字符导致问题,你只需要知道这样做是标准的做法就行了。
qinglangee
2015-08-01 14:07:55 +08:00
@tanteng 这哪里正常了, 只能说解析器做的奇怪,所以代码也行写得奇怪. 不过vim编辑时删除到最后确实是方便了一点
raincious
2015-08-01 14:13:32 +08:00
第一行和第二行都是事实。只是表述可能不太清楚。

如果你的PHP文件里都是代码,没有输出的不分,比如:

文件里只有:
<?php

function add($a, $b) {
return $a + $b;
}

这时末尾的 ?> 是可以(也是应该被)省略的。

然而当PHP被用作模板输出的时候(比如当作“经典”用法使用的时候),比如:

<!doctype html>
<html>
<title><?php echo('My title'); ?></title>
......

的时候,开始和结尾的定界符都是必须的,否则解析器就没办法正确找到代码的结尾。

这两个例子里,上面一个对应的是:
“如果你的文件中只有php代码,那么最好省略结束括号标记”

下面一个对应的是:
“PHP必须被包围于 <?php ? > 之中”

至于原因,楼主试一下建立一个文件a.php,内容:

<?php

function add($a, $b) {
return $a + $b;
}

?>
Hello world

然后建立一个b.php,在执行里面require('a.php'),应该就明白了。
raincious
2015-08-01 14:14:18 +08:00
- 如果你的PHP文件里都是代码,没有输出的不分,比如:
+ 如果你的PHP文件里都是代码,没有输出的*部分*,比如:
SoloCompany
2015-08-01 14:42:12 +08:00
这样是最佳实践有什么好奇怪的吗,因为对写代码的人而言更方便,少两个字符,而且添加代码更容易

另一个对比例子就是 java 的数组定义和 js 的数组以及 object 定义
java 的数组 {
a,
b,
}

js 的数组 [
a,
b,
]

js 的 object {
a : x,
b : x,
}

最佳实践都应该是最后一个多余的逗号保留在代码里,因为这样代码调整更容易
只是因为兼容性的考虑(IE6 兼容),才必须得删除那个多余的逗号(但经过打包工具处理的话是完全没问题的)
qinglangee
2015-08-01 14:45:50 +08:00
@raincious 这个理解起来倒不难, 只是看起来不舒服. 如果不省略也可以的话, 那么省了只是为了少一行代码? 如果像一楼说的不省有时会导致问题, 那么就说必须省略, 免得有麻烦
qinglangee
2015-08-01 14:47:57 +08:00
@SoloCompany 样子奇怪
maddot
2015-08-01 14:52:26 +08:00
加上 ?>结束符,会导致结束符后的空白字符输出(如果有的话),  如果后面别的PHP文件有设置相应的头信息的话,就会导致程序报错。因为头信息必须在返回响应前设置。
tabris17
2015-08-01 14:54:25 +08:00
@qinglangee 这还想不明白么?

?>后面的所有内容会被输出

如果你?>后面有个回车换行就被直接输出了
qinglangee
2015-08-01 14:58:52 +08:00
@maddot
@tabris17
这样就明白了...这才是重点嘛, jsp又没有这个问题 >_>
loveyu
2015-08-01 15:00:08 +08:00
这是标准的做法,上面说得很清楚了。
czheo
2015-08-01 15:12:21 +08:00
给一个实际例子的坑吧。
## lib.php
```
<? php
// 随便你写什么1
?>
```

## index.php
```
<?php
require "lib.php";
// 随便你再写什么2
?>
```

某天程序员在修改lib.php的时候,最后一个?>后面不小心多加了一个空行。比如这样。
## lib.php
```
<? php
// 随便你写什么1
?>

```

你会发现执行index.php只多了一个空行,而实际工作中如果index.php输出的是html,这个多出来空行根本很难察觉。

再过了几点,某程序员在index.php里面某处多加了一行header()调用。比如
```
<?php
require "lib.php";
// 随便你再写什么2
header("Location: http://google.com");
?>
```
程序开始报错,Warning: Cannot modify header information - headers already sent by...

你知道为什么么?自己琢磨下吧。
。。。

对于没有view输出的php文件,省略最后的?>就可以大大避免这种情况。
zhs227
2015-08-01 16:23:33 +08:00
防止结束符后面还有其它不可见字符。这样会导致文件互相包含时出现问题,是一种标准用法。
anubiskong
2015-08-01 16:30:23 +08:00
是的, 没错, php连末尾的特殊字符都搞不定
endrollex
2015-08-01 16:30:53 +08:00
语法上比较难看,毕竟习惯 < > 对称,为什么不出个?eof>标记
breeswish
2015-08-01 17:08:33 +08:00
在纯 include 代码中省略结束的 ?> 是官方推荐做法,原因楼上说了..如果结束符号 ?> 后有空白符号(如回车),则包含这个文件的时候就会立即向客户端输出回车,就可能导致包含该文件的代码无法修改 header(因为包含的时候已经有字符发送了出去)

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.

http://php.net/manual/en/language.basic-syntax.phptags.php
maxsec
2015-08-01 21:09:33 +08:00
```php doing_something.php
<?php
function doing_something(){
echo '1'
}
?>[\r\n]
```
```
<?php
require_once 'doing_something.php';
doing_something();
?>
```

在输出1前会有换行.
vinsony
2015-08-02 10:48:00 +08:00
就是防止最后又换行什么的
realpg
2015-08-03 15:26:40 +08:00
这话说得其实有点隐晦

准确的说法我觉得应该是 如果你的文件以?> 结尾 请省略它
orvice
2015-08-04 23:21:34 +08:00
如果不小心在「?>」后面添加了啥东西的话就。。。嗯

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/210047

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX