当前位置:  开发笔记 > 编程语言 > 正文

一般的PHP地雷

如何解决《一般的PHP地雷》经验,为你挑选了10个好方法。

其他人在编写PHP Web应用程序时发现了什么惊喜?编译时类继承是众所周知的问题,但我知道其他几个问题,并且想要尝试构建一个语言的顶层问题列表.

注意:

作为一名高级PHP5开发人员,我担任过多个职位,因此PHP工作支付我的账单,这个问题并不意味着将PHP作为一种语言,因为我使用过的每一种语言都有一些众所周知或不那么知名的惊喜.



1> cg...:

我不确定这是否重要,但是编译PHP脚本的需求是一个巨大的性能问题.在任何严肃的PHP项目中,您都需要某种编译器缓存,如APC,eAccelerator,PHP Accelerator或(商业)Zend平台.


@David:我认为它还没有被包含在内,但它计划包含在PHP6中.

2> too much php..:

递归引用泄漏内存

如果您创建两个对象并将它们存储在彼此的属性中,则垃圾收集器将永远不会触及它们:

$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不能依赖于守护进程或其他具有较长使用寿命的应用程序.


循环垃圾收集器应该包含在PHP 5.3中:http://www.ibm.com/developerworks/opensource/library/os-php-5.3new1/index.html#N101D4
您应该将其更改为"循环引用",即常用术语.

3> David..:

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中使用自动加载并搜索类文件? 如果按照这些方式实施,您几乎尽可能地减少文件包含/要求的惩罚.


自动加载(http://uk.php.net/autoload)是一种更清晰,更灵活的解决方法.

4> Richard Leva..:

一个有趣的地雷:全局变量可以影响$_SESSION何时register_globals开启.但我想这就是当地雷矿本身register_globals开启时会发生什么.



5> Robert Gould..:

在Php中,NULL和"0"字符串是纯粹的邪恶

if ("0" == false) //true
if ("0" == NULL)  //true
if ("0" == "NULL")//true


这就是为什么你应该使用严格的比较(===)

6> Shane H..:

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


iirc,php数组是copy-on-write,所以使用foreach()迭代它不会产生任何额外的内存,除非你修改它们.应该避免引用它们,它们是一个主要的地雷.

7> David..:

事实之后有点明显,但是当在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中的引用仍然在当前上下文范围内.


PHP没有块范围,只有函数/类/全局范围.

8> Jeremy DeGro..:

__autoload()事实证明,这对我来说是一个重要的地雷.我们的一些遗留代码和库使用class_exists(),并尝试自动加载从未打算以这种方式加载的类.许多致命的错误和警告. class_exists()如果你有自动加载,仍然可以使用,但必须将第二个参数(PHP 5.2.0以来的新参数)设置为false



9> Gumbo..:

不了解运算符优先级可能会导致一些问题:

if ($foo = getSomeValue() && $bar) {
    // …
}
// equals
if ($foo = (getSomeValue() && $bar)) {
    // …
}


在条件测试中分配值并不是一个好的开始.

10> too much php..:

@应始终避免使用错误消音器.

一个例子:

// 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,如果某处有致命错误,你的网页将停止,无法找出错误是什么是.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有