本文目录导读:

- 提前说明:PHP 包体积问题在哪里?
- Composer 依赖优化(最见效)
- Docker 镜像体积优化(最常用)
- 代码层面的体积压缩
- 框架和项目结构优化
- 检测与分析工具
- 实际案例优化对比(Laravel 项目)
- 不建议的操作(容易引发问题)
- 最有效的三个操作
PHP 包体积优化可以从多个维度入手,这里整理成 思路 + 具体措施 + 工具检测 的结构。
提前说明:PHP 包体积问题在哪里?
常见场景:
- Docker 镜像(PHP 运行时的基础镜像 + 扩展 + Composer 依赖)
- Composer 依赖 打包进项目(生产环境中 vendor 目录)
- 静态资源 与代码混在一起(图片、CSS、JS)
- 框架本身 包含大量 unused files
优化核心原则:只保留生产环境真正需要的东西。
Composer 依赖优化(最见效)
区分 require 和 require-dev
生产不要安装 dev 依赖:
composer install --no-dev --optimize-autoloader
使用 --optimize-autoloader
composer install --optimize-autoloader # 生成 classmap 提升性能同时减小 classmap 文件数量
清理 autoloader 的 PSR-4 目录扫描路径
composer.json 中精确指定路径,避免扫描整个目录:
{
"autoload": {
"psr-4": {
"App\\": "src/App/",
"Lib\\": "src/Lib/"
}
// 不要用 "App\\": "src/"
}
}
使用 composer require --prefer-dist 减少 git 元数据
dist 包不包含 .git,体积小。
移除不用的包
composer remove unused/package composer why phpunit/phpunit # 确认是否真的需要
生产清理脚本(推荐放进 CI)
composer install --no-progress --no-interaction --no-suggest --no-dev --optimize-autoloader --prefer-dist composer dump-autoload --no-dev --optimize
Docker 镜像体积优化(最常用)
选择轻量基础镜像
| 镜像 | 大小 | 用途 |
|---|---|---|
php:8.2-cli-alpine |
~80MB | 纯 CLI |
php:8.2-fpm-alpine |
~90MB | FPM 场景 |
php:8.2-apache-buster |
~400MB | 自带 Apache,很大 |
永远选 alpine 版本。
多阶段构建(最核心)
# Stage 1: 构建阶段 FROM composer:2.5 AS composer COPY . /app WORKDIR /app RUN composer install --no-dev --optimize-autoloader --no-interaction --prefer-dist # Stage 2: 运行阶段 FROM php:8.2-fpm-alpine COPY --from=composer /app /var/www/html RUN docker-php-ext-install pdo_mysql
效果:构建阶段有 PHP + Composer + 扩展,最终镜像只有运行时 + 必要的 vendor 文件。
合并 RUN 指令减少镜像层
RUN set -eux; \
apk add --no-cache libpng libjpeg-turbo; \
docker-php-ext-install pdo_mysql gd; \
apk del .build-deps
清理包管理器缓存
RUN apk add --no-cache ... # --no-cache 自动清理 /var/cache/apk # 或者手动清理: RUN rm -rf /var/cache/apk/*
使用 .dockerignore 排除无关文件
.git
.gitignore
.env
docker-compose*
tests/
docs/
node_modules/
storage/debugbar/
生产不安装 PHP 额外扩展的构建工具
# 只安装运行时需要的扩展 RUN apk add --no-cache php-pdo php-pdo_mysql # 不要装 php-dev, gcc, make 等构建依赖
代码层面的体积压缩
使用 php-scoper 隔离依赖(场景:打包成 phar)
如果你的项目最终打包成一个 phar 文件,推荐:
composer global require humbug/php-scoper php-scoper add-prefix
生产环境使用 OPCache 文件缓存(性能 + 体积)
opcache.enable=1 opcache.file_cache=/tmp/opcache opcache.file_cache_only=1
生成的缓存文件是二进制的,加载速度更快,原始文件可以删除。
代码压缩工具(非必须)
- PHP-Parser + 自定义 Visitor:删除注释、空白符(对性能提升有限,体积能小 30%)
- 生产部署时可以考虑对代码做一次
strip_whitespace处理(不推荐,仅极端场景)
框架和项目结构优化
框架选择
| 框架 | 体积 | 说明 |
|---|---|---|
| Laravel | ~12MB(vendor) | 功能齐全,但包体积大 |
| Symfony | ~8MB | 按需加载 |
| Slim/Phalcon | ~1-2MB | 轻量 |
| 原生 PHP + Composer 选包 | 可控 | 体积完全取决于你的选择 |
如果项目不大,推荐 Slim 或 Lumen。
移除框架的 demo 文件、文档
find vendor -type f \( -name "*.md" -o -name "*.txt" \) -delete
find vendor -type d -name "tests" -exec rm -rf {} +
find vendor -type d -name "docs" -exec rm -rf {} +
⚠️ 注意:某些包的 tests 目录可能是自动加载规则的一部分,但一般不会。
打包时排除不必要的文件夹
tar -czf release.tar.gz --exclude='vendor/*/tests' --exclude='vendor/*/.git' .
检测与分析工具
Composer 依赖可视化
composer show --size # 查看每个包的大小 composer depends packageName # 查看谁依赖它
建议定期检查 composer.lock 中的包大小,删除不再使用的包。
使用 composer-require-checker 检测 unused packages
composer global require maglnet/composer-require-checker composer-require-checker check
Docker 镜像分析工具
# 安装 dive dive your-image:tag # 可以交互式查看每一层的大小、哪些文件被删除、哪些保留
列出镜像内所有文件大小(生产验证)
docker run --rm your-image /bin/sh -c "du -sh /var/www/html/* | sort -rh | head -20"
实际案例优化对比(Laravel 项目)
| 步骤 | 体积变化 |
|---|---|
基础镜像 php:8.2-fpm → php:8.2-fpm-alpine |
670MB → 180MB |
| 多阶段构建 Composer 依赖 | 180MB → 120MB |
| 删除 dev 依赖(--no-dev) | 120MB → 85MB |
| 删除 tests, docs, .git 目录 | 85MB → 72MB |
| 删除 vendor 中的 .md, .txt 文件 | 72MB → 68MB |
| 最终镜像 | 约 70MB(原 670MB,体积缩小 90%) |
不建议的操作(容易引发问题)
-
删除 vendor 中的 composer.json 和 composer.lock
→ 某些包的自动加载依赖 composer.json 中的配置,删除会直接报错。 -
对所有 PHP 文件做空白符压缩(生产环境)
→ 节省空间有限(约 10%),但造成代码不可读、调试困难、OPCache 不兼容。 -
把 vendor 目录全部压缩成 7z 再解压
→ 运行时反而更慢,也不安全。
最有效的三个操作
| 优先级 | 操作 | 效果 |
|---|---|---|
| 多阶段 Docker 构建 | 镜像体积减少 70%+ | |
composer install --no-dev --optimize-autoloader |
包体积减少 40% | |
| 选用 alpine 基础镜像 | 体积减少 60% |
从这三个入手,能覆盖 90% 的场景。