
Webman 是一个基于 Workerman 的高性能 PHP 框架,其 console 插件支持将项目打包成单个 Phar 文件,便于部署和分发。然而,默认的 Phar 打包仅将文件归档到单个文件中,并未启用压缩,导致打包后的文件体积较大,占用更多磁盘和内存空间。
通过启用 Gzip 压缩,可以显著减小 Phar 文件大小(实际测试中可压缩至原大小的 20%-30%),同时还能在一定程度上保护源码(直接用文本编辑器打开 Phar 文件时无法直观查看内容)。本文基于社区实践,介绍如何在 Webman 项目中实现 Phar 的 Gzip 压缩打包,并解决潜在的兼容性问题。
最新发布版本
webman/console v2.1.11已经支持 Gzip 压缩打包
优点:
缺点:
建议在空项目中测试,避免影响现有代码。核心是通过修改 vendor 中的相关文件来实现。
修改 vendor/webman/console/src/Commands/BuildPharCommand.php 文件,大约在第 49 行附近:
原代码类似:
$phar = new Phar($phar_file, alias: 'webman');
修改为:
$phar = new Phar($phar_file, alias: 'webman');
$phar = $phar->convertToExecutable(Phar::TAR, Phar::GZ); // 启用 TAR + GZ 格式
这会将 Phar 转换为可执行的 TAR.GZ 格式,实现压缩。
在多进程环境下,压缩 Phar 可能导致文件读取错乱,引发类加载失败。通过文件锁机制修复。
修改 vendor/composer/ClassLoader.php 文件底部,将 include $file; 替换为:
if (str_starts_with($file, 'phar://')) {
$lockFile = sys_get_temp_dir() . '/phar_' . md5($file) . '.lock';
$fp = fopen($lockFile, 'c');
flock($fp, LOCK_EX) && include $file;
fclose($fp);
file_exists($lockFile) && @unlink($lockFile);
} else {
include $file;
}
这确保在 Phar 文件读取时使用独占锁,避免并发冲突。
对于二进制资源,文件锁可能无效。可通过延迟进程启动来缓解。
修改 vendor/workerman/workerman/src/Worker.php,在 static::forkOneWorkerForLinux($worker); 后添加:
php_sapi_name() == 'micro' && usleep(50000); // 延迟 50 毫秒
这在 Micro SAPI(Phar 运行模式)下为每个进程添加短暂延迟,减少竞争。
执行打包命令:
php webman build:phar
生成的压缩文件通常位于 build/webman.phar.tar.gz,上传至服务器。
在服务器上运行:
php webman.phar.tar.gz start
无报错即成功。测试访问:
curl http://127.0.0.1:8787/
实际测试中,无压缩 Phar 可能达 30-40MB,启用 Gzip 后可压缩至 7-10MB(压缩率约 70-80%),具体取决于项目中代码与资源比例(纯代码项目压缩率更高)。

通过这些优化,Webman Phar 部署更高效、更安全,适合单文件分发场景。如果你在实践中遇到问题,欢迎进一步探索或贡献社区!
https://www.php.net/manual/zh/phar.converttoexecutable.php https://www.php.net/manual/zh/phar.fileformat.comparison.php
原文: https://www.workerman.net/a/1959 workerman社区