BPC 是一个 PHP Native Compiler,可以将 PHP 源码最终转译成 C 语言,然后编译成动态链接库或可执行程序.
BPC 还内置软件授权机制,最终可实现源码保护、软件授权、二进制打包三合一!
彻底解决 PHP 项目的交付问题.

1. [官网 bpc.dev]( https://bpc.dev/)
2. [安装使用文档]( https://github.com/bob-php-compiler/bpc-release/wiki/01_Install)
写在前面:
1. bpc 不是一个开源项目,项目历史可以翻看之前的文章和帖子.
2. ThinkPHP8 的编译只是一个可行性验证,请勿用于生产环境.
## 1. 了解 ThinkPHP
之前就有网友提过能不能编译 ThinkPHP,我也翻看过几次 ThinkPHP 的代码,虽然 ThinkPHP 带有测试用例,但是一眼看去很少,不清楚能覆盖到多少功能点.
再加上我自己从没写过 ThinkPHP 的项目,对 ThinkPHP 很陌生,所以一直没有尝试编译.
由于 php 的动态性和 bpc 与 php 的高兼容特点,bpc 编译通过不代表就没问题了,如果有测试用例保障的话,通过运行测试用例可以验证编译后的二进制可执行文件是否与原来的 php 等同.
## 2. 迁移 OurBlog 到 ThinkPHP
之前写的一本关于 PHPUnit 的电子书《 PHPUnit in Action --- The Easy Way 》里有一个博客项目 [OurBlog]( https://github.com/heguangyu5/PHPUnit-in-Action-Code),虽然功能很简单,但基本的 CURD 都涉及到了,测试也非常完整.
于是就想着把 OurBlog 迁移到 ThinkPHP 试一下,由于有测试保障,这个迁移应该比较好做.
一番折腾之后,迁移成功了! 源码见: [bpc-thinkphp8-ourblog]( https://github.com/heguangyu5/bpc-thinkphp8-ourblog)
## 3. BPC 编译: 理清依赖
在使用 composer 创建 ThinkPHP 项目时,可以看到一个 ThinkPHP8 项目有以下依赖:
```
league/mime-type-detection (1.15.0)
league/flysystem (2.5.0)
psr/container (2.0.2)
psr/http-message (1.1)
psr/simple-cache (3.0.0)
psr/log (3.0.0)
symfony/polyfill-mbstring (v1.29.0)
symfony/var-dumper (v7.1.1)
topthink/think-helper (v3.1.6)
topthink/think-orm (v3.0.20)
topthink/framework (v8.0.3)
topthink/think-filesystem (v2.0.2)
topthink/think-trace (v1.6)
```
进一步地,跑通 OurBlog 测试用例, 只需要搞定 3 个依赖就可以了:
1. psr/simple-cache (3.0.0)
2. topthink/think-helper (v3.1.6)
3. topthink/think-orm (v3.0.20)
最后,ourblog 的前端界面能正常运行,不需要搞定所有依赖,只需要搞定下边 4 个就行了:
1. psr/container (2.0.2)
2. psr/http-message (1.1)
3. psr/log (3.0.0)
4. topthink/framework (v8.0.3)
由于 topthink/framework 和 think-orm 里都包含了 `think\Facade` 和 `think\Exception` , 需要把 `think-orm/stubs` 独立出来, 再加上 ourblog 项目本身,[一共 9 个 repo, 见这里]( https://github.com/stars/heguangyu5/lists/thinkphp8).
## 4. BPC 编译: 调整代码
要想一行代码不动就能编译成功,几乎是不可能的.
代码调整主要集中在 3 个方面:
1. 语法: bpc 不支持的语法可以通过 [phptobpc]( https://github.com/bob-php-compiler/phptobpc) 做转换, 转换也不支持的,就需要手动调整代码了.
2. 判断 php 代码文件是否存在: bpc 编译后都是二进制了,不能使用 `is_file/is_dir/file_exists/glob` 来判断,要换用 bpc 自己的专有函数.
3. Reflection: bpc 不支持 Reflection,使用 Reflection 实现的功能要调整成 bpc 的方式.
代码调整的细节可以查看每个 repo 的 commit 历史.
## 5. 运行
1. 创建数据库
2. 运行 `tp8-ourblog-althttpd-ubuntu-24.04-amd64`
详见: [bpc-thinkphp8-ourblog release v0.1]( https://github.com/heguangyu5/bpc-thinkphp8-ourblog/releases/tag/v0.1)
后边可以出个视频来演示一下整个编译运行的过程. |
|