ChatGPT解决这个技术问题 Extra ChatGPT

PSR-0 和 PSR-4 有什么区别?

最近我读到了命名空间以及它们如何有益。我目前正在 Laravel 中创建一个项目,并尝试从类映射自动加载转移到命名空间。但是,我似乎无法掌握 PSR-0 和 PSR-4 之间的实际区别。

我读过的一些资源是......

自动装弹机之战

Laracasts PSR-4 自动加载

PSR-0

PSR-4

我的理解:

PSR-4 不会将下划线转换为目录分隔符

composer 的某些特定规则导致目录结构变得复杂,这反过来又使 PSR-0 命名空间变得冗长,因此创建了 PSR-4

解释差异的示例将不胜感激。

阅读 PSR0PSR4。他们解释了每一个细节。
☝️ 有人应该输入这个要点作为答案...... :)
IMO,PSR 中的大部分内容是关于他们喜欢什么,而不是什么是正确的......

A
Alex_Nabu

它们非常相似,因此有点令人困惑也就不足为奇了。总结是 PSR-0 对 PSR-4 删除的 PEAR 样式类名有一些向后兼容的特性,因此它只支持命名空间代码。除此之外,PSR-4 并不强制您将整个命名空间作为目录结构,而只是将锚点之后的部分。

例如,如果您定义 Acme\Foo\ 命名空间锚定在 src/ 中,使用 PSR-0 表示它将在 src/Acme/Foo/Bar.php 中查找 Acme\Foo\Bar,而在 PSR-4 中它将在 src/Bar.php 中查找它,允许更短的目录结构。另一方面,有些人更喜欢拥有完整的目录结构以清楚地查看哪个名称空间中的内容,因此您也可以说 Acme\Foo\ 与 PSR-4 位于 src/Acme/Foo 中,这将为您提供与 PSR-0 相同的功能上述行为。

长话短说,对于新项目以及大多数意图和目的,您可以使用 PSR-4 而忘记 PSR-0。


如果您说 Acme\Foo\ => src/,它会选择 src/Bar.php
非常感谢您的解释!
PSR-4 比 PSR-0 慢,不是吗?
@NguyenLinh 我不这么认为。它做同样的事情,但可能使用更少的目录级别,因此它实际上可能会更快一些。测量它。您可以创建一个可以在 PSR-0 和 PSR-4 之间切换的包 - 我认为您不会看到差异。
A
Adil Abbasi

以下是主要区别,

1. 例如,如果您定义 Acme\Foo\ 命名空间锚定在 src/ 中,

使用 PSR-0 意味着它将在 src/Acme/Foo/Bar.php 中查找 Acme\Foo\Bar

而在 PSR-4 中,它将在 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 而没有命名空间脚本,没有这样的限制,我确实使用它(不是我的选择)
在您的 1.(第一点)中,对于 PSR-4 案例,Bar 是从哪里来的?
w
wbsnail

PSR-4 类似于“相对路径”、PSR-0、“绝对路径”。

例如

配置:

'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/


U
Udhav Sarvaiya

命名空间/文件夹约定。

类应根据其名称空间存储在文件夹中。

通常,您将在根文件夹中创建一个 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 文件,您可以看到名称空间和它们映射到的目录。

作曲家.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 

在 src/Book/History/UnitedStates.php 中寻找 Book\History\UnitedStates

在 src/Vehicle/Air/Wings/Airplane.php 中寻找 Vehicle\Air\Wings\Airplane

psr-4

查看 vendor/composer/autoload_psr4.php 文件,您可以看到名称空间和它们映射到的目录。

作曲家.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   

在 src/History/UnitedStates.php 中寻找 Book\History\UnitedStates

在 src/Air/Wings/Airplane.php 中寻找 Vehicle\Air\Wings\Airplane

作曲家.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    

寻找 Book\History\UnitedStates src/Book/History/UnitedStates.php

在 src/Vehicle/Air/Wings/Airplane.php 中寻找 Vehicle\Air\Wings\Airplane


挣扎了一段时间,直到这篇文章。非常感谢您提供简洁的示例!
m
magallanes

即使我尝试过,但 Composer 还是一团糟。可悲的是,它是市场的唯一选择。为什么乱七八糟。。如果您可以控制代码,则 Composer 的自动完成功能可以正常工作。但是,如果您要导入不同的项目,您会发现自己有很多样式和方法来创建文件夹。例如,有些项目是 /company/src/class.php,而有些项目是 company/class.php,有些项目是 company/src/class/class.php

我创建了一个解决它的库:

https://github.com/EFTEC/AutoLoadOne(它是免费的,麻省理工学院)。

它通过扫描文件夹的所有类来生成自动包含,因此它适用于每种情况(psr-0 psr-4,没有命名空间的类,具有多个类的文件..

编辑:再一次,毫无理由地被否决。 ;-)


阅读 composer.json 中的 classmap 选项。 getcomposer.org/doc/04-schema.md#classmap - 可能是对您的答案投反对票的原因。
@Patrick 我看了他的图书馆。这是一个有趣的方法。我的意思是,对我来说,避免作曲家的类图太过分了,但没关系。