更新:
查看zend语言扫描器源代码,似乎我的"直觉"是正确的: T_CLOSE_TAG
标记可能包含换行符。更重要的是,似乎一个包含结束标记的脚本中最后一条语句的分号是可选的...
<ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0);
BEGIN(INITIAL);
return T_CLOSE_TAG;
}
只需要在这里的zend_language_scanner.c和zend_language_scanner.l文件中查找T_CLOSE_TAG
即可。
foo:
<?= $bar; ?>
foobar
输出:
foo:
bar
foobar
看起来我的怀疑可能是有根据的。
不过,综合考虑,除非你想要去修改Zend引擎源码,否则手动添加换行符并不是太麻烦的事情。实际上,这是确保生成正确的换行符的好方法:
假设你在一个健康的*NIX系统上编写了一些代码,其中换行符基本上由\n
转义序列表示,手动添加该字符可能无法产生期望的输出,例如,在 Windows 系统上(使用 \r\n
),Apple 系统使用\r
...
PHP有一个常量可以确保根据你的代码运行平台生成正确的换行符:PHP_EOL
。为什么不使用它呢:
<?= $bar, PHP_EOL; ?>
如果你在想:没错,那里看到的是$bar
逗号PHP_EOL
。为什么呢?把echo
或<?=
想象成C ++的COUT
,它只是将你想要输出的任何东西推送到输出流中,无论是一个连接的字符串还是仅仅是一系列用逗号分隔的变量:它都不关心。
现在,我的回答以下部分有点跑题,但这是一些如此基础,自明,但许多人却不知道的事情,我忍不住想解释一两句有关字符串连接的事情。
PHP和我所知道的大多数语言都不关心要将多少变量/值推送到输出流中。这就是它的作用。PHP和再次强调:大多数语言,确实关心字符串的连接:字符串是一种常量值。当你情绪高涨时,你不能只是让一个字符串变长。一系列字符必须存储在内存中,必须分配内存来容纳更长的字符串。连接实际上会进行以下操作(最好的情况):
- 计算字符串1和字符串2的长度
- 分配所需的额外内存来将字符串2连接到字符串1上
- 将字符串2复制到新分配的内存中
而在许多情况下,实际发生的是:
- 计算两个字符串的长度
- 分配所需的内存,以连接两个字符串
- 将两个字符串复制到新分配的内存块中
- 将新指针分配给需要分配的任何变量
- 释放不再被引用的任何内存
这里有一个第一种情况的示例:
$str1 = 'I am string constant 1';
$str2 = ' And I\'ll be concatenated';
$str1 .= $str2;
可以翻译为以下C代码:
char *str1, *str2;
//allocate mem for both strings, assign them their vals
str1 = realloc(str1,(strlen(str1) + strlen(str2)+1));//re-allocate mem for str1
strncat(str1, str2, strlen(str2);//concatenate str2 onto str1
然而,仅仅通过这样做:
$str3 = $str1 . $str2;
你实际上正在做的是:
char *str3 = malloc((strlen(str1) + strlen(str2) + 1)*sizeof(char));
strcpy(str3, str1);//copy first string to newly allocated memory
strcat(str3, str2);//concatenate second string...
就好像那个还不够,再想想这段代码意味着什么:
$str1 = $str2 . $str1;
是的,果然如此:
char *str3 = malloc((strlen(str1) + strlen(str2) + 1)*sizeof(char));
strcpy(str3, str2);//copy seconds string to start of new string
strcat(str3, str1);//add first string at the end
free(str1);//free memory associated with first string, because we're reassigning it
str1 = str3;//set str1 to point to the new block of memory
现在我还没有谈到真正的拼接噩梦(别担心,我也不会谈到)。像这样的东西:$foo = 'I ' . ' am '. 'The'. ' ' .$result.' of some'.1.' with a dot'.' fetish';
。看看它,里面有变量,可能是任何东西(数组,对象,巨大的字符串... 还有一个整数... 用逗号代替句点,并将其推送到echo
结构中,比开始考虑编写正确拼接所有这些值所需的代码要容易得多...
抱歉稍微偏离了一下,但我认为,由于这是如此基础,我觉得每个人都应该知道这一点...
<pre></pre>
标签中使用<?= $var ?>
输出变量时,在许多行的末尾需要添加额外的换行符才能保持文本输出的正确格式。虽然我可以理解为什么会添加这个功能,以防止在文件以?>
结尾时输出额外的换行符(而且它可能是一个不应该输出任何内容的包含文件),但我真的不喜欢这种行为。 - Haprog