PSR-4的当前约定是将src
文件夹命名为Vendor\Package
。然后使用目录结构对其中的任何文件进行命名空间。所以
src/Model/MyModel.php
用途
namespace Vendor\Package\Model;
class MyModel {...}
这对于src
文件夹中的任何文件夹都很直观,但与src
在同一级别上的文件夹的惯例是什么?例如tests
,public
,config
等等
(据我所知,有些人会对命名空间测试的观点发表评论,但想象一个大型项目,其中包含许多单独的软件包,每个软件包都有自己的测试,但可以在软件包之间重复使用。)
我已经看到了使用Vendor\Package\Tests
的建议,但对我来说,遵循src
约定,这会给人的印象是Tests
中有src
个文件夹,不是这样的。虽然如果 Tests
中的src
文件夹,那么这些名称空间会发生冲突吗?
答案 0 :(得分:4)
命名空间应该将逻辑上和语义上属于的代码分组。在我看来,配置,路由器和测试都作为整体应用程序的一部分在一起,因此我的配置往往让它们共享命名空间:
autoload: { "psr-4": { "Vendor\\Package\\": [ "public", "conf", "src" ] } }
autoload-dev: { "psr-4": { "Vendor\\Package\\": [ "tests" ] } }
当然,通过共享命名空间,这意味着必须对每个工件进行分类(通常通过其" kind")来防止类名冲突。例如,Vendor\Package\Foo
可能涉及以下相关工件:
Vendor\Package\FooTest
,tests/FooTest.php
Vendor\Package\FooIntegrationTest
,一个专门涵盖tests/FooIntegrationTest.php
Vendor\Package\AbstractFoo
,src/AbstractFoo.php
Vendor\Package\Fooable
,src/Fooable.php
沿着这些方向,您可能会考虑将不同类型的代码分离到不同的目录中,而不是一个" 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的认知负担意味着编写测试的工作量增加,这降低了我编写测试的愿望。因此,您可能会说在源和测试之间共享命名空间会降低编写测试的障碍。
最后,源代码组织的问题确实属于每个项目,以建立促进有效开发和合理构建的布局。我说如果尝试一个就不会受到伤害,如果不能解决则重构。