关于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文件. 就可以实现编译和执行分离啦, 一个简单的示意代码如下:
- $ find ./ -name "*.php" -exec php -r "apc_bin_dumpfile(array('{}'), array(), '{}' . '.bin');" \
然后在服务器端的文件自动加载部分:
- <?php
- function __autoload($name) {
- /*首先计算出文件名字*/
- $file = 根据类名得到PHP文件路径();
- if (!file_exists($file)) {
- //文件不存在, 说明我们还没有load过, 那么创建一个空文件.
- file_put_contents($file, '');
- apc_bin_loadfile($file . '.bin');
- } else {
- //我们已经load过了, 理论上应该已经被服务器的APC缓存处理Cache住了.
- }
- include ($file);
- }
当然, 这里只是一个简单的示意, 如果要实际使用, 你还要考虑缓存被换出的可能, 那么一个解决方案就是设置俩个自动加载函数, 第一个如上, 第二个如果被调用, 就说明缓存被换出, 导致include了一个空文件, 于是就再次load一次bin文件就可以了.
当然, 你也可以把所有的文件打包到一个bin文件中, 然后只load一次, 后续就交给服务器上的APC Cache来做就可以了. 但是这里有一个要注意的点就是,
那么对于这部分希望”代码保护”功能的人来说, 就可以使用APC来免费的完成这些事情了.
最后, thanks to @cfc4n同学, 在这件事情上的推动, 呵呵
建议继续学习:
- 从C语言的Hello World说起 (阅读:6161)
- 如何在Windows下编译或调试MySQL (阅读:3544)
- javascript语句的执行过程分析 (阅读:3113)
- 内核编译升级失败了以后的处理方案 (阅读:2926)
- Javascript 装载和执行 (阅读:2546)
- 如何在AIX中编译Perl (阅读:2292)
- 产品经理能力模型解说―执行 (阅读:2285)
- 编译安装mysql 5.141源代码,常见两处错误解决 (阅读:2160)
- 在编译php-fpm0.6的时候需要注意的一些问题 (阅读:1959)
- GCC编译错误 (阅读:1895)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:雪候鸟 来源: 风雪之隅
- 标签: 执行 编译
- 发布时间:2012-08-17 13:13:08
- [66] Oracle MTS模式下 进程地址与会话信
- [66] Go Reflect 性能
- [65] 如何拿下简短的域名
- [59] android 开发入门
- [59] 图书馆的世界纪录
- [59] IOS安全–浅谈关于IOS加固的几种方法
- [58] 【社会化设计】自我(self)部分――欢迎区
- [53] 视觉调整-设计师 vs. 逻辑
- [47] 界面设计速成
- [46] 读书笔记-壹百度:百度十年千倍的29条法则