其他人在编写PHP Web应用程序时发现了什么惊喜?编译时类继承是众所周知的问题,但我知道其他几个问题,并且想要尝试构建一个语言的顶层问题列表.
注意:
作为一名高级PHP5开发人员,我担任过多个职位,因此PHP工作支付我的账单,这个问题并不意味着将PHP作为一种语言,因为我使用过的每一种语言都有一些众所周知或不那么知名的惊喜.
我不确定这是否重要,但是编译PHP脚本的需求是一个巨大的性能问题.在任何严肃的PHP项目中,您都需要某种编译器缓存,如APC,eAccelerator,PHP Accelerator或(商业)Zend平台.
递归引用泄漏内存
如果您创建两个对象并将它们存储在彼此的属性中,则垃圾收集器将永远不会触及它们:
$a = new stdClass; $b = new stdClass; $a->b = $b; $b->a = $a;
当一个大类创建一个通常存储主类的小助手对象时,这实际上很容易做到:
// GC will never clean up any instance of Big. class Big { function __construct() { $this->helper = new LittleHelper($this); } } class LittleHelper { function __construct(Big $big) { $this->big = $big; } }
只要PHP针对短快速页面请求,它们就不太可能解决此问题.这意味着PHP不能依赖于守护进程或其他具有较长使用寿命的应用程序.
require_once和include_once在过度使用时通常会导致主要的性能杀手.如果你的包含/要求一个包含类的文件...这样的模式可以节省一些严重的处理时间.
class_exists("myFoo") or require("myFoo.someClass.php");
更新:这仍然是一个问题 - http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once
更新:阅读以下问题的所选答案: 性能是否会在php中使用自动加载并搜索类文件? 如果按照这些方式实施,您几乎尽可能地减少文件包含/要求的惩罚.
一个有趣的地雷:全局变量可以影响$_SESSION
何时register_globals
开启.但我想这就是当地雷矿本身register_globals开启时会发生什么.
在Php中,NULL和"0"字符串是纯粹的邪恶
if ("0" == false) //true if ("0" == NULL) //true if ("0" == "NULL")//true
foreach()默默地在后台复制数组并通过该副本进行迭代.如果您有一个大型阵列,这将降低性能.在这些情况下,foreach()的by-reference选项是php5的新功能或使用for()循环.
注意平等(==)与身份(===).
请注意构成empty()与构成isset()的构成.
现在我有更多的地雷了:
不要比较浮点数是否相等.PHP不是matlab,它不是专为精确浮点运算而设计的.试试这个:
if (0.1 + 0.2 == 0.3) echo "equal"; else echo "nope"; // <-- ding ding
同样,不要忘记你的八卦!具有前导零的int被转换为八进制.
if (0111 == 111) echo "equal"; else echo "nope"; // <-- ding ding
事实之后有点明显,但是当在foreach中使用时,一个众所周知的问题与范围和引用有关.
foreach($myArray as &$element){ //do something to the element here... maybe trim or something more complicated } //Multiple lines or immediately after the loop $element = $foobar;
数组中的最后一个单元格现在变为$ foobar,因为上面的foreach中的引用仍然在当前上下文范围内.
__autoload()
事实证明,这对我来说是一个重要的地雷.我们的一些遗留代码和库使用class_exists()
,并尝试自动加载从未打算以这种方式加载的类.许多致命的错误和警告. class_exists()
如果你有自动加载,仍然可以使用,但必须将第二个参数(PHP 5.2.0以来的新参数)设置为false
不了解运算符优先级可能会导致一些问题:
if ($foo = getSomeValue() && $bar) { // … } // equals if ($foo = (getSomeValue() && $bar)) { // … }
@
应始终避免使用错误消音器.
一个例子:
// Don't let the user see an error if this unimportant header file is missing: @include 'header.inc.php';
使用上面的代码,你永远不会知道任何代码中的任何错误header.inc.php
,或任何调用的函数header.inc.php
,如果某处有致命错误,你的网页将停止,无法找出错误是什么是.