Press "Enter" to skip to content

PHP对程序员的要求更高

今天是愚人节, 但我这个文章标题可不是和大家开玩笑. 🙂
首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译..
为此, 也就有了一些Opcode Cache, 比如开源的APC, eacc. 还有商业的Zend O+等.
那么为什么PHP不把编译/执行分开呢?
PHP虽然是一种编译型脚本语言, 但是它的编译速度非常快, 它的编译不做任何语义优化, 就是简单的忠实的把你所写的代码翻译成对应的Opcodes. 而其他语言因为在编译器做很多的优化工作, 会造成编译比较重, 也一定程度上要求它们分离.
所以, 理论上来说, 通过编译执行分离, 想达到源码加密, 是不会有什么太大收效的, 因为它很容易被反向.
另外, 编译直接分离, 并不会带来特别大的收益, 反而会降低调试部署的效率(想想, 修改, 编译, 发布, 看效果), 并且APC等Opcode Cache工具, 已经很成熟了..
到这里, 请大家注意这句:"它的编译不做任何语义优化"....
这也就是我为什么说, PHP对程序员的要求更高, 不同于其他的编译型语言, PHP在编译的时候不会帮你做一些优化, 比如对于如下的代码:

$j = "laruence";
for ($i=0;$i<strlen($j);$i++) {
}

如果是其他预编译语言, 它的编译器也许会帮你做优化, 把strlen提取到前面去, 只做一次就够了. 而对于PHP来说, 它在编译的时候不做任何优化, 也就是说, 你的strlen, 会忠实的被调用8次.
再比如:

$table = "table";
while($i++ < 1000) {
  $sql = "select * from " .  $table . " where id = " . $i;
}

没错, "select * from " . $table会被concat 1000次..
可见, PHP的程序员, 需要认真的想好, 你的代码会怎么被执行, 你怎么写代码, 最终的执行效率才最高. 而不像其他的语言, 程序员可以把一部分优化工作交给编译器.
这也就是我为什么说:"PHP对程序员的要求更高" 的原因. 当然, 这个是好是坏, 那就是见仁见智了.

51 Comments

  1. Heropoo
    Heropoo June 4, 2019

    不容易啊[捂脸]

  2. 七彩方糖
    七彩方糖 March 15, 2019

    看完评论我终于知道为什么大部分人只适合玩LOL了, 因为大部分人认为游戏应该把精力放在打架上,而不是花在打钱、补刀上。
    看来我还是支持鸟哥,支持dota的。

  3. cwk44
    cwk44 June 17, 2013

    这个角度是PHP要求更高
    但从其他角度
    比如对计算机的理解(比如内存、指针什么的)、对语言的理解(数据类型什么的)、学习能力、理解能力等
    是其他语言要求更高啦
    整体来说还是其他语言要求更高啦
    说白了PHP就是除了注意性能就没什么要求的语言啦…

  4. qiongqi
    qiongqi June 16, 2013

    @laruence 对hhvm感觉如何?觉得PHP会采用hhvm吗?

  5. t.k.
    t.k. October 4, 2012

    如果单纯为了降低“降低调试部署的效率”而不选择编译我认为是不充分的。作为服务端追求效率的语言,还想看看其他使得PHP不作编译处理的理由。

  6. sk
    sk June 21, 2012

    是这样的。php性能很重要,不同的程序员差距很大。

  7. […] 我怀疑是不是asp.net 空for是不是没处理去了。楼主能不能在for里加些什么运算吧。 想到了鸟哥的一篇文章,说的是php编译执行的时候不做任何语义优化,上面的代码会忠实的loop10000000次,其它预编译语言会做语义优化,对这种空结构,优化之后或许就不对它进行循环了http://www.laruence.com/2012/04/01/2571.html 一个for语句比PHP快点就能说明asp.net比PHP 快。这也太那个什么的了吧。 哦,是的 引用 2 楼 的回复: […]

  8. Anonymous
    Anonymous April 24, 2012

    PHP不是解释型脚本吗,怎么是编译型?。
    java, c/c++是编译型的。
    php脚本实际上经过zend解释器解释后,再编译。也就是每次运行先解释后编译。
    所以请大鸟解释这个疑问.

  9. w
    w April 20, 2012

    汇编语言对程序员要求更高.
    搞WEB都注重更多框架, 更方便开发的API.

  10. rafer
    rafer April 17, 2012

    鸟哥据说去新浪微博了?

  11. 深圳丝印
    深圳丝印 April 8, 2012

    都仔细看了文章了,但是看不懂啊,为啥不能给个链接呢?

  12. dequan
    dequan April 6, 2012

    这回让你觉得编译跟你有莫大的关系,不至于,写完代码后,毫不在乎。

  13. Replie
    Replie April 5, 2012

    需要注意的是语言本身的特性。

  14. Qianfeng
    Qianfeng April 5, 2012

    <?php
    //Demo
    for($i=0;$i<getLen('test');$i++){
    //just for
    }
    function getLen($str)
    {
    static $i;
    $i++;
    echo $i;
    return strlen($str);
    }
    echo ', ';
    foreach(getArray() as $item)
    {
    //empty
    }
    function getArray()
    {
    static $i;
    $i++;
    echo $i;
    return array(1,2,3,4,5);
    }
    /* ————-
    结果是 12345, 1
    为什么 array 能够处理,简单的一个int 却不能记录主呢?
    我觉得php 可以优化下~
    */

  15. fc_lamp
    fc_lamp April 5, 2012

    “Error establishing a database connection”
    大牛你的博客报这个错~~

  16. taylortai
    taylortai April 5, 2012

    作为一个c coder2phper 我觉得带过来好多习惯还不错
    上次百度沙龙终于看到心中的php大神您了~

  17. jlake
    jlake April 4, 2012

    其实哪种语言都一样,
    编译后的代码或是被解释的代码性能再高,
    不合理的写法同样导致效率低下。
    如同文中的例子,大循环里面执行SQL都会产生问题。
    所以说,没有“更高”,只有“同样高”。
    需要注意的是语言本身的特性。

  18. csdcit
    csdcit April 3, 2012

    以上例子,不无道理。

  19. Qiang
    Qiang April 2, 2012

    别的语言是讲究效率所以才会让编译器优化,php这种糙不拉极的,没有优化倒成了对程序员的高要求了?!

  20. Forever
    Forever April 1, 2012

    嗯 有好有坏
    这就让程序员要更注意这些
    从另一方面看 其他语言 这也是优点哈

  21. zyanlu
    zyanlu April 1, 2012

    顶鸟哥

  22. dk01
    dk01 April 1, 2012

    这。。。

  23. 农村旺财的主人
    农村旺财的主人 April 1, 2012

    楼主说的这些问题不能体现PHP需要注意的更多。
    这些问题你完全可以不关心,知道它真的成为瓶颈。
    PHP几乎完全不用关心数据类型和内存分配,语法也比Python还要傻瓜,只需要一个很小的集合就能写出很多有用的程序。
    从入门者的水平就看得出来,PHP比C的差很多,比Java和C#的都有所不及。

  24. 杨昆
    杨昆 April 1, 2012

    顶了再看

  25. wait
    wait April 1, 2012

    for ($i=0;$i<strlen($j);$i++) {
    }
    对JAVA来说,会选择性的优化,如果循环的是基础类型的数组,会优化,包装类型的话,会选择性优化。知道这个比简单的知道PHP需要把strlen提到外面来对程序员的功力要求更高,需要熟悉JVM字节码。
    所以,就这个例子,恰恰说明文章作者的观点是站不住脚的。

  26. weidian01
    weidian01 April 1, 2012

    到底是编译型 还是 解释型 ???

  27. Bruce
    Bruce April 1, 2012

    第一个很简单,在循环之前就确定长度。
    第二个其实只写出来了部分的算法,while循环中应该还有查询数据库的部分,而不仅仅是生成一个SQL语句。第二个的优化应该是优化SQL语句。
    $table = “table”;
    $i = 1000;
    $sql = “SELECT * FROM {$table} WHERE id<{$i} ORDER BY id DESC";

  28. wclssdn
    wclssdn April 1, 2012

    汗.. 第二个例子的意思是说.. $table变量既然已经确定了. 那就要在循环外边确定$sql能确定的部分. 而不是去循环里边把$table 放在$sql中..
    $table = “table”;
    $sql = “select * from ” . $table . ” where id = “;
    while(++$i < 1000) {
    $sql .= $i;
    }
    虽说这个优化的效果不一定有多明显. 但这起码说明了程序员的水平…

    • 前方
      前方 September 5, 2018

      用一个in不好吗,我感觉你这个写出来有毛病

    • Avant
      Avant November 15, 2019

      厉害 ?

  29. hello
    hello April 1, 2012

    第2个貌似应该是999次吧。
    不知道第2个要表达什么意思?

  30. reeze
    reeze April 1, 2012

    @cndong 鸟哥的意思是字符串的连接操作,每次循环都要执行一次。

  31. Lukin
    Lukin April 1, 2012

    第二个看懂了,但应该怎么优化那?

  32. 66beta
    66beta April 1, 2012

    第二个例子意思,应该是想说where的时候直接指定范围 0< id <1000 而不是做循环

  33. cndong
    cndong April 1, 2012

    第一个:
    $len = strlen($j);
    for ($i=0;$len;$i++) {
    }
    第二个着实没有看懂题意:
    执行时$tableName肯定是不一样的, 还是想说 “select * from ” => ‘select * from ‘

    • leeboot
      leeboot March 14, 2019

      $i++ ($i,1000)

  34. vk
    vk April 1, 2012

    因为它很容易被方向。
    别字了,鸟哥。

  35. 雪候鸟
    雪候鸟 April 1, 2012

    @hileon 目标不同, 编译期间优化, 会带来额外的复杂逻辑和性能损失.

  36. hileon
    hileon April 1, 2012

    好的语言应该是程序员的好的表达方式,而不是给程序员制造蹩脚的的难点,让人钻进去解决本来该语言解决的问题.
    我觉得这些例子只能说明php的实现不好,阴暗一点,怀疑zend故意这样的,Zend O+才有市场.
    呵呵,不好意思,在这里乱说了.

  37. qing
    qing April 1, 2012

    就 上述两个例子 您是如何解决的呢?

  38. xupeng
    xupeng April 1, 2012

    很有道理

Comments are closed.