我意识到,虽然我的大部分经验都是编写PHP应用程序,但我发现自己不时会犯“初学者错误”。这是因为PHP是一种非常有机的语言,因此有一些我不知道的特质,怪癖和陷阱。
我希望这个问题能够成为所有想要了解我们可能认为是规则的PHP陷阱和异常的人的维基。但是,请不要写一般的回答,如:
某些函数接收参数为
$needle
,$haystack
,而有些则为$haystack
,$needle
。
告诉功能名称。作为例子,你有几个答案。哦,每个答案添加一个陷阱。通过这种方式,我们可以看到哪些是最受鄙视的(通过投票)。
我不想开始一场火焰战,把它留给主题。如果您想写一些关于PHP的坏事,那么请将其作为对相应答案的评论。
希望这个wiki对我们所有人,初学者和专家都有帮助。
更新
在Andrew Moore的评论之后,我认为答案也应包含解决方案或解决方法。
答案 0 :(得分: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
类似于SimpleXML对象。
答案 1 :(得分:9)
如果您使用?>
结束标记关闭php文件(看起来应该是另一种方式),我讨厌如何解决问题。例如,在?&gt;之后包含一些带有空格的文件。然后尝试更改标题(假设没有输出缓冲)。啊。让我学会永远不要用?>
答案 2 :(得分:8)
非行业标准的运营商优先权。
$x = 1;
echo 'foo: ' . $x+1 . ' bar';
将输出:“1 bar
”,而不是预期的“foo: 2 bar
”。解决方案:使用括号。
答案 3 :(得分:7)
整数大小取决于平台。在没有任何外部模块的情况下,通常不能在32位机器上使用64位整数。此外,您不能声明无符号整数。
答案 4 :(得分:7)
多种方式进行真相测试(not operator,empty(),is_null(),isset())+弱打字= this
有了一些纪律,你几乎可以避免引用这个表:
对于一般真值测试,您可以使用布尔比较if ($)
{...} if (!$x) { ... }
。它的行为与大多数语言中的布尔运算符相同。
如果要测试表格输入是否为虚假值(它将“0”视为假),请始终使用empty()
。
如果要确定是否设置了变量,请始终使用isset()
如果您只需要检查NULL,请使用is_null()
或$x === NULL
答案 5 :(得分: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"
在PHP4时代,这真的让我失望了,虽然如果你不使用显式引用,但在PHP5中通过明智的行为变得更好,我仍然设法偶尔被这个引起。
答案 6 :(得分:4)
内置函数的命名约定不一致。例如,这组字符串处理函数:
str_shuffle()
str_split()
str_word_count()
strcasecmp()
strchr()
strcmp()
解决方案:始终保持手动打开状态。
答案 7 :(得分:3)
有时你想直接将函数结果传递给另一个函数,它只接受变量作为输入。
例如:
array_pop( explode('\\', get_class($this)) )
...将导致E_STRICT错误“只应通过引用传递”。要使其正常工作,只需在内部(返回)语句周围添加另一对括号:
array_pop( (explode('\\', get_class($this))) )
(如果您正在使用名称空间和扩展类,则此行仅返回来自调用对象的类名(不带名称空间) - 而不是已扩展的父类,并且可以保留此函数。)
答案 8 :(得分:2)
一些新引入的PHP功能因为无法保证在托管环境中默认支持这些功能。
我最大的烦恼是short_tags
设置,它启用了<? foobar(); ?>
和标记语法。我认为PHP应该默认启用此功能,而不是选择加入。<?=$var ?>
==编辑==
在PHP&gt; = 5.4中,简写echo语句不再考虑short_tags
设置,因此它将在支持PHP 5.4及更高版本的每个托管环境中可用。
答案 9 :(得分:2)
函数在不同的OS上表现不同,某些函数仅在特定的OS上可用。
例如,Windows上的mail()
函数无法在$to
参数中使用发件人名称。它只能包含电子邮件地址。在Linux上一切正常。
另一个例子,函数strptime()
仅在Linux上可用,而不是Windows(这使我进入了我希望在Windows机器上运行的现有项目)。
当然,有些功能只对某些操作系统(如Win32API功能)有意义,但许多其他功能似乎在所有操作系统上应该表现相同,而实际上并非如此。
答案 10 :(得分: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() ...
答案 11 :(得分:1)
我的最爱:
<?php
$a = 0;
$b = 'x';
var_dump(FALSE == $a);
var_dump($a == $b);
var_dump($b == TRUE);
echo' <br />Conclusion: TRUE equals FALSE (at least in PHP)';
答案 12 :(得分:1)
==编辑== 这不再适用于PHP&gt; = 5.5!
使用
Fatal error: Can't use function return value in write context
时,我有时会遇到empty()
错误 构造。例如:if (!empty(trim($_GET['s']))) { // ... }
empty()
需要一个变量,其他任何内容都会导致错误。解决方案:
$s = trim($_GET['s']); if (!empty($s)) { // ... }
答案 13 :(得分:0)
$x = "a string";
if ($x == 142)
{
echo "lol, of course $x is a number";
}
else
{
echo "$x is clearly not equal to 142";
}
运行时:
lol, of course a string is a number
您必须使用 ===
$x = "a string";
if ($x === 142)
{
echo "lol, of course $x is a number";
}
else
{
echo "$x is clearly not equal to 142";
}
运行时:
a string is clearly not equal to 142