💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
BPC 是一个 PHP Native Compiler,可以将 PHP 源码最终转译成 C 语言,然后编译成动态链接库或可执行程序. BPC 还内置软件授权机制,最终可实现源码保护、软件授权、二进制打包三合一! 彻底解决 PHP 项目的交付问题. ![How BPC Works](https://bpc.dev/bpc.svg) 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项目有以下依赖: ~~~php 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) 后边可以出个视频来演示一下整个编译运行的过程.