Composer 不参与 Phar 打包,仅生成 autoloader;Box 或 Phar 类负责打包,入口脚本须显式 require autoload.php 且含 shebang:#!/usr/bin/env php。

Composer 本身不参与 Phar 打包过程,它只负责生成可被 Phar 加载的 autoloader;真正打包的是 Box 或原生 Phar 类,而关键动作是让 Composer 的加载逻辑在 Phar 内部“活过来”。
入口脚本必须显式 require autoload.php
Box 或 Phar 类不会自动注入或重写 require 语句。如果你的 bin/myapp 没写 require,打进 Phar 后照样报 Class not found。
- 入口文件开头必须有 shebang:
#!/usr/bin/env php(注意换行,不能紧贴<?php) - 紧接着就要
require __DIR__.'/../vendor/autoload.php';—— 这行代码会被 Box 复制进 Phar,并在运行时从phar://协议加载 - 该脚本在开发阶段必须能独立执行:
php bin/myapp --version成功,打进 Phar 才可能成功 - Linux/macOS 下记得
chmod +x bin/myapp;Box 的"stub": true依赖这个可执行位生成合法 stub
box.json 中必须设 "install": false
Box 默认会在打包前静默执行 composer install,这会导致 dev 依赖混入、autoload.php 未优化、甚至因本地扩展差异引发运行时错误。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
"install": false是硬性开关,不是"composer-install": false(后者无效) - 打包前手动运行:
composer install --no-dev --optimize-autoloader --classmap-authoritative - 确认
vendor/composer/autoload_dev.php文件不存在,否则说明 dev autoloader 没清理干净 -
"autoloader": "vendor/autoload.php"必须指向你手动安装后生成的那个文件路径
Phar 内部路径不能依赖 __DIR__ 或 __FILE__
很多包(如 Twig、Symfony Console)会用 __DIR__ 构造模板路径或配置位置,直接打进 Phar 后这些路径就失效了——因为 __DIR__ 返回的是 Phar 归档外的路径,而非内部虚拟路径。
- 改用
Phar::running(true)获取当前 Phar 文件路径,再拼接资源,例如:Phar::running(true) . '/templates/layout.twig' - 对资源访问做封装,统一走自定义加载器,避免散落在各处的硬编码路径
- 若用 Symfony Console,初始化前加一句:
Symfony\Component\Console\Application::setAutoExit(false),防止exit()中断 Phar 执行流 - 启用
Phar::interceptFileFuncs(true)(在 stub 或入口中调用),让file_get_contents('phar://...')自动生效
签名和压缩要分开对待
GZ 压缩能减体积,但 OpenSSL 签名才是分发安全底线;二者不冲突,但顺序和配置容易出错。
- 压缩只对 PHP 源码有效,二进制资源(图片、证书、.env)建议不压缩,否则可能损坏或解包失败
- 签名必须用私钥:
$phar->setSignatureAlgorithm(Phar::OPENSSL, file_get_contents('private.key')) - Box 配置中签名字段是
"signing": { "key": "openssl://path/to/private.key", "key-pass": "..." },路径必须可读且格式正确 - 验证签名不能靠肉眼:用
php -r "echo (new Phar('myapp.phar'))->getSignature();"查看是否含openssl类型
最常被跳过的一步是验证 vendor/composer/autoload_files.php 是否真的没被 Box 扫进去——它常被 finder 规则意外包含,导致运行时报找不到某个测试类,其实只是 autoloader 映射指向了并不存在的文件。

















