最近,我读了一些关于名称空间及其益处的文章。我目前正在Laravel中创建一个项目,并试图从类映射自动加载到命名空间。然而,我似乎无法理解PSR-0和PSR-4之间的实际区别。

我读过的一些资源是…

自动装弹机之战 laracsts PSR-4自动装填 PSR-0 PSR-4

我的理解是:

PSR-4不将下划线转换为目录分隔符 编写器的某些特定规则会导致目录结构变得复杂,从而使PSR-0名称空间变得冗长,因此创建了PSR-4

请举例说明其区别。


当前回答

它们非常相似,所以有点令人困惑也就不足为奇了。总的来说,PSR-0为pear风格的类名提供了一些向后兼容的特性,而PSR-4放弃了这些特性,因此它只支持命名空间代码。在此基础上,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行为。

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

其他回答

这是主要的区别,

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

PSR-0意味着它将在src/Acme/Foo/Bar.php中查找Acme\Foo\Bar 而在PSR-4中,它将在src/Bar.php中查找Acme\Foo\Bar (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类)将不工作

命名空间/文件夹约定。

类应该根据它们的名称空间存储在文件夹中。

通常,您将在根文件夹中创建一个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/"
        }
} 

在src/Book/History/UnitedStates.php中查找Book\History\UnitedStates 在src/Vehicle/Air/Wings/ plane.php中查找Vehicle\Air\Wings\Airplane

psr-4

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

composer.json

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

在src/History/UnitedStates.php查找Book\History\UnitedStates 在src/Air/Wings/ plane.php中查找Vehicle\Air\Wings\Airplane

composer.json

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

查找Book\History\UnitedStates src/Book/History/UnitedStates.php 在src/Vehicle/Air/Wings/ plane.php中查找Vehicle\Air\Wings\Airplane

即使当我尝试,但作曲家是一个烂摊子。遗憾的是,这是唯一的选择。市场。 为什么是一团乱? 如果你能控制代码,Composer的自动补全功能就能正常工作。但是,如果您正在导入不同的项目,您会发现自己有很多样式和方法来创建文件夹。例如,有些项目是/company/src/class.php,有些是company/class.php,有些是company/src/class/class.php

我创建了一个库来解决这个问题:

https://github.com/EFTEC/AutoLoadOne(麻省理工学院免费提供)。

它通过扫描文件夹的所有类来生成一个自动包含,因此它可以在任何情况下工作(psr-0 psr-4,没有名称空间的类,包含多个类的文件..

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

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

e.g.

配置:

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

它们非常相似,所以有点令人困惑也就不足为奇了。总的来说,PSR-0为pear风格的类名提供了一些向后兼容的特性,而PSR-4放弃了这些特性,因此它只支持命名空间代码。在此基础上,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行为。

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