具有相同命名空间的不同 Composer 包

Posted

技术标签:

【中文标题】具有相同命名空间的不同 Composer 包【英文标题】:Different Composer packages with same namespace 【发布时间】:2014-09-27 01:44:58 【问题描述】:

简介

我正在使用 Laravel 4 并且有两个具有相同命名空间的作曲家包,使用 PSR-0 自动加载。 composer.json文件的简化示意图如下。

Laravel 应用 composer.json


    "require": 
        "laravel/framework": "4.2.*",
        "xxxxx/packageA": "1.2.0"
    

xxxxx/packageA composer.json


    "require": 
        "xxxxx/packageB": "~2.1.0"
    ,
    "autoload": 
        "psr-0": 
            "NS": "src/"
        
    

xxxxx/packageB composer.json


    "autoload": 
        "psr-0": 
            "NS": "src/"
        
    

问题

所以,xxxxx/packageAxxxxx/packageBsrc 目录中都有一个 NS 命名空间。这行得通吗?我收到一条错误消息,提示找不到该类 NS\\X。这是对具有相同命名空间的包的 Composer 限制,还是这很好,我的代码中有错误?

【问题讨论】:

【参考方案1】:

出于性能原因,您应该尽量避免定义相同的前缀两次。

从技术上讲,Composer 没有为两个包定义相同前缀的目录的问题。但这会强制 Composer 首先检查其中一个目录是否包含该类。失败时,它会检查第二个。

Composer 尝试记住这些未命中,但结果仅在单个脚本运行期间使用,然后被遗忘。

假设您声明"NS":"src/",则将在src/NS/X.php 中搜索类名NS\X。但是,如果您更有可能拥有类 NS\X\ANS\Y\B,则可以定义两个较长的前缀 NS\XNS\Y,而不是单个较短的前缀 NS。如果您只在 NS 前缀内托管一个类,您也可以使用整个类名作为前缀。

始终尝试使前缀尽可能长且尽可能精确。它们是命名空间是有原因的,每个命名空间应该只负责一个包。拥有两个为NS 托管类的包将很难检测到重叠:如果创建了两个具有完全相同名称的类怎么办?每个包使用不同的命名空间,这不会发生。

【讨论】:

感谢您的解释:) @Sven,假设我有以下内容:一组标准接口,这些接口的一些方法的抽象实现,以及基于抽象的完整实现。它们都与一个“事物”相关,它们直接相关,但我想将它们保存在单独的包中 - 因为我想单独分发/使用它们。这是 OP 要求的正当理由吗?

以上是关于具有相同命名空间的不同 Composer 包的主要内容,如果未能解决你的问题,请参考以下文章

Composer 生成大小写错误的命名空间

处理 R 中冲突的命名空间(不同包中的相同函数名):重置包命名空间的优先级

ejabberd:并行处理具有不同命名空间的多个数据包

具有相同命名空间但在不同程序集中的内部类?

如何拥有两个具有不同命名空间和相同 JAXB 类的不同端点?

如何在没有 Composer 作为依赖项(PSR-0)的情况下使用具有命名空间的 PHP 库?