Каковы различия между PSR-0 и PSR-4?

225

Недавно я прочитал о пространствах имен и о том, как они полезны. В настоящее время я создаю проект в Laravel и пытаюсь перейти от автозагрузки карты классов к пространству имен. Тем не менее, я не могу понять, какая на самом деле разница между PSR-0 и PSR-4.

Некоторые ресурсы, которые я прочитал ...

Что я понимаю:

  • PSR-4 не преобразует подчеркивания в разделители каталогов
  • Некоторые конкретные правила композитора приводят к усложнению структуры каталогов, что, в свою очередь, делает многословным пространство имен PSR-0 и, таким образом, PSR-4 был создан

Примеры, объясняющие разницу, будут оценены.

Варун Натх
источник
3
Прочитайте PSR0 и PSR4 . Они объясняют каждую деталь.
Сверри М. Олсен
4
☝️ Кто-то должен напечатать суть этого в качестве ответа ... :)
deceze
1
ИМО, большинство частей в PSR - это то, что им НРАВИТСЯ, а не то, что ПРАВО ...
Юша Aleayoub

Ответы:

283

Они очень похожи, поэтому неудивительно, что это немного сбивает с толку. В итоге PSR-0 обладает некоторыми функциями обратной совместимости для имен классов в стиле PEAR, которые PSR-4 отбрасывает, так как он поддерживает только код пространства имен. Вдобавок к этому PSR-4 не заставляет вас иметь все пространство имен в качестве структуры каталогов, а только часть, следующую за точкой привязки.

Например, если вы определили, что Acme\Foo\пространство имен привязано src/, с PSR-0 это означает, что оно будет искать, Acme\Foo\Barв src/Acme/Foo/Bar.phpто время как в PSR-4 оно будет искать его src/Bar.php, обеспечивая более короткие структуры каталогов. С другой стороны, некоторые предпочитают иметь полную структуру каталогов, чтобы четко видеть, что находится в каком пространстве имен, так что вы также можете сказать, что Acme\Foo\это src/Acme/Fooс PSR-4, что даст вам эквивалент поведения PSR-0, описанного выше.

Короче говоря, для новых проектов и для большинства целей и целей, вы можете использовать PSR-4 и забыть все о PSR-0.

Seldaek
источник
17
Это выбирает, src/Bar.phpесли вы говоритеAcme\Foo\ => src/
Seldaek
Большое спасибо за объяснение!
尤川豪
4
PSR-4 медленнее, чем PSR-0, не так ли?
Нгуен Линь
2
@NguyenLinh Я так не думаю. Он делает то же самое, но, возможно, с меньшим количеством каталогов, так что на самом деле он может быть немного быстрее. Измерь это. Вы можете создать пакет, который вы можете переключать между PSR-0 и PSR-4 - я не думаю, что вы увидите разницу.
Свен
44

Вот основные различия,

1. Например, если вы определите, что Acme\Foo\пространство имен привязано src/,

  • с PSR-0 это означает, что он будет искать Acme\Foo\Barвsrc/Acme/Foo/Bar.php
  • в то время как в PSR-4 он будет искать Acme\Foo\Barв src/Bar.php(where Bar class is).

2. PSR-4 не преобразует подчеркивания в разделители каталогов

3. Вы бы предпочли использовать PSR-4 с пространствами имен

4. PSR-0 не будет работать, даже если имя класса отличается от имени файла, как в примере выше:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (для класса Бар) будет работать
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(для класса Bar) работать не будет
Адиль Аббаси
источник
1
Вы, безусловно, можете использовать PSR-4 без сценариев пространства имен, такого ограничения нет, и я его использую (не мой выбор)
Galvani
В вашем 1. (первом пункте), откуда появился Бар для дела PSR-4?
cjmling
31

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/

wbswjc
источник
10

Соглашение о пространстве имен / папок.

Классы должны храниться в папках в соответствии с их пространствами имен.

В общем случае вы создадите каталог 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/"
        }
} 
  • Ищу Книгу \ Историю \ UnitedStates в src / Book /History/UnitedStates.php
  • Ищу Автомобиль \ Воздух \ Крылья \ Самолет в src / Автомобиль /Air/Wings/Airplane.php

PSR-4

Глядя на vendor/composer/autoload_psr4.phpфайл, вы можете видеть пространства имен и каталоги, в которые они отображаются.

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Находясь в поиске книгу \ История \ Соединенные Штаты в src /History/UnitedStates.php
  • Ищу Автомобиль \ Воздух \ Крылья \ Самолет в src /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Ищу книгу \ История \ UnitedStates src / Book /History/UnitedStates.php
  • Ищу Автомобиль \ Воздух \ Крылья \ Самолет в src / Автомобиль /Air/Wings/Airplane.php
Удхав Сарваия
источник
-4

Даже когда я пытался, но Composer это беспорядок. К сожалению, это единственная альтернатива рынка.
Почему беспорядок?
Автозаполнение Composer работает нормально, если вы контролируете код. Однако, если вы импортируете другой проект, вы обнаружите множество стилей и способов создания папок. Например, некоторые проекты /company/src/class.php, в то время как другие - company / class.php, а другие - company / src / class / class.php

Я создал библиотеку, которая решает это:

https://github.com/EFTEC/AutoLoadOne (это бесплатно, MIT).

Он генерирует автоинклюзию путем сканирования всех классов папки, поэтому он работает в каждом случае (psr-0 psr-4, классы без пространства имен, файл с несколькими классами).

Редактировать: И снова, без голосования. ;-)

Магеллана
источник
Узнайте больше о параметре classmap в composer.json. getcomposer.org/doc/04-schema.md#classmap - может быть причиной для понижения вашего ответа.
Патрик