- 本文地址: https://www.laruence.com/2012/08/16/2701.html
- 转载请注明出处
关于让"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来免费的完成这些事情了. 当然, 因为是内存镜像dump, 所以要受PHP版本和系统的大小端影响, 不过对于一般的应用来说, 这个倒可以很容易做到匹配.
最后, thanks to @cfc4n同学, 在这件事情上的推动, 呵呵
This extension is considered unmaintained and dead. However, the source code for this extension is still available within PECL GIT here
额。。。
是看了opcache后又看到鸟哥这篇文章的,但php.net上已经说apc不维护了,尴尬……
感觉opcache的方法少了些,仅能自动缓存,但没法手动控制
[…] 本文地址: http://www.laruence.com/2012/08/16/2701.html […]
APC在windows下并没有5.5的版本啊
64位Ubuntu 14.04, PHP-5.4.39 非线程安全版本, APC版本为官方APC-3.1.13.tgz, 导出大一点的文件时(约大于10KB),会发生错误:
<?php
$file = '/path/file.php';
var_dump(apc_compile_file($file));
var_dump(apc_bin_dumpfile(array($file), null, $file));
错误:
apc_bin_dumpfile(): Exceeded bounds check in apc_bd_alloc_ex by 280 bytes.
C源代码:
apc_bin.c:147 Exceeded bounds check in apc_bd_alloc_ex by %d bytes.
APC已经不再维护的.鸟哥现在维护的ZendOpcache是否考虑加入类似APC的 apc_bin_dumpfile 和 apc_bin_loadfile 相关函数和配置用于导出和载入二进制文件实现代码保护呢?
其实我觉得编译还有一个好处,可以避免一些sb的错误,比如变量写错啊,引用一个未定义变量之类的,编译的时候通通可以找出来
hip-hop不是可以吗
我最近也在考虑这个问题,如果把php这个解释型语言变成编译型语言是不是运行效率会很高?考虑到开发的效率可以再开发的时候继续扮演解释型语言,到正式环境的时候摇身一变成为编译型语言,这样如何?
@鸟哥 啊
为什么要这句?
include($file);
并且$file是个空文件,怎么确定apc会从缓存中找这个$file而不是去找这个空文件呢?
请教关于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://aa.com/f2.php
报错:
PHP Fatal error: Call to undefined function dosome() in /www/f2.php on line 8
=====================================
这两个函数到底该怎么用?!
谢谢!
Foarte bine, e un pas inainte.
[…] 关于PHP的编译和执行分离 […]
[…] 本文地址: http://www.laruence.com/2012/08/16/2701.html […]
[…] 关于PHP的编译和执行分离 […]
[…] 关于PHP的编译和执行分离 […]
[…] 关于PHP的编译和执行分离 […]
真的受教了,原来PHP也这么强大
我用的时候遇到一个问题
//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 这是为什么啊
我用的时候遇到一个问题
b();
?>
加载成功 但是报告 Class ‘a’ not found 这是为什么啊
相信APC越来越好
[…] 本文地址: http://www.laruence.com/2012/08/16/2701.html […]
请问php以后会实现类似c语言#ifdef之类的预编译指令吗?
[…] 早在3-4个月之前,鸟哥博客上一篇文章《关于PHP的编译和执行分离》中提到APC来作为PHP代码保护的方案。从文中可以看出,鸟哥的想法是每个php文件,导出一个opcode 的bin文件,加载时,也是挨个加载,这样也实现了代码保护,但一个项目几百个php文件的话,也得相应存在几百个bin文件,量比较大,操作比较复杂,管理不方便,不好做版本验证(以后会提到)。末学比较倾向于单个bin文件的导出,单个opcode bin文件的加载。而且,单个bin文件的加载,可以避免项目中出现部分文件跟整体版本不一致的情况发生,运维同事再也不用担心个别文件跟整个项目版本不一致的情况了。 […]
[…] 早在3-4个月之前,鸟哥博客上一篇文章《关于PHP的编译和执行分离》中提到APC来作为PHP代码保护的方案。从文中可以看出,鸟哥的想法是每个php文件,导出一个opcode 的bin文件,加载时,也是挨个加载,这样也实现了代码保护,但一个项目几百个php文件的话,也得相应存在几百个bin文件,量比较大,操作比较复杂,管理不方便,不好做版本验证(以后会提到)。末学比较倾向于单个bin文件的导出,单个opcode bin文件的加载。而且,单个bin文件的加载,可以避免项目中出现部分文件跟整体版本不一致的情况发生,运维同事再也不用担心个别文件跟整个项目版本不一致的情况了。 […]
崇拜前辈啊
不错!
以后就基本直接执行底层C代码了~
不过以后应该增加相应管理工具了。比如每次修改php自动编译成apc.bin等
[…] 关于PHP的编译和执行分离 […]
apc相比eaccelerator性能如何, 我之前做过测试, 使用apc的程序qps要比ea慢了1倍所有.
水一个:想起一句话,聊天止与呵呵
看完前一篇和这一篇之后,忽然想到一个略有些离题的事情:
php对windows环境的支持。
自从windows.php.net出现之后,php本身对于windows的支持已经大致上没什么严重的问题,现在的矛盾卡在扩展上。
php的扩展,除了windows版本的发行包中间已经附带的那些之外,其他的想找到供windows环境用的.dll文件那是相当的困难,PECL For Windows已经说了N年了,始终不见动静,到目前为止基本上只能指望http://downloads.php.net/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扩展来?
[…] 本文地址: http://www.laruence.com/2012/08/16/2701.html […]
前辈你好。我有个问题想问下,现在我在网站后台架构上产生了好大的疑问。两个选择:1。php的现有框架(yii,zf,yaf)2。后台使用java和c语言来做逻辑处理和数据库操作,中转用thrift给php
重点是并行处理上和速度上,我不知道怎么平衡这个问题。
希望前辈指点下,新浪微薄后台也是用php的么?
[…] 风雪之隅 » PHP应用 Posted in: php / Tagged: 关于PHP的编译和执行分离 […]
见教了,非常好
支持window是吗?
@sesehai 支持
APC 目前是否支持 PHP-5.4.4呢?
貌似没有for windows的版本下载,最新的是3.1.10
慢慢研究
就算不用这种方法, 直接开启apc. 不也会缓存住opcode么? 一直也不是很了解apc. 一直认为的就是开启了它, 只要php文件没发生修改. 那只要执行过一次,再下一次执行的时候, apc就会略过它的编译过程. 直接执行上次编译过的结果.. 是这样么?
PHP的一个优点就是开发/部署/调试非常`方案`
是
`方便`吧
APC终于有希望了,哈哈哈
拿到这些bin文件,再apc_bin_loadfile,那也起不到代码保护的左右- –
在一起!在一起!在一起!在一起!在一起!在一起!在一起!在一起!在一起!
太好了,又可加速又可保护代码.
如果我说在一起,鸟哥会不会生气。在一起!在一起!在一起!
老黑你幼稚不
抢占沙发