FrankenPHP单文件部署中仅PHP源码文件可加密,其二进制和Caddyfile不可也不应加密;ionCube或SG16加密后可运行,但需匹配PHP版本与扩展架构,并注意worker模式下$_SERVER变量完整性及反向代理时的Host头传递。

FrankenPHP 本身不提供源码加密能力,它只是一个嵌入式 PHP 运行时(Caddy + PHP 解释器),所有 PHP 文件仍以明文形式存在。商业交付时若用 FrankenPHP 打包成单文件(如 frankenphp 二进制 + public/ + app/ 目录),源码保护必须在 FrankenPHP 之外单独设计,否则客户拿到整个目录就能直接读取、修改、复制全部逻辑。
FrankenPHP 单文件部署中哪些文件能被加密?
能加密的只有你自己的 PHP 源码文件(如 app/Logic/Payment.php、app/Service/LicenseChecker.php);FrankenPHP 自身的二进制(frankenphp)和 Caddy 配置(Caddyfile)无法也不应加密——它们是运行载体,不是业务逻辑。
-
frankenphp是 Go 编译的静态二进制,天然不可读,无需额外保护 -
Caddyfile可能含敏感路径或代理规则,建议用环境变量注入或运行时生成,避免硬编码域名/IP - 所有
.php文件默认可被直接 cat 查看,必须单独加密或混淆 -
vendor/下的第三方库一般不加密(Composer autoload 会失败),但可删掉 dev-only 包(如phpunit)并禁用composer dump-autoload --optimize
ionCube 加密后能在 FrankenPHP 中正常运行吗?
可以,但前提是目标服务器已安装匹配的 ioncube_loader 扩展。FrankenPHP 本质仍是标准 PHP SAPI(支持 CLI 和 embed 模式),只要加载了 ionCube Loader,就能执行 .php 加密文件。
- 确认 FrankenPHP 启动时使用的 PHP 版本与 ionCube Encoder 的
--php-version一致(例如--php-version 8.2) - FrankenPHP 默认使用内置 PHP,需通过
php.ini路径显式指定扩展:在frankenphp.yaml或启动参数中加入--php-ini /path/to/php.ini -
php.ini中必须包含zend_extension = /path/to/ioncube_loader.so,且该 so 文件架构(x64/NTS)与 FrankenPHP 内置 PHP 完全一致 - 加密时务必加
--no-allow-run,否则未授权服务器可绕过 license 校验直接运行
SG16 Pro 域名绑定在 FrankenPHP 环境下怎么生效?
SG16 Pro 的域名绑定依赖 ixed 扩展对 $_SERVER['HTTP_HOST'] 的实时校验,FrankenPHP 支持该变量(尤其在 HTTP 模式下),但需注意两个关键限制:
立即学习“PHP免费学习笔记(深入)”;
- FrankenPHP 的
worker模式下,$_SERVER变量可能不完整,建议强制使用classic模式启动(frankenphp php-server --mode classic) - 如果用 FrankenPHP 作反向代理(如前端接 Nginx),真实域名由 Nginx 传入
X-Forwarded-Host,此时 SG16 默认不识别,需在Caddyfile中显式设置header Host {http.request.header.X-Forwarded-Host} - SG16 加密文件(
.php.sgc)替换后,必须确保ixed扩展版本 ≥ SG16 加密所用版本(SG16 最高只支持 PHP 8.3,不能用于 FrankenPHP 内置 PHP 8.4+) - 离线 license 校验(
license.lic)文件需放在与加密脚本同目录,且 FrankenPHP 进程有读取权限
真正容易被忽略的是:FrankenPHP 的单文件便利性会让人误以为“打包即安全”。实际上,只要没加密 PHP 文件,客户用 find . -name "*.php" -exec cat {} \; 就能瞬间拿到全部业务逻辑。授权校验代码(比如域名检查)如果本身是明文,客户删掉两行就能绕过——所以最核心的 LicenseChecker.php 必须用 ionCube 或 SG16 加密,且校验逻辑要分散在多个加密文件中,不能集中在一个入口里。



















