Jakie są różnice między PSR-0 a PSR-4?


225

Ostatnio czytałem o przestrzeniach nazw i ich zaletach. Obecnie tworzę projekt w Laravel i próbuję przejść z automatycznego ładowania map klas do przestrzeni nazw. Wydaje mi się jednak, że nie rozumiem, jaka jest rzeczywista różnica między PSR-0 a PSR-4.

Niektóre zasoby, które przeczytałem to ...

Co rozumiem:

  • PSR-4 nie konwertuje znaków podkreślenia na separatory katalogów
  • Pewne szczególne reguły kompozytora powodują, że struktura katalogów staje się złożona, co z kolei powoduje, że przestrzeń nazw PSR-0 jest pełna, a zatem PSR-4 został utworzony

Docenione zostaną przykłady wyjaśniające różnicę.


3
Czytaj PSR0 i PSR4 . Wyjaśniają każdy szczegół.
Sverri M. Olsen


4
☝️ Ktoś powinien wpisać sedno tego jako odpowiedź ... :)
deceze

1
IMO, większość części w PSR dotyczy tego, co im się nie podoba, a co jest PRAWE ...
Yousha Aleayoub,

Odpowiedzi:


283

Są bardzo podobne, więc nic dziwnego, że jest to trochę mylące. Podsumowując, PSR-0 miał pewne funkcje kompatybilności wstecznej dla nazw klas w stylu PEAR, które PSR-4 upuścił, dlatego obsługuje tylko kod z przestrzenią nazw. Na dodatek PSR-4 nie zmusza cię do posiadania całej przestrzeni nazw jako struktury katalogów, a jedynie część po punkcie zakotwiczenia.

Na przykład, jeśli zdefiniujesz, że Acme\Foo\ przestrzeń nazw jest zakotwiczona w src/, z PSR-0 to oznacza, że będzie szukać Acme\Foo\Barw src/Acme/Foo/Bar.phpnatomiast w PSR-4 będzie szukać w src/Bar.php, pozwalając na krótszych struktur katalogów. Z drugiej strony niektórzy wolą mieć pełną strukturę katalogów, aby wyraźnie zobaczyć, w jakiej przestrzeni nazw, więc możesz też powiedzieć, że Acme\Foo\jest w src/Acme/FooPSR-4, który da ci równoważne zachowanie PSR-0 opisane powyżej.

Krótko mówiąc o nowych projektach oraz większości zamierzeń i celów, możesz użyć PSR-4 i zapomnieć o PSR-0.


17
Znalazło src/Bar.phpjeśli powieszAcme\Foo\ => src/
Seldaek

Dziękuję bardzo za wyjaśnienie!
尤川豪

4
PSR-4 jest wolniejszy niż PSR-0, prawda?
Nguyen Linh

2
@NguyenLinh Nie sądzę. Robi to samo, ale możliwe, że ma mniej poziomów katalogów, więc może być nieco szybszy. Zmierz to. Możesz stworzyć pakiet, który możesz przełączać między PSR-0 i PSR-4 - nie sądzę, żebyś zobaczył różnicę.
Sven

44

Oto główne różnice,

1. Na przykład, jeśli zdefiniujesz, że Acme\Foo\przestrzeń nazw jest zakotwiczona src/,

  • z PSR-0 oznacza, że ​​będzie szukał Acme\Foo\Barwsrc/Acme/Foo/Bar.php
  • podczas gdy w PSR-4 będzie szukał Acme\Foo\Barw src/Bar.php(where Bar class is).

2. PSR-4 nie konwertuje podkreśleń na separatory katalogów

3. Wolisz używać PSR-4 z przestrzeniami nazw

4. PSR-0 nie będzie działać, nawet jeśli nazwa klasy jest inna niż nazwa pliku, podobnie jak w powyższym przykładzie:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (dla klasy Bar) będzie działać
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(dla klasy Bar) nie będzie działać

1
Z pewnością możesz używać PSR-4 bez skryptów przestrzeni nazw, nie ma takiego ograniczenia i ja go używam (nie mój wybór)
Galvani,

W twoim 1. (pierwszym punkcie) skąd wziął się Bar dla skrzynki PSR-4?
cjmling

31

PSR-4 to coś w rodzaju „ścieżki względnej”, PSR-0, „ścieżki absolutnej”.

na przykład

config:

'App\Controller' => 'dir/'

Automatyczne ładowanie PSR-0 :

App\Controller\IndexController --> dir/App/Controller/IndexController.php

Automatyczne ładowanie PSR-4 :

App\Controller\IndexController --> dir/IndexController.php

I jest jeszcze więcej różnic w szczegółach między PSR-0 i PSR-4, patrz tutaj: http://www.php-fig.org/psr/psr-4/


10

Konwencja przestrzeni nazw / folderów.

Klasy powinny być przechowywane w folderach zgodnie z ich przestrzeniami nazw.

Ogólnie rzecz biorąc, utworzysz katalog src / w folderze głównym na tym samym poziomie co dostawca / i dodasz tam swoje projekty. Poniżej znajduje się przykład struktury folderów:

.
+-- 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

Różnica między psr-0 i psr-4

psr-0

To jest przestarzałe. Patrząc na vendor/composer/autoload_namespaces.phpplik, możesz zobaczyć przestrzenie nazw i katalogi, na które są mapowane.

composer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • Szukasz Book \ History \ UnitedStates w src / Book /History/UnitedStates.php
  • Poszukuje pojazdu \ Air \ Wings \ Airplane w src / Vehicle /Air/Wings/Airplane.php

psr-4

Patrząc na vendor/composer/autoload_psr4.phpplik, możesz zobaczyć przestrzenie nazw i katalogi, na które są mapowane.

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Szukasz Book \ History \ UnitedStates w src /History/UnitedStates.php
  • Poszukiwanie pojazdu \ Air \ Wings \ Airplane w src /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Szukasz Book \ History \ UnitedStates src / Book /History/UnitedStates.php
  • Poszukuje pojazdu \ Air \ Wings \ Airplane w src / Vehicle /Air/Wings/Airplane.php

-4

Nawet kiedy próbowałem, ale Kompozytor to bałagan. Niestety, jest to jedyna alternatywa na rynku.
Dlaczego bałagan?
Autouzupełnianie kompozytora działa dobrze, jeśli masz kontrolę nad kodem. Jeśli jednak importujesz inny projekt, znajdziesz wiele stylów i sposobów tworzenia folderów. Na przykład niektóre projekty to /company/src/class.php, podczas gdy inne to company / class.php, a inne to company / src / class / class.php

Stworzyłem bibliotekę, która to rozwiązuje:

https://github.com/EFTEC/AutoLoadOne (za darmo, MIT).

Generuje autowyłączanie poprzez skanowanie wszystkich klas folderu, więc działa w każdym przypadku (psr-0 psr-4, klasy bez przestrzeni nazw, plik z wieloma klasami ..

edytuj: I ponownie, przegłosowano bez żadnego powodu. ;-)


Przeczytaj o opcji map klas w composer.json. getcomposer.org/doc/04-schema.md#classmap - może być powodem odrzucenia twojej odpowiedzi.
Patrick
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.