与src相同级别的文件夹的PSR-4命名空间约定

时间:2016-10-28 13:10:34

标签: php composer-php psr-4

PSR-4的当前约定是将src文件夹命名为Vendor\Package。然后使用目录结构对其中的任何文件进行命名空间。所以

src/Model/MyModel.php

用途

namespace Vendor\Package\Model;

class MyModel {...}

这对于src文件夹中的任何文件夹都很直观,但与src在同一级别上的文件夹的惯例是什么?例如testspublicconfig等等

(据我所知,有些人会对命名空间测试的观点发表评论,但想象一个大型项目,其中包含许多单独的软件包,每个软件包都有自己的测试,但可以在软件包之间重复使用。)

我已经看到了使用Vendor\Package\Tests的建议,但对我来说,遵循src约定,这会给人的印象是Tests中有src个文件夹,不是这样的。虽然如果 Tests中的src文件夹,那么这些名称空间会发生冲突吗?

1 个答案:

答案 0 :(得分:4)

命名空间应该将逻辑上和语义上属于的代码分组。在我看来,配置,路由器和测试都作为整体应用程序的一部分在一起,因此我的配置往往让它们共享命名空间:

autoload: { "psr-4": { "Vendor\\Package\\": [ "public", "conf", "src" ] } }
autoload-dev: { "psr-4": { "Vendor\\Package\\": [ "tests" ] } }

当然,通过共享命名空间,这意味着必须对每个工件进行分类(通常通过其" kind")来防止类名冲突。例如,Vendor\Package\Foo可能涉及以下相关工件:

  • Vendor\Package\FooTesttests/FooTest.php
  • 中foo的单元测试
  • Vendor\Package\FooIntegrationTest,一个专门涵盖tests/FooIntegrationTest.php
  • 中foo的集成测试
  • Vendor\Package\AbstractFoosrc/AbstractFoo.php
  • 中foo家庭成员的基础
  • Vendor\Package\Fooablesrc/Fooable.php
  • 中foo类型的界面

沿着这些方向,您可能会考虑将不同类型的代码分离到不同的目录中,而不是一个" catch-all" src。对于大型项目,这使得查找特定类型的文件更容易,但对于库或小型应用程序来说可能有点过分:

autoload: { 
    "psr-4": {
        "Vendor\\Package\\": [
            "public", "conf", "lib", "view", "contract", "exception"
        ]
    }
}

至于"约定",我特别发现在源代码和测试之间共享命名空间是方便和容易的,因为当我想测试Foo时,我不必去处理命名空间来获取它。

// tests/Something/FooTest.php
namespace Vendor\Package\Test\Something;
use Vendor\Package\Test\BaseTestCase;
use Vendor\Package\Something\Foo; // extra work I don't want to do

class FooTest extends BaseTestCase {
    public function testX() {
        $sut = new Foo;
    }
}

每个测试文件中都有一行,加上在编写测试时必须找到SUT的认知负担意味着编写测试的工作量增加,这降低了我编写测试的愿望。因此,您可能会说在源和测试之间共享命名空间会降低编写测试的障碍。

最后,源代码组织的问题确实属于每个项目,以建立促进有效开发和合理构建的布局。我说如果尝试一个就不会受到伤害,如果不能解决则重构。