我最近在SO上创建了一个答案,我开始意识到我认为PHP中的一个奇怪的行为,我从未注意到由于我的(以下)编码风格:
$var = 1;
echo "test string ". $var+1 ." example";
这样可行,但如果删除1
和.
之间的空格:
echo "test string ". $var+1." example";
它会向我提供T_CONSTANT_ENCAPSED_STRING
解析错误,在这种情况下,期望','
或';'
非常不正确。
是的..它会像这样工作:
echo "test string ".($var+1)." example";
我遇到的问题是,错误信息是它没有反映其特定需要的基本问题,其中大多数其他消息直接指向并纠正。
虽然我最初并不认为浮点是导致这种情况的原因,但我仍然很难理解浮点运算符在以下场景中优先于concat运算符的原因:
var_dump( .1, 1, 1., 1.0);
var_dump( 1.."a", "a"..1, 1.0."a");
float(0.1),int(1),float(1),float(1)
string(2)“1a”,string(4)“a0.1”,string(2)“1a “
现在我明白算术运算符应该在字符串运算之前进行,但这是我不能得到的部分:
".1
和1."
应该表明.
是一个concat运算符,而1.1
应该表明.
是一个float的标识符。相反,他们都给出了解析错误。
PHP是一种在变量类型方面不挑剔的语言:
var_dump(1 + 1.); // float(2)
var_dump(1. + 1); // float(2)
您可以简单地使用+ 1
添加到浮点数,为什么要将1.
解析为浮点数?解析错误发生在下一个令牌上,在该令牌中它需要一个数字,甚至不允许它成为一个连接运算符。
所以我的问题是,为什么PHP词法分析器如此强调浮点识别?如果 echo 1."test"
输出1test
它会破坏当前现有的代码吗?
我已经编辑了这个问题,以便首先澄清我的意思,因为我得到了负面的代表。目前接受的答案仍然非常有效,因为我需要一种方法来验证PHP代码而不使用
eval()
答案 0 :(得分:2)
1.
指的是浮点数1.0
。所以你写的内容是:
echo "test string " . $var + 1.0 " example";
字符串" example"
是T_CONSTANT_ENCAPSED_STRING
令牌。解析器不会在浮点数之后立即出现。
您可以使用token_get_all()
:
php > var_export(token_get_all('<?php echo "test string ".$var+1." example";'));
array (
0 =>
array (
0 => 379,
1 => '<?php ',
2 => 1,
),
1 =>
array (
0 => 328,
1 => 'echo',
2 => 1,
),
2 =>
array (
0 => 382,
1 => ' ',
2 => 1,
),
3 =>
array (
0 => 323,
1 => '"test string "',
2 => 1,
),
4 => '.',
5 =>
array (
0 => 320,
1 => '$var',
2 => 1,
),
6 => '+',
7 =>
array (
0 => 318,
1 => '1.',
2 => 1,
),
8 =>
array (
0 => 323,
1 => '" example"',
2 => 1,
),
9 => ';',
)
php > print token_name(318);
T_DNUMBER
php > print token_name(323);
T_CONSTANT_ENCAPSED_STRING
请注意,1.
显示为一个令牌318
(T_DNUMBER
,双号)。
答案 1 :(得分:0)
让我告诉你,甚至你的陈述:
echo "test string ". $var+1 ." example";
可能无法正常工作。
它可能会打印1 example
而不是 test string 2 example
。
你也可能觉得它很有用
var_dump(1) gives `int 1` and
var_dump(1.) gives `float 1` and as expected
var_dump(1.0) gives `float 1` as answer
意外结果的原因:
在"test string ". $var+1 ." example";
中
首先将“test string
”(一个字符串变量)连接到$var
并生成结果string 1
(一个字符串),然后将其添加(未连接) 1使php将**string 1**
(字符串)的类型更改为 int ,因此它将变为0,然后添加到1,结果为1(0 + 1 = 1)。然后将1(从int再次转换为字符串)添加到example
(字符串),结果为1 example
(字符串)。
使用括号可避免此类更改
如上一个陈述enter code here
echo "test string ".($var+1)." example";