PHP怪癖和陷阱

Ion*_*tan 14 php

我意识到,虽然我的大部分经验都是编写PHP应用程序,但我发现自己不时会犯"初学者错误".这是因为PHP是一种非常有机的语言,因此具有一些我不知道的特性,怪癖和陷阱.

我希望这个问题成为所有想要了解PHP的陷阱和例外的人的维基.但是,请不要写一般的回答,如:

有些功能接收参数为 $needle,$haystack而有的 $haystack,$needle.

告诉函数名称.作为例子,你有几个答案.哦,每个答案添加一个陷阱.通过这种方式,我们可以看到哪些是最受鄙视的(通过投票).

我不想开始一场火焰战,把它留给主题.如果您想写一些关于PHP的坏事,那么请将其作为对相应答案的评论.

希望这个wiki对我们所有人,初学者和专家都有帮助.

更新:

在Andrew Moore的评论之后,我认为答案也应该包含一个解决方案或解决方案的陷阱.

Ion*_*tan 10

序列化处理XML结构然后反序列化它们的对象不会恢复原始XML结构:

$dom = new DOMDocument;
$dom->loadXML('<test/>');

$dom = serialize($dom);
$dom = unserialize($dom);

var_dump($dom->saveXML());
// $ Warning: DOMDocument::saveXML(): Couldn't fetch DOMDocument in ...
// $ NULL
Run Code Online (Sandbox Code Playgroud)

类似地,对于SimpleXML对象.


tj1*_*111 9

我讨厌如果你用一个?>结束标签关闭php文件你会如何得到问题(这似乎应该是相反的方式).例如,在?>之后包含一些带有空格的文件,然后尝试更改标题(假设没有输出缓冲).啊.我花了很长时间才学会永远不要关闭php文件?>


spo*_*son 8

非行业标准的运营商优先权.

$x = 1;
echo 'foo: ' . $x+1 . ' bar';
Run Code Online (Sandbox Code Playgroud)

将输出:" 1 bar",而不是预期的" foo: 2 bar".解决方案:使用括号.

  • echo()可以使用几个参数也可以在这里使用:echo'foo:',$ x + 1,'bar'; (7认同)
  • @ojrac,那是因为PHP中的连接运算符是.(点),而不是像许多其他语言中的+(加号).+用于算术加法,"foo:1"被评估为0以便加1,因此最终结果为1. (4认同)

Mos*_*Bin 7

整数大小取决于平台.在没有任何外部模块的情况下,通常不能在32位机器上使用64位整数.此外,您不能声明无符号整数.


Imr*_*ran 7

进行真值测试的多种方式(不是运算符,空(),is_null(),isset())+弱类型= 这个

通过一些规则,您几乎可以避免需要引用此表:

  • 对于一般真值测试,您可以使用布尔比较if ($){...} if (!$x) { ... }.它的行为与大多数语言中的布尔运算符相同.

  • empty()如果要测试表格输入是否为虚假值,则始终使用(它将"0"视为假).

  • isset()如果要确定是否设置了变量,请始终使用

  • 使用is_null()或者$x === NULL只需要检查NULL


Joe*_*hts 6

我有各种各样的麻烦结合foreach和参考

$testarray = array(1 => "one", 2 => "two");
$item = "three";
$testarray[3] =& $item;
foreach ($testarray as $key => $item) {
  // do nothing
}
echo $testarray[3]; // outputs "two"
Run Code Online (Sandbox Code Playgroud)

在PHP4时代,这真的让我失望了,虽然如果你不使用显式引用,它在PHP5中通过明智的行为变得更好,我仍然设法偶尔被这个引起.

  • =&赋值使数组中的最后一个条目成为$ item变量的引用.在foreach循环的每次迭代中,这意味着$ testarray [3]将更改为$ item的当前值.由于$ testarray [2]是"两个",当迭代$ testarray [3]时该值仍然存在,并且它仍然是$ testarray的最终值[3] (2认同)

Ion*_*tan 1

尽管可以使用for循环和索引来迭代字符串,但不能使用foreach循环来迭代字符串。例子:

$str = 'foo';
$max = strlen($str);

for ($i=0; $i<$max; $i++)  {
    echo $str[$i];
}
// outputs: foo

foreach ($str as $char) {
    echo $char;
}
// Warning: Invalid argument supplied for foreach() ...
Run Code Online (Sandbox Code Playgroud)

  • foreach(str_split($str) AS $char) { 回显 $char; } (4认同)
  • 这是因为 PHP 中的字符串不是字符数组。for 循环之所以起作用,只是因为方括号 [] 是用于访问特定字符的语法糖。不幸的是,这也使得字符串可以作为字符数组进行操作,正如您在 foreach 循环中看到的那样,这是不正确的。正如 Andrew 所指出的,如果您需要的话,使用 str_split() 是将其分解为实际数组的简单方法。 (3认同)