1. 项目定位与目标
1.1 了解 Phar 打包的场景
在日常的 PHP 应用交付中,单文件部署能显著简化上线流程,提高可移植性。Phar 文件作为 PHP 的打包格式,能够将代码、资源与依赖打包为一个可执行的归档,减少部署的复杂度。
本教程聚焦从零开始实现一个简单的 Phar 文件制作过程,帮助你掌握从准备环境到打包、设置入口和分发的完整链路。通过理解Phar 的工作原理,你可以在实际项目中快速定制打包方案。
2. Phar 的核心概念与工作原理
2.1 Phar 的结构与执行流程
一个 Phar 包通常包含 phar 文件本体、可选的 存根(stub)、以及元数据。存根决定了应用的入口和执行流程,遇到入口时会将归档映射为虚拟路径,进而加载内部文件。

为了保证安全,签名与可执行性在打包过程中也很关键。Phar 提供了通过签名算法对归档进行完整性校验的能力,常见的做法是为打包后的 Phar 设置一个签名。
3. 环境准备与安全要点
3.1 本地环境与关键配置
在开始打包前,请确保你的 PHP 版本和 PHAR 扩展可用。可通过命令确认:php -m | grep Phar。
最重要的安全配置是 phar.readonly。默认为 1 时,无法写入 Phar,打包需要将其临时设置为 0(或在 php.ini 中将其关闭)。这是实现从零到一打包的关键步骤之一。
4. 从零开始:创建一个简单的 Phar
4.1 实操步骤与代码演示
准备一个要打包的源码目录,例如 src,其中放置你的入口脚本和依赖。接下来使用 PHP 脚本创建一个 Phar 包,并将目录内容写入其中。
以下代码演示了从目录构建 Phar、设置存根以及完成打包的过程:
buildFromDirectory(__DIR__ . '/src');// 设置存根(stub),使 Phar 可直接执行
$stub = "#!/usr/bin/env php
";
$phar->setStub($stub);// 完成打包
$phar->stopBuffering();// 使打包产物可执行(Linux/macOS 需有执行权限)
chmod($pharFile, 0775);
?>
在上述代码中,buildFromDirectory 是核心方法,用于把指定目录的内容打包进 Phar;setStub 则确定了应用的入口点。运行后,你将得到一个名为 app.phar 的单文件包。
5. 设置存根(stub)和入口
5.1 自定义入口脚本
存根不仅决定启动方式,也可以包含一个简单的自检逻辑,用于在打包后快速验证环境是否满足运行需求。入口脚本通常会调用 phar:// 路径来定位内部资源。
示例存根中包含了对 Phar 的映射,以及对入口文件的直接引用:Phar::mapPhar 和 __HALT_COMPILER() 的使用可以确保 Phar 安全的边界。
6. 将 Phar 发布为可执行包
6.1 打包完成后的运行与分发
为了让用户像执行普通命令一样运行你的应用,通常会在存根中添加一个 shebang 行,从而在类 Unix 系统上实现直接执行。示例中用到的 #!/usr/bin/env php 就是实现这种效果的常用做法。
打包完成后,可以通过以下方式进行测试与分发:直接执行、使用 PHP 解释器执行、或在服务器上按需解包。若要允许直接执行,请确保 Phar 文件具有执行权限,并且存根中有正确的入口点。
7. 调试、测试与优化
7.1 常见问题排查与调试要点
遇到打包失败时,首先检查 phar.readonly 是否被禁用;确保在打包时该设置为 0,否则写入将被拒绝。
在调试阶段,建议使用 phar 的缓冲模式:startBuffering()、stopBuffering(),以便对打包过程进行分步排错。
8. 进阶优化:依赖、压缩与签名
8.1 高级打包选项与最佳实践
对于较大的应用,可以选择对归档中的文件进行压缩以减小体积,常用方法包括对单个文件的压缩与整包压缩。示例方法是使用 compressFiles,配合 Phar::GZ 或 Phar::BZ2 实现压缩。
另外,签名是提高安全性的常用手段。你可以在打包后为 Phar 设置签名算法,例如:Phar::setSignatureAlgorithm(Phar::SHA1),以确保分发过程中的完整性。
版本控制与自动化打包也属于进阶范畴。将打包过程脚本化、加入持续集成流程(CI),能够在每次提交后自动产出最新的 Phar 包,提升交付的一致性与可重复性。


