Was sind die Unterschiede zwischen PSR-0 und PSR-4?

225

Kürzlich habe ich über Namespaces gelesen und wie sie nützlich sind. Ich erstelle gerade ein Projekt in Laravel und versuche, vom automatischen Laden der Klassenzuordnung zum Namespace zu wechseln. Ich kann jedoch nicht verstehen, was der tatsächliche Unterschied zwischen PSR-0 und PSR-4 ist.

Einige Ressourcen, die ich gelesen habe, sind ...

Was ich verstehe:

  • PSR-4 konvertiert keine Unterstriche in Verzeichnistrennzeichen
  • Bestimmte spezifische Regeln des Komponisten führen dazu, dass die Verzeichnisstruktur komplex wird, was wiederum den PSR-0-Namespace ausführlich macht und somit PSR-4 erstellt wurde

Beispiele, die den Unterschied erklären, wären willkommen.

Varun Nath
quelle
3
Lesen Sie PSR0 und PSR4 . Sie erklären jedes einzelne Detail.
Sverri M. Olsen
4
☝️ Jemand sollte das Wesentliche als Antwort
eingeben
1
IMO, die meisten Teile in PSR handeln davon, was sie mögen, nicht was
richtig

Antworten:

282

Sie sind sich sehr ähnlich, daher ist es nicht verwunderlich, dass es etwas verwirrend ist. Die Zusammenfassung ist, dass PSR-0 einige Abwärtskompatibilitätsfunktionen für PEAR-artige Klassennamen hatte, die PSR-4 gelöscht hat, da es nur Code mit Namespace unterstützt. Darüber hinaus zwingt PSR-4 Sie nicht dazu, den gesamten Namespace als Verzeichnisstruktur zu verwenden, sondern nur den Teil, der dem Ankerpunkt folgt.

Zum Beispiel, wenn Sie definieren, dass der Acme\Foo\Namespace in verankert istsrc/ , mit PSR-0 bedeutet , es es aussehen wird Acme\Foo\Barin src/Acme/Foo/Bar.phpwährend in PSR-4 es für sie aussieht in src/Bar.php, so dass für kürzere Verzeichnisstrukturen. Auf der anderen Seite bevorzugen einige die vollständige Verzeichnisstruktur, um klar zu sehen, was sich in welchem ​​Namespace befindet. Sie können also auch sagen, dass Acme\Foo\sich dieser in befindetsrc/Acme/Foo mit PSR-4, werden Ihnen das Äquivalent des PSR-0 Verhaltens gibt oben beschrieben.

Kurz gesagt, für neue Projekte und für die meisten Absichten und Zwecke können Sie PSR-4 verwenden und alles über PSR-0 vergessen.

Seldaek
quelle
17
Es wählt, src/Bar.phpwenn Sie sagenAcme\Foo\ => src/
Seldaek
Vielen Dank für die Erklärung!
6.
4
PSR-4 ist langsamer als PSR-0, nicht wahr?
Nguyen Linh
2
@NguyenLinh Das glaube ich nicht. Es macht das Gleiche, aber möglicherweise mit weniger Verzeichnisebenen, so dass es tatsächlich etwas schneller sein kann. Messe Es. Sie können ein Paket erstellen, mit dem Sie zwischen PSR-0 und PSR-4 wechseln können. Ich glaube nicht, dass Sie einen Unterschied feststellen werden.
Sven
44

Hier sind die Hauptunterschiede,

1. Wenn Sie beispielsweise definieren, dass der Acme\Foo\Namespace in verankert ist src/,

  • mit PSR-0 bedeutet , es es aussehen wird Acme\Foo\Barinsrc/Acme/Foo/Bar.php
  • während in PSR-4 wird es aussehen Acme\Foo\Barin src/Bar.php(where Bar class is).

2. PSR-4 konvertiert keine Unterstriche in Verzeichnistrennzeichen

3. Sie würden es vorziehen, PSR-4 mit Namespaces zu verwenden

4. PSR-0 funktioniert auch dann nicht, wenn sich der Klassenname vom Dateinamen unterscheidet, wie im obigen Beispiel dargestellt:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (für Bar-Klasse) wird funktionieren
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(für Bar-Klasse) funktioniert nicht
Adil Abbasi
quelle
1
Sie können PSR-4 sicherlich zusammen mit Namespace-Skripten verwenden, es gibt keine solche Einschränkung und ich verwende sie (nicht meine Wahl)
Galvani
Woher kam Bar in Ihrem 1. (ersten Punkt) für den PSR-4-Fall?
cjmling
31

PSR-4 ist so etwas wie "relativer Pfad", PSR-0, "absoluter Pfad".

z.B

config:

'App\Controller' => 'dir/'

PSR-0 Autoload:

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

PSR-4 Autoload:

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

Weitere Detailunterschiede zwischen PSR-0 und PSR-4 finden Sie hier: http://www.php-fig.org/psr/psr-4/

wbswjc
quelle
10

Namespace / Ordner-Konvention.

Klassen sollten entsprechend ihren Namespaces in Ordnern gespeichert werden.

Im Allgemeinen erstellen Sie ein src / -Verzeichnis in Ihrem Stammordner, das sich auf derselben Ebene wie vendor / befindet, und fügen dort Ihre Projekte hinzu. Unten finden Sie ein Beispiel für die Ordnerstruktur:

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

Unterschied zwischen psr-0 und psr-4

psr-0

Es ist veraltet. Wenn vendor/composer/autoload_namespaces.phpSie sich die Datei ansehen, sehen Sie die Namespaces und die Verzeichnisse, denen sie zugeordnet sind.

composer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • Suchen Sie nach Buch \ History \ UnitedStates in src / Book /History/UnitedStates.php
  • Suchen Sie nach Fahrzeug \ Luft \ Flügel \ Flugzeug in src / Fahrzeug / Luft / Flügel / Flugzeug.php

psr-4

Wenn vendor/composer/autoload_psr4.phpSie sich die Datei ansehen, sehen Sie die Namespaces und die Verzeichnisse, denen sie zugeordnet sind.

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Auf der Suche nach Book \ History \ UnitedStates in src /History/UnitedStates.php
  • Suchen Sie nach Fahrzeug \ Luft \ Flügel \ Flugzeug in src /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Suchen Sie nach Book \ History \ UnitedStates src / Book /History/UnitedStates.php
  • Suchen Sie nach Fahrzeug \ Luft \ Flügel \ Flugzeug in src / Fahrzeug / Luft / Flügel / Flugzeug.php
Udhav Sarvaiya
quelle
-4

Auch wenn ich es versucht habe, ist Composer ein Chaos. Leider ist es die einzige Alternative auf dem Markt.
Warum ist ein Chaos?
Die automatische Vervollständigung des Komponisten funktioniert einwandfrei, wenn Sie die Kontrolle über den Code haben. Wenn Sie jedoch ein anderes Projekt importieren, stehen Ihnen viele Stile und Möglichkeiten zum Erstellen von Ordnern zur Verfügung. Einige Projekte sind beispielsweise /company/src/class.php, während andere company / class.php und andere company / src / class / class.php sind

Ich habe eine Bibliothek erstellt, die es löst:

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

Es generiert eine automatische Schließung, indem alle Klassen eines Ordners gescannt werden, sodass es in jedem Fall funktioniert (psr-0 psr-4, Klassen ohne Namespace, Datei mit mehreren Klassen.

edit: Und wieder ohne Grund herabgestimmt. ;-);

Magallane
quelle
Informieren Sie sich über die Option classmap in composer.json. getcomposer.org/doc/04-schema.md#classmap - könnte der Grund für die Ablehnung Ihrer Antwort sein.
Patrick