分享

关于PHP的编译和执行分离 | 风雪之隅

 quasiceo 2014-01-16

关于PHP的编译和执行分离

关于让”PHP的编译和执行分离”这个问题, 一直有人提, 也一直有人尝试. 提的人认为编译执行分离以后, 可以得到性能提升, 可以做代码保护等.

我本身并不是对这个特性很感冒, 因为这里面存在一个投入产出比. 让我来给大家解释一下, 然而不管怎么样, 在最后我会给大家提供一种方案来实现这个功能.

1. PHP的编译并不是很耗时

我之前的文章也介绍过, PHP的编译是线性的编译过程, 不做优化, 所以这个过程非常之快. 而编译和执行分离这个特性的提出着认为分离以后, 可以省掉编译过程, 会有很大的性能提升.

后记, 有同学提出, 编译和执行分离以后, 就可以在编译的时候做各种优化, 从而影响执行速度. 这个确实是个值得研究的方向.

2. 开发速度

PHP的一个优点就是开发/部署/调试非常方便, 快速, 更改立即见效, 这个当大家在十万火急的情况下修复线上bug的时候会感受更加深刻, :) 而如果我们采用了编译/执行分离以后, 那么更改就需要首先编译, 然后部署, 然后才能生效, 这对于开发来说, 并不是什么好事.

3. 我们有APC/Zend O+等第三方的代码缓存工具

APC等第三方的代码缓存工具(Opcodes Cache)已经相对比较成熟, 并对开发者透明, 大家只要在服务器上安装了APC, 就可以得到编译/执行分离的性能提升.

4. 简单的编译/执行分离, 并不能很好的实现代码保护

原因很简单, PHP的编译不做优化, 所以很容易被反编译. 当然, 我也不否认, 采用二进制内容确实有一些作用.

另外, 还有一些因素, 比如编译/执行分离这个方案是有人在做的, 但是还不成熟等等.

最后呢, 其实我们目前也是可以做到的, 在这里我给大家提供一个类似的解决方案.

首先, 我要打个广告, 以后APC将由我来维护, 大家以后在APC的使用中如果有问题, 可以直接联系我. :)

回归正题: 要实现编译和执行分离, 其实我们借助APC就能做到, APC提供了一族apc_bin_dump, apc_bin_load函数, 能把Opcodes缓存导出到外部文件中.

然而, 可惜的是, 这部分功能以前一直不能很好的正常工作, 这和之前的开发者因为时间原因不在投精力在这个上面是有关系的.

经过我对apc_bin系列函数的重新梳理, 修复以后, 这部分功能现在终于可以正常工作了(从APC-3.1.12开始), 那么基于这些函数, 我们就可以实现编译执行分离.

思路很简单, 在本地通过apc_bin_dumpfile把我们的php文件, 导出成bin文件, 然后在服务器上通过apc_bin_loadfile来读取这些bin文件. 就可以实现编译和执行分离啦, 一个简单的示意代码如下:

  1. $ find ./ -name "*.php" -exec php -r "apc_bin_dumpfile(array('{}'), array(), '{}' . '.bin');" \;

然后在服务器端的文件自动加载部分:

  1. <?php
  2.     function __autoload($name) {
  3.        /*首先计算出文件名字*/
  4.        $file = 根据类名得到PHP文件路径();
  5.        if (!file_exists($file)) {
  6.           //文件不存在, 说明我们还没有load过, 那么创建一个空文件.
  7.           file_put_contents($file, '');
  8.           apc_bin_loadfile($file . '.bin');
  9.        } else {
  10.           //我们已经load过了, 理论上应该已经被服务器的APC缓存处理Cache住了.
  11.         }
  12.  
  13.        include ($file);
  14.    }

当然, 这里只是一个简单的示意, 如果要实际使用, 你还要考虑缓存被换出的可能, 那么一个解决方案就是设置俩个自动加载函数, 第一个如上, 第二个如果被调用, 就说明缓存被换出, 导致include了一个空文件, 于是就再次load一次bin文件就可以了.

当然, 你也可以把所有的文件打包到一个bin文件中, 然后只load一次, 后续就交给服务器上的APC Cache来做就可以了. 但是这里有一个要注意的点就是,

那么对于这部分希望”代码保护”功能的人来说, 就可以使用APC来免费的完成这些事情了. 当然, 因为是内存镜像dump, 所以要受PHP版本和系统的大小端影响, 不过对于一般的应用来说, 这个倒可以很容易做到匹配.

最后, thanks to @cfc4n同学, 在这件事情上的推动, 呵呵


分享到: 2



Related Posts:

Tags: , , , ,

41 Responses to “关于PHP的编译和执行分离”

  1. www.的站长 | 02 Jan 2014 17:28

    我最近也在考虑这个问题,如果把php这个解释型语言变成编译型语言是不是运行效率会很高?考虑到开发的效率可以再开发的时候继续扮演解释型语言,到正式环境的时候摇身一变成为编译型语言,这样如何?

  2. lein | 31 Jul 2013 19:55

    @鸟哥 啊

    为什么要这句?
    include($file);

    并且$file是个空文件,怎么确定apc会从缓存中找这个$file而不是去找这个空文件呢?

  3. lein | 31 Jul 2013 19:32

    请教关于apc的使用

    bin_dump的文件怎么使用呢,网上找到的代码都不够详细,手册上也没有示例。
    我的代码:
    1 被dump的文件(/www/f1.php):

    ‘.chr(10);
    function dosome(){
    echo date(‘Y-m-d H:i:s’);
    }

    2 执行dump的文件(/www/f2.php):
    <?php
    $filename = '/www/f1.php';
    $cache_filename = $filename.'.bin';

    apc_bin_dumpfile(array($filename),null,$cache_filename);
    apc_bin_loadfile($cache_filename);

    dosome();
    echo $cache_filename.' loaded';

    通过浏览器访问:
    http:///f2.php

    报错:
    PHP Fatal error: Call to undefined function dosome() in /www/f2.php on line 8

    =====================================

    这两个函数到底该怎么用?!

    谢谢!

  4. Accepting the things that happen to you in your life with grace and wisdom is a worthy goal. While we get into challenging situations often which test both grace and wisdom, the goal is to act and react gracefully as much as possible. It strengthens our c | 15 May 2013 23:28

    Foarte bine, e un pas inainte.

  5. Taint-0.3.0(A XSS codes sniffer) released | 午后小憩 | 02 May 2013 21:30

    [...] 关于PHP的编译和执行分离 [...]

  6. 关于PHP的编译和执行分离 | 午后小憩 | 01 May 2013 05:28

    [...] 本文地址: http://www./2012/08/16/2701.html [...]

  7. PHP & “Data” URL scheme | 午后小憩 | 30 Apr 2013 19:30

    [...] 关于PHP的编译和执行分离 [...]

  8. 再一次, 不要使用(include/require)_once | 午后小憩 | 30 Apr 2013 04:29

    [...] 关于PHP的编译和执行分离 [...]

  9. Yac (Yet Another Cache) – 无锁共享内存Cache | 午后小憩 | 28 Apr 2013 10:58

    [...] 关于PHP的编译和执行分离 [...]

  10. php | 05 Mar 2013 21:32

    真的受教了,原来PHP也这么强大

  11. Anonymous | 27 Jan 2013 11:52

    我用的时候遇到一个问题

    //t.php
    class a{
    public b(){
    return ‘a’;
    }
    }

    //dump.php
    apc_bin_dumpfile(array(dirname(__FILE__).’\t.php’),array(),’t2.bin’);

    //test.php
    $res = apc_bin_load(file_get_contents(‘t2.bin’));
    var_dump($res);//exit;
    $c = new a();
    echo $c->b();

    加载成功 但是报告 Class ‘a’ not found 这是为什么啊

  12. dailingang | 27 Jan 2013 11:51

    我用的时候遇到一个问题

    b();
    ?>

    加载成功 但是报告 Class ‘a’ not found 这是为什么啊

  13. gaodi07 | 19 Jan 2013 12:51

    相信APC越来越好

  14. 关于PHP的编译和执行分离 | 5iphp | 06 Dec 2012 23:08

    [...] 本文地址: http://www./2012/08/16/2701.html [...]

  15. dawsonJ | 06 Dec 2012 16:42

    请问php以后会实现类似c语言#ifdef之类的预编译指令吗?

  16. 使用APC来保护PHP代码 | 安全-脚本-运维 K. | 29 Nov 2012 19:36

    [...] 早在3-4个月之前,鸟哥博客上一篇文章《关于PHP的编译和执行分离》中提到APC来作为PHP代码保护的方案。从文中可以看出,鸟哥的想法是每个php文件,导出一个opcode 的bin文件,加载时,也是挨个加载,这样也实现了代码保护,但一个项目几百个php文件的话,也得相应存在几百个bin文件,量比较大,操作比较复杂,管理不方便,不好做版本验证(以后会提到)。末学比较倾向于单个bin文件的导出,单个opcode bin文件的加载。而且,单个bin文件的加载,可以避免项目中出现部分文件跟整体版本不一致的情况发生,运维同事再也不用担心个别文件跟整个项目版本不一致的情况了。 [...]

  17. 使用APC来保护PHP代码 | CNXCT小组的博客 | 29 Nov 2012 17:09

    [...] 早在3-4个月之前,鸟哥博客上一篇文章《关于PHP的编译和执行分离》中提到APC来作为PHP代码保护的方案。从文中可以看出,鸟哥的想法是每个php文件,导出一个opcode 的bin文件,加载时,也是挨个加载,这样也实现了代码保护,但一个项目几百个php文件的话,也得相应存在几百个bin文件,量比较大,操作比较复杂,管理不方便,不好做版本验证(以后会提到)。末学比较倾向于单个bin文件的导出,单个opcode bin文件的加载。而且,单个bin文件的加载,可以避免项目中出现部分文件跟整体版本不一致的情况发生,运维同事再也不用担心个别文件跟整个项目版本不一致的情况了。 [...]

  18. 张 健 | 10 Nov 2012 17:07

    崇拜前辈啊

  19. jianwu | 29 Oct 2012 18:11

    不错!

    以后就基本直接执行底层C代码了~

    不过以后应该增加相应管理工具了。比如每次修改php自动编译成apc.bin等

  20. 奇言妙事-文学奇谈小小说阅读xlinblog.sinaapp.com ? 再一次, 不要使用(include/require)_once | 14 Sep 2012 09:15

    [...] 关于PHP的编译和执行分离 [...]

  21. Anonymous | 31 Aug 2012 11:35

    apc相比eaccelerator性能如何, 我之前做过测试, 使用apc的程序qps要比ea慢了1倍所有.

  22. smallyang | 29 Aug 2012 17:20

    水一个:想起一句话,聊天止与呵呵

  23. wee | 29 Aug 2012 17:06

    看完前一篇和这一篇之后,忽然想到一个略有些离题的事情:
    php对windows环境的支持。
    自从windows.出现之后,php本身对于windows的支持已经大致上没什么严重的问题,现在的矛盾卡在扩展上。
    php的扩展,除了windows版本的发行包中间已经附带的那些之外,其他的想找到供windows环境用的.dll文件那是相当的困难,PECL For Windows已经说了N年了,始终不见动静,到目前为止基本上只能指望http://downloads./pierre/这个页面上的那些文件。问题是这里面基本就没有PHP5.4可用的扩展……于是我只好一边对着5.4的几个新特性流口水一边咬牙继续用5.3。为啥?项目里对几个扩展依赖很大,比如http,imagick,oauth……5.4的新特性诱惑很大,但是还不足以抵消解决这几个扩展带来的成本。
    肯定有人说为啥服务器要用windows环境?理由类似于上一篇的“关于语言的选用”,理由就是“易用”。尤其是考虑到安全因素之后。windows server 2k8r2的环境可以很放心的交给开发人员花一点点时间打理即可,linux环境,就必须认真考虑养一个专职的维护人员。
    所以我是不太明白为什么pecl在对windows的支持这上面特别不给力,也许某些扩展在实现上导致了很难提供对windows的支持,但是已经在5.2和5.3上有提供的那些,要提供对应5.4的版本应该不难吧?
    也曾经在之前的某个文章里看到鸟哥提到编译windows版本的扩展并不难,但是我就一直找不到一个像样的教程,鸟哥能写一个不?对于并不精通C的PHP用户来说,怎样做才能编译出windows版本的pecl扩展来?

  24. 关于PHP的编译和执行分离 | 奇言妙事-文学奇谈小小说阅读xlinblog.sinaapp.com | 25 Aug 2012 02:37

    [...] 本文地址: http://www./2012/08/16/2701.html [...]

  25. sevensoile | 24 Aug 2012 13:58

    前辈你好。我有个问题想问下,现在我在网站后台架构上产生了好大的疑问。两个选择:1。php的现有框架(yii,zf,yaf)2。后台使用java和c语言来做逻辑处理和数据库操作,中转用thrift给php
    重点是并行处理上和速度上,我不知道怎么平衡这个问题。
    希望前辈指点下,新浪微薄后台也是用php的么?

  26. 关于PHP的编译和执行分离树林/咖啡 成都专业php网站制作 | 树林/咖啡 成都专业php网站制作 | 24 Aug 2012 09:59

    [...] 风雪之隅 ? PHP应用 Posted in: php / Tagged: 关于PHP的编译和执行分离 [...]

  27. MC | 20 Aug 2012 21:17

    见教了,非常好

  28. crazymartian | 20 Aug 2012 17:58

    支持window是吗?

  29. 雪候鸟 | 17 Aug 2012 17:23

    @sesehai 支持

  30. sesehai | 17 Aug 2012 15:56

    APC 目前是否支持 PHP-5.4.4呢?

  31. hellokitty | 17 Aug 2012 11:34

    貌似没有for windows的版本下载,最新的是3.1.10

  32. PHP小菜鸟 | 16 Aug 2012 14:50

    慢慢研究

  33. wclssdn | 16 Aug 2012 14:28

    就算不用这种方法, 直接开启apc. 不也会缓存住opcode么? 一直也不是很了解apc. 一直认为的就是开启了它, 只要php文件没发生修改. 那只要执行过一次,再下一次执行的时候, apc就会略过它的编译过程. 直接执行上次编译过的结果.. 是这样么?

  34. hileon | 16 Aug 2012 13:37

    PHP的一个优点就是开发/部署/调试非常`方案`

    `方便`吧

  35. 大力水手 | 16 Aug 2012 13:37

    APC终于有希望了,哈哈哈

  36. loki | 16 Aug 2012 13:28

    拿到这些bin文件,再apc_bin_loadfile,那也起不到代码保护的左右- -

  37. 大草原 | 16 Aug 2012 13:27

    在一起!在一起!在一起!在一起!在一起!在一起!在一起!在一起!在一起!

  38. beimuaihui | 16 Aug 2012 13:23

    太好了,又可加速又可保护代码.

  39. Demon | 16 Aug 2012 13:15

    如果我说在一起,鸟哥会不会生气。在一起!在一起!在一起!

  40. 烽火 | 16 Aug 2012 13:02

    老黑你幼稚不

  41. 非洲黑馒头 | 16 Aug 2012 12:46

    抢占沙发

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多