最近我读到了命名空间以及它们是如何有益的。我目前正在 Laravel 中创建一个项目,并尝试从类映射自动加载移动到命名空间。但是,我似乎无法理解PSR-0和PSR-4之间的实际区别。
我读过的一些资源是...
- 自动装填机之战
- 拉拉卡斯PSR-4自动加载
- PSR-0
- PSR-4
我的理解:
- PSR-4 不会将下划线转换为目录分隔符
- 作曲家的某些特定规则会导致目录结构变得复杂,这反过来又使 PSR-0 命名空间变得冗长,因此创建了 PSR-4
举例说明差异将不胜感激。
它们非常相似,所以有点令人困惑也就不足为奇了。总结一下,PSR-0 对 PSR-4 删除的 PEAR 样式类名具有一些向后兼容性功能,因此它仅支持命名空间代码。最重要的是,PSR-4 不会强制您将整个命名空间作为目录结构,而只会将锚点后面的部分作为目录结构。
例如,如果您定义AcmeFoo
命名空间锚定在 src/
中,PSR-0 表示它将在src/Acme/Foo/Bar.php
中查找AcmeFooBar
,而在 PSR-4 中它将在 src/Bar.php
中查找它,允许更短的目录结构。另一方面,有些人更喜欢拥有完整的目录结构来清楚地看到哪个命名空间中的内容,因此您也可以说AcmeFoo
与 PSR-4 src/Acme/Foo
,这将为您提供等效的上述 PSR-0 行为。
长话短说,对于新项目和大多数意图和目的,您可以使用PSR-4而忘记PSR-0的所有内容。
以下是主要区别,
1. 例如,如果您定义 AcmeFoo
命名空间锚定在 src/
中,
- 使用PSR-0,这意味着它将在
src/Acme/Foo/Bar.php
中寻找AcmeFooBar
- 而在PSR-4中,它将在
src/Bar.php(where Bar class is)
中寻找AcmeFooBar
.
2. PSR-4 不会将下划线转换为目录分隔符
3. 您希望将 PSR-4 与命名空间一起使用
4. 即使类名与文件名不同,PSR-0 也不起作用,就像考虑上面的例子一样:
-
AcmeFooBar
--->src/Acme/Foo/Bar.php
(对于酒吧类(将起作用 -
AcmeFooBar
--->src/Acme/Foo/Bar2.php
(对于酒吧类(将不起作用
PSR-4 类似于"相对路径",PSR-0,"绝对路径"。
例如
配置:
'AppController' => 'dir/'
PSR-0 自动加载:
AppControllerIndexController --> dir/App/Controller/IndexController.php
PSR-4 自动加载:
AppControllerIndexController --> dir/IndexController.php
PSR-0和PSR-4之间在细节上还有更多差异,请参见此处:http://www.php-fig.org/psr/psr-4/
命名空间/文件夹约定。
类应根据其命名空间存储在文件夹中。
通常,您将在根文件夹中创建一个 src/目录,与 vendor/位于同一级别,并在那里添加您的项目。下面是文件夹结构的示例:
.
+-- src
|
+-- Book
| +-- History
| | +-- UnitedStates.php - namespace BookHistory;
+-- Vehicle
| +-- Air
| | +-- Wings
| | | +-- Airplane.php - namespace VehicleAirWings;
| +-- Road
| | +-- Car.php - namespace VehicleRoad;
+-- tests
+-- test.php
+-- vendor
PSR-0和PSR-4之间的区别
PSR-0
它已被弃用。查看vendor/composer/autoload_namespaces.php
文件,您可以看到命名空间及其映射到的目录。
作曲家.json
"autoload": {
"psr-0": {
"Book\": "src/",
"Vehicle\": "src/"
}
}
- 在src/Book/History/United States中查找Book\History\United States.php
- 在src/vehicle/air/wing/plane中寻找车辆\空气\机翼\飞机.php
PSR-4
查看vendor/composer/autoload_psr4.php
文件,您可以看到命名空间及其映射到的目录。
作曲家.json
"autoload": {
"psr-4": {
"Book\": "src/",
"Vehicle\": "src/"
}
}
- 在src/History/United States中查找书籍\历史\美国.php
- 在src/air/wing/plane中寻找车辆\空气\机翼\飞机.php
作曲家.json
"autoload": {
"psr-4": {
"Book\": "src/Book/",
"Vehicle\": "src/Vehicle/"
}
}
- 查找 Book\History\United States
- src/Book/History/United States.php
- 在src/vehicle/air/wing/plane中寻找车辆\空气\机翼\飞机.php
即使我尝试过,但作曲家是一团糟。 可悲的是,这是市场的唯一选择。
为什么一团糟?。
如果您控制代码,则编辑器的自动完成功能可以正常工作。但是,如果您要导入其他项目,您会发现自己有很多样式和创建文件夹的方法。 例如,一些项目是/company/src/class.php而另一些是 company/class.php而另一些是 company/src/class/class.php
我创建了一个解决它的库:
https://github.com/EFTEC/AutoLoadOne(它是免费的,麻省理工学院(。
它通过扫描文件夹的所有类来生成自动包含,因此它可以在每种情况下工作(psr-0 psr-4,没有命名空间的类,具有多个类的文件(。
编辑:再一次,没有任何理由地投了反对票。