【问题标题】:What Are the Differences Between PSR-0 and PSR-4?PSR-0 和 PSR-4 有什么区别?
【发布时间】:2014-09-12 03:56:36
【问题描述】:

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

我读过的一些资源是……

我的理解:

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

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

【问题讨论】:

标签: php laravel composer-php psr-0 psr-4


【解决方案1】:

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

例如,如果您定义 Acme\Foo\ 命名空间锚定在 src/ 中,使用 PSR-0 意味着它将在 src/Acme/Foo/Bar.php 中查找 Acme\Foo\Bar,而在 PSR-4 中它将在 @ 中查找它987654325@,允许更短的目录结构。另一方面,有些人更喜欢拥有完整的目录结构以清楚地查看哪个名称空间中的内容,因此您也可以说 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 之间切换的包 - 我认为您不会看到区别。
【解决方案2】:

以下是主要区别,

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

  • 使用 PSR-0 意味着它将在 src/Acme/Foo/Bar.php 中查找 Acme\Foo\Bar
  • 在 PSR-4 中,它将在 src/Bar.php(where Bar class is) 中查找 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 是从哪里来的?
【解决方案3】:

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/

【讨论】:

    【解决方案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 文件,您可以看到命名空间和它们映射到的目录。

    作曲家.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 文件,您可以看到命名空间和它们映射到的目录。

    composer.json

    "autoload": {
        "psr-4": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
    }   
    
    • src/History/UnitedStates.php 中寻找 Book\History\UnitedStates
    • src/Air/Wings/Airplane.php 中寻找 Vehicle\Air\Wings\Airplane

    composer.json

    "autoload": {
        "psr-4": {
            "Book\\": "src/Book/",
            "Vehicle\\": "src/Vehicle/"
        }
    }    
    
    • 正在寻找图书\History\UnitedStates src/Book/History/UnitedStates.php
    • src/Vehicle/Air/Wings/Airplane.php 中寻找 Vehicle\Air\Wings\Airplane

    【讨论】:

    • 在这篇文章之前已经为此苦苦挣扎了一段时间。非常感谢您提供简洁的示例!
    【解决方案5】:

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

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

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

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

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

    【讨论】:

    猜你喜欢
    • 2015-01-08
    • 2014-07-25
    • 2019-02-11
    • 2012-07-16
    • 2016-12-05
    • 2014-04-07
    • 2013-01-26
    • 2014-01-10
    • 2020-05-30
    相关资源
    最近更新 更多