composer psr-4自动加载要求命名空间以双反斜杠结尾、路径相对且不以/开头,命名空间、目录结构、类名、composer.json配置四者必须严格大小写一致,修改后需执行composer dump-autoload生效。

autoload 配置必须用 PSR-4,且命名空间不能耦合框架
跨框架通用的前提是:包本身不依赖任何特定框架的类或生命周期机制。一旦你在 composer.json 的 autoload 里写 "Topthink\": "src/thinkphp/" 或 "Illuminate\": "src/laravel/",这个包就锁死在对应生态里了。
正确做法是定义一个独立、语义清晰的根命名空间,比如 "Hoo\Tool\" 或 "Acme\Utils\",并严格映射到 src/。所有类都放在这里,不引入 thinkacadeApp、IlluminateSupportServiceProvider 这类框架专属类。
- 错误示例:
"autoload": {"psr-4": {"App\": "src/app/"}}(App是 Laravel 默认命名空间,极易冲突) - 正确示例:
"autoload": {"psr-4": {"Hoo\Tool\": "src/"}} - 如果包内有工具类、DTO、异常类、纯函数封装,它们天然适合跨框架;但一旦出现
$app->bind()或$this->app['router'],就已丧失通用性
不要在包里写 service provider,除非你提供可选的桥接层
Service provider 是 Laravel/ThinkPHP/Yii 等框架的注册机制,不是 Composer 标准。直接在包里硬编码 DemoServiceProvider 并声明到 composer.json 的 extra.laravel.providers,等于主动放弃对其他框架的支持。
真正通用的做法是:把核心逻辑完全剥离,只在 src/ 提供可手动调用的类和方法;如果想适配某框架,另建一个“桥接包”或在文档里写清楚如何手动注册——比如在 ThinkPHP 的 app.php 里手动 bind,在 Laravel 的 AppServiceProvider 里手动 bind。
- 包自身
composer.json中不要出现extra.laravel、extra.thinkphp等字段 - 不提供
src/Providers/目录,也不在src/里放继承ServiceProvider的类 - 若真要支持自动发现,可额外发布一个
acme/utils-laravel子包,专门做 Laravel 适配,主包保持干净
require 字段只约束 PHP 版本和真正依赖的库
很多开发者一上来就在 require 里加 "topthink/framework": "^8.0" 或 "illuminate/support": "^10.0",这是最典型的自废武功行为。这些依赖会让 Composer 强制拉取整个框架,不仅体积爆炸,还会引发版本冲突——比如你的包要求 Laravel 10,而用户项目用的是 Laravel 9。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
通用包的 require 应该极简:
- 必须有:
"php": ">=8.0"(按实际支持的最低版本写) - 可选有:
"ext-json": "*"、"psr/log": "^3.0"这类广泛兼容的接口规范包 - 绝对不要有框架本体、ORM、HTTP 客户端等具体实现依赖
- 如果确实需要日志能力,依赖
psr/log接口,而不是monolog/monolog具体实现
本地开发时用 path repository,别碰 composer link
跨框架验证包是否真能通用,必须在多个真实项目里跑一遍。这时候你得让 Laravel 项目、ThinkPHP 项目、纯 PHP CLI 项目都能加载你正在写的代码,而不是每次改完都要 composer update 发布再安装。
唯一稳定的方式是在各个测试项目的 composer.json 里加 path 源:
"repositories": [
{
"type": "path",
"url": "../my-universal-package"
}
]
然后运行 composer require acme/utils:@dev。Composer 会创建 symlink,所有修改实时可见。注意两点:
-
@dev必须加,否则可能 fallback 到 Packagist 上已发布的旧版 - Windows 用户尤其要避开
composer link,它在 Laravel 10+ 下大概率导致 autoload 冲突,报Class not found却找不到原因 - 每次切换测试项目后,记得运行
composer dump-autoload确保映射刷新
跨框架通用不是靠“兼容所有”,而是靠“不依赖任何”。越早砍掉框架绑定,后期维护成本越低;越晚意识到 extra 字段和 service provider 是枷锁,就越容易把包做成半吊子框架专用包。










