不了解BPC是什么的可以翻看之前的 几个分享,也可以翻阅 知乎专栏 或者 v2ex 了解更多.
简言之,BPC可以将PHP代码最终转译成C语言,然后编译成动态链接库或者可执行程序,实现 PHP Native AOT!
本文所述的所有操作都是在 Ubuntu 18.04 amd64 上完成的,但这并不是说BPC只能在 Ubuntu 18.04 上运行.
BPC编译器自身已验证过可以在 Ubuntu 18.04 / 20. 04 / 22.04 上运行,编译结果还可以在 Debian 12 上运行, 参看 wordpress的例子.
下载编译好的二进制文件 start
加上可执行权限 chmod +x start
运行 mkdir /tmp/x && mv start /tmp/x && cd /tmp/x && ./start start
另外打开一个终端
~$ tree /tmp/x/
/tmp/x/
├── runtime
│ ├── logs
│ │ └── workerman.log
│ ├── views
│ └── webman.pid
└── start
3 directories, 3 files
访问以下url查看效果
~$ bpc
bpc/6.4.0
Usage: bpc [options] <input-files> [-- script args]
see bpc -h for help with command line options
下载安装phptobpc 来解决BPC不支持的语法特性
phptobpc就是个phar文件,下载回来后加上可执行权限,放到 ~/bin/
或者 /usr/local/bin/
目录下即可.
由于是phar文件,当然需要php解释器,sudo apt install php-cli
即可.
~$ phptobpc
Usage: php phptobpc.php file.php
参照以下 git repo README.md 开头的 BPC Notes 编译安装webman依赖
结果如下:
~$ cd /usr/local/lib/
/usr/local/lib$ ls *psr*
libpsr-container_u-4.4a.a libpsr-log_u-4.4a.a psr-container.heap psr-log.heap
libpsr-container_u-4.4a.so libpsr-log_u-4.4a.so psr-container.sch psr-log.sch
/usr/local/lib$ ls *fastroute*
fastroute.heap fastroute.sch libfastroute_u-4.4a.a libfastroute_u-4.4a.so
/usr/local/lib$ ls *monolog*
libmonolog_u-4.4a.a libmonolog_u-4.4a.so monolog.heap monolog.sch
/usr/local/lib$ ls *workerman*
libworkerman_u-4.4a.a libworkerman_u-4.4a.so workerman.heap workerman.sch
/usr/local/lib$ ls *webman*
libwebman_u-4.4a.a libwebman_u-4.4a.so webman.heap webman.sch
注意: 需要完成1,2,3步才能进行这一步.
```shell
~$ git clone git@github.com:heguangyu5/bpc-webman.git
~$ cd bpc-webman/
~/bpc-webman$ make
...
output prologue
generate main.c
generate build.ninja
run ninja
[34/34] link ../start (statically linked)
mv start ../
make[1]: Leaving directory '~/bpc-webman/build'
~/bpc-webman$ ./start start
Workerman[./start] start in DEBUG mode
--------------------------------------------- WORKERMAN ----------------------------------------------
Workerman version:4.1.10 PHP version:7.2.19-bpc Event-Loop:\Workerman\Events\Event
---------------------------------------------- WORKERS -----------------------------------------------
proto user worker listen processes status
tcp hgy webman http://0.0.0.0:8787 16 [OK]
------------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
```
webman-framework 详见 git commits
src/App.php
不支持依赖注入
依赖注入需要获取到callback或者controller每个method的参数的详细信息,BPC目前不提供这些信息,所以依赖注入部分的代码都给注释掉了, @see src/App.php#L322
src/Context.php
简化实现
BPC尚未实现SplObjectStorage
, 所以临时使用一个array
替代了原来的代码
BPC6.5已实现SplObjectStorage
,此修改已rollback
src/support/App.php
Worker::$eventLoopClass
固定为 \Workerman\Events\Event
, 不可配置
src/App.php::getController()
要求目录及文件名全部小写.
编译成二进制后,目录和文件的概念都没有了,所以也就不能scanDir了,根据url找到controller的逻辑必须固定下来,不能scanDir+strtolower来实现.
Controller的文件名可以大写,bpc-prepare.sh
会将文件名转成小写.
src/Config.php
src/Route.php
src/support/App.php
和第4点一样,由于不能scanDir,config文件必须想个办法明确列出来.
webman 详见 git commits
support/helpers.php
定义了一个常量 BASE_PATH_REAL
用于当需要读写硬盘文件时用 config/view.php
编译时为了区分静态资源文件(css/js/html/图片等)和view文件, 将view_suffix
配置为 phtml
vendor/autoload.php
BPC不需要composer,所以需要一个手写的 autoloader.php
参看 webman Makefile 里的编译命令:
bpc -v \
--static \
-c bpc.conf \
-u psr-log \
-u psr-container \
-u fastroute \
-u monolog \
-u workerman \
-u webman \
-d display_errors=on \
--input-file src.list
将你项目的外部依赖像 psr-log/container, fastroute, monolog 等一样,编译成 .so/.a, 然后通过参数 -u YOUR_LIB
link进来, 然后把项目自身的静态资源和php文件加到src.list
里编译就好了.
等待BPC升级新版本.
翻阅过之前文章的网友应该知道,BPC并不是我们公司的主营业务,它最初是为了解决云招OurATS招聘管理系统本地部署而生的一个 side project ,目前OurATS自身的需求已经完善解决,所以BPC目前处在稳定期,更新和维护要看OurATS的需求来进行,请大家期望不要太高.
确实有需求的网友可以在公司层面和我们进行深度合作,我们乐意提供相应的技术支持.
语法特性涉及到BPC编译器的核心部分,因此实现起来一般不会很快,所以能用phptobpc解决的,可以用phptobpc解决.
php扩展开发较为容易,简单的几天可以开发一个,复杂的需要几周时间,比如开发 event(core) 扩展用了3天,开发 mysqli 扩展用了2周.
目前BPC有3个大的特性尚未实现,提前知悉以免白忙一场:
trait
简单的trait就相当于copy paste, monolog-2.x里有用到几个trait,就是通过代码替换完成编译的.
class typed properties
BPC 支持 function/method type hints,但不支持 return type (可通过phptobpc去掉).
Generator / Fiber
PHPUnit.
我们维护着一个BPC可编译的phpunit版本: bpc-phpunit.phar-4.8.36.
使用php运行phpunit tests没问题,然后再用bpc编译运行这些tests还没问题,那就是没问题.
nikic-fast-route-1.3.0 和 monolog-2.x-branch 的 phpunit tests 就是使用 bpc-phpunit.phar-4.8.36 跑过的,所以可以确保没问题.
另外,我们也有一本收费的电子书 《PHPUnit in Action --- The Easy Way》 介绍了云招OurATS 10多年来的测试心得,有需要的可以看看.
这里说的软件授权不是BPC编译器自身的license,而是你自己项目的授权.
比如你自己的项目中可能会有如下授权检测代码:
if (/* 没有通过授权检测 */) {
die('请购买授权后再使用');
}
BPC的解决方案是在生成的scheme代码中随机插入授权检测代码,数量可由一个参数控制,通过插入足够多的授权检测(比如10万个)来增加破解时间,简单粗暴.
请参看文档 06_Licensing
在 https://bpc.dev 上可以在线试用BPC编译器, 已内置了一些示例项目代码, 欢迎大家试玩儿~
BPC的出发点在于源码保护和软件授权,因此对性能没那么在意,也没有做什么编译优化.
这里感谢网友 kspade 提供的性能测试结果,供大家参考,编译后较PHP还是有很大差距.
BPC ./start
PHP 8.0
为了减小最终生成的二进制大小, bpc-webman//bpc.conf 里仅包含了webman用到的扩展.
BPC已实现的扩展列表见这里 bpc-php-7.2.19-tests.
还有几个扩展仅实现了一小部分函数,并且没有过phpt测试,未列出,比如 gd imagick zlib sysvsem等,这些在 bpc-release 的 tar.gz 里可以找到.
支持!
太牛了
关注
centos 测试失败提示:
解决办法安装
然后:ldconfig -p | grep libargon2 查看发现已安装
但是仍然报错:把/lib64/libargon2.so.1 复制1个改名为:libargon2.so.0
然后运行成功
Debian 11.1 64bit 测试报错
解决办法安装libargon2-0:
安装后测试成功
最后我进行打包自己的webman 项目。不行嗷嗷报错,太多错误了。
或许是我打包姿势不对,但是我看了一下 很多我使用的扩展都没有支持 因此放弃了,而且翻阅了文档似乎无法将指定目录或者文件不打包操作,
实际上libargon2是可以link .a的,只是ubuntu下默认系统都已经安装了,所以没有加上.
编译时可以修改 bpc.conf 的 ldflags 调整link选项, https://github.com/heguangyu5/bpc-webman/blob/ca9680d9cd4372f512cebff12f9cb191bb830454/bpc.conf#L26
之前在编译wordpress时尝试过centos7,发现它的libc版本太低了,然后就没再试了,你的centos是哪个版本的?
ubuntu 22.04下编译好的可以直接放到debian 12上运行,没问题,其它的没试过 .
具体要编译哪些文件是要明确列出来的,也就是白名单,不是黑名单.
扩展不支持一般问题不大,确有需要开发就是了.
centos7.9
centos8.2
CentOS Stream 9
Ubuntu 22.04.3 LTS
Debian 11.1
均测试了 不行 报一样错误
当然安装一下就解决了,只不过这不是很友好
bpc-release里发的编译器也是针对 ubuntu 18.04 的,要想上22.04上正确运行,需要发一个22.04版本的BPC编译器,然后再编译就好了.
但目前我们自己用的情况下,就锁定 ubuntu 18.04 了.
如果局限于指定系统平台 以及版本 那就很难受了
大佬,收藏了
赞个👍🏻,一般性能够用了!
收藏、关注👍
大佬,这个性能相对于传统的fpm相比如何?
BPC不是为性能而生的,如果是追求性能的项目就不用考虑了.
以 wordpress 为例, ab测试 apache2 + php 8.1 101 req/s, BPC althttpd 37 req/s.
感谢解答