最近我阅读了关于命名空间及其益处的文章。我的项目正在使用Laravel框架,我试图从类映射自动加载转移到命名空间。然而,我似乎不太理解PSR-0和PSR-4之间的实际区别。
我阅读的一些资源包括:
我的理解:
- PSR-4不会将下划线转换为目录分隔符
- Composer的某些特定规则导致目录结构变得复杂,进而使得PSR-0命名空间冗长,因此才出现了PSR-4
希望能有例子来解释它们之间的差异。
最近我阅读了关于命名空间及其益处的文章。我的项目正在使用Laravel框架,我试图从类映射自动加载转移到命名空间。然而,我似乎不太理解PSR-0和PSR-4之间的实际区别。
我阅读的一些资源包括:
我的理解:
希望能有例子来解释它们之间的差异。
Acme\Foo\
命名空间在 src/
中,则在使用PSR-0时,它意味着它将在 src/Acme/Foo/Bar.php
中查找 Acme\Foo\Bar
,而在PSR-4中它将在src/Bar.php
中查找,从而允许使用更短的目录结构。另一方面,一些人喜欢具有完整的目录结构以清晰地看到哪个命名空间中的内容,因此您还可以说Acme\Foo\
在 src/Acme/Foo
中使用PSR-4来获得上述PSR-0行为的等效结果。Acme\Foo\ => src/
,它会选择 src/Bar.php
。 - Seldaek以下是主要区别:
1. 例如,如果您定义了Acme\Foo\
命名空间在src/
中,则:
src/Acme/Foo/Bar.php
中的Acme\Foo\Bar
src/Bar.php(其中Bar类位于)
中查找Acme\Foo\Bar
。2. PSR-4不会将下划线转换为目录分隔符
3. 您可能更喜欢使用带有命名空间的PSR-4
4. 即使类名与文件名不同,例如上面的示例,PSR-0也无法工作:
Acme\Foo\Bar
---> src/Acme/Foo/Bar.php
(用于Bar类)将起作用Acme\Foo\Bar
---> src/Acme/Foo/Bar2.php
(用于Bar类)将不起作用PSR-4类似于“相对路径”,而PSR-0则是“绝对路径”。
例如:
config:
'App\Controller' => 'dir/'
PSR-0 自动加载:
App\Controller\IndexController --> dir/App/Controller/IndexController.php
PSR-4自动加载:
App\Controller\IndexController --> dir/IndexController.php
PSR-0和PSR-4之间还有一些细节上的不同,请在这里查看:http://www.php-fig.org/psr/psr-4/
命名空间/文件夹惯例。
类应该按照它们的命名空间存储在文件夹中。
通常,您会在根文件夹中创建一个src/目录,与vendor/处于同一级别,并将项目添加到其中。以下是文件夹结构示例:
.
+-- src
|
+-- Book
| +-- History
| | +-- UnitedStates.php - namespace Book\History;
+-- Vehicle
| +-- Air
| | +-- Wings
| | | +-- Airplane.php - namespace Vehicle\Air\Wings;
| +-- Road
| | +-- Car.php - namespace Vehicle\Road;
+-- tests
+-- test.php
+-- vendor
psr-0和psr-4的区别
psr-0
该标准已经被弃用。查看vendor/composer/autoload_namespaces.php
文件,您可以看到命名空间及其映射到的目录。
composer.json
"autoload": {
"psr-0": {
"Book\\": "src/",
"Vehicle\\": "src/"
}
}
psr-4
查看 vendor/composer/autoload_psr4.php
文件,可以看到命名空间和它们映射到的目录。
composer.json
"autoload": {
"psr-4": {
"Book\\": "src/",
"Vehicle\\": "src/"
}
}
composer.json
"autoload": {
"psr-4": {
"Book\\": "src/Book/",
"Vehicle\\": "src/Vehicle/"
}
}
即使我尝试过,但Composer仍然很混乱。可悲的是,这是市场上唯一的选择。
为什么会这样呢?
如果您控制代码,则Composer的自动完成功能正常运行。但是,如果您导入不同的项目,则会发现有许多样式和创建文件夹的方法。例如,某些项目是/company/src/class.php,而其他项目是company/class.php,还有其他项目是company/src/class/class.php
我创建了一个解决方案库:
https://github.com/EFTEC/AutoLoadOne(它是免费的,MIT许可证)。
它通过扫描文件夹中的所有类来生成自动包含,因此在每种情况下都可以使用(psr-0 psr-4,没有命名空间的类,具有多个类的文件等)。
编辑:再次被投票否决,没有任何理由。;-)