phar打包使用gzip压缩,从5.8MB压缩到1MB,压缩率为17.2%!

luoyue

前言

目前webman/console中phar打包只是将项目文件添加到phar单文件中,并未进行压缩,所以我在一年前就开始研究了,但是以失败结束研究,不过就在昨天,我再次尝试phar压缩发现在单进程中可以很好的运行,在此分享这次的研究成果。

phar压缩的优点和缺点

优点:

  • 压缩文件大小占用、减少phar内存占用
  • 使用文本打开phar文件无法直接查看代码

缺点:

  • 启动时可能有一点点的延迟(文件越多越慢),具体影响未知,后面代码里有体现
  • 需要生产环境支持压缩扩展

参考链接

https://www.php.net/manual/zh/phar.converttoexecutable.php
https://www.php.net/manual/zh/phar.fileformat.comparison.php

实现步骤

建议使用空项目

1、添加gzip压缩

打开vendor/webman/console/src/Commands/BuildPharCommand.php修改约第49行的代码:

$phar = new Phar($phar_file, alias: 'webman');
// 添加此处代码,参数1可选PHAR、TAR、ZIP,参数2可选GZ、BZ2
$phar = $phar->convertToExecutable(Phar::TAR, Phar::GZ);

最终代码:
截图

2、修改composer类加载器(通过文件锁修复读取文件错乱问题导致的类无法加载)

打开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;
}

最终代码:
截图

3、兼容二进制打包

二进制文件未知原因文件锁未生效,使用进程延迟加载方法。
打开vendor/workerman/workerman/src/Worker.php搜索static::forkOneWorkerForLinux($worker);在后面添加下面这行代码:

php_sapi_name() == 'micro' && usleep(50000); // 每启动一个进程后延迟50毫秒

4、上传phar文件

运行php webman build:phar后将build/webman.phar.tar.gz上传至服务器

5、运行phar

在服务器运行php webman.phar.tar.gz start,无报错即为运行成功

6、验证是否可访问

curl http://127.0.0.1:8787/

磁盘占用与内存占用对比

截图
截图
截图

218 9 3
9个评论

青鱼

大佬厉害👍🏻

  • 暂无评论
walkor

非常精彩的分享 👍👍👍

  • 暂无评论
tanhongbin

大佬666

  • 暂无评论
Jinson

挺有用的分享

  • 暂无评论
tanhongbin

大佬 能不能不该源码 想想办法 在打包命令执行的代码里面实现呢,如果能就太高级了

  • luoyue 1天前

    我正在准备提交pr,在这之前还要研究一下composer加载器如何修改

  • tanhongbin 1天前

    加油,还有压缩感觉只有30%左右 您再多测试 测试

tanhongbin

大佬 我测试了 实际压缩 只有30%左右 34M 压缩完10M

  • Jinson 1天前

    目录内是否有gzip不好压缩的文件,比如图片之类的

  • tanhongbin 1天前

    没有 现在是30M左右 打完包 7M左右 还可以

10bang

给力!感谢分享

  • 暂无评论
chaz6chez

牛的👍

  • tanhongbin 13小时前

    兔子大佬,他这个我测试了,发现启动一直报错,应该是代码混乱了

  • chaz6chez 10小时前

    我还没试过,但理论上行得通,可能是有些步骤没做对,你多看看;空了我试试

  • tanhongbin 9小时前

    就看您了,大佬 我是没想到啥办法

luoyue

我提交了pr,针对报错如果有更好的解决方法可以随时通知我
https://github.com/webman-php/console/pull/51

  • 暂无评论

luoyue

310
积分
0
获赞数
0
粉丝数
2025-01-07 加入
🔝