¿Cuáles son las diferencias entre PSR-0 y PSR-4?

225

Recientemente he leído sobre espacios de nombres y cómo son beneficiosos. Actualmente estoy creando un proyecto en Laravel e intento pasar de la carga automática del mapa de clase al espacio de nombres. Sin embargo, parece que no puedo entender cuál es la diferencia real entre PSR-0 y PSR-4.

Algunos recursos que he leído son ...

Lo que yo entiendo:

  • PSR-4 no convierte guiones bajos en separadores de directorio
  • Ciertas reglas específicas del compositor hacen que la estructura de directorios se vuelva compleja, lo que a su vez hace que el espacio de nombres PSR-0 sea detallado y, por lo tanto, se creó PSR-4

Se agradecerán ejemplos que expliquen la diferencia.

Varun Nath
fuente
3
Lea PSR0 y PSR4 . Explican cada detalle.
Sverri M. Olsen
44
☝️ Alguien debería escribir la esencia de esto como respuesta ... :)
deceze
1
En mi opinión, la mayoría de las partes en PSR se trata de lo que les GUSTA, no de lo CORRECTO ...
Yousha Aleayoub

Respuestas:

283

Son muy similares, por lo que no es sorprendente que sea un poco confuso. El resumen es que PSR-0 tenía algunas características de compatibilidad con versiones anteriores para los nombres de clase de estilo PEAR que PSR-4 descartó, por lo que solo admite código de espacio de nombres. Además de eso, PSR-4 no te obliga a tener todo el espacio de nombres como una estructura de directorio, sino solo la parte que sigue al punto de anclaje.

Por ejemplo si se define que el Acme\Foo\espacio de nombres está anclado en src/, con PSR-0 que significa que buscará Acme\Foo\Baren src/Acme/Foo/Bar.phpmientras que en PSR-4 que lo buscará en src/Bar.php, teniendo en cuenta las estructuras de directorios más cortos. Por otro lado, algunos prefieren tener la estructura de directorio completa para ver claramente en qué espacio de nombres, por lo que también puede decir que Acme\Foo\está en src/Acme/FooPSR-4, lo que le dará el equivalente del comportamiento de PSR-0 descrito anteriormente.

Larga historia corta para nuevos proyectos y para la mayoría de las intenciones y propósitos, puede usar PSR-4 y olvidarse de PSR-0.

Seldaek
fuente
17
Se recoge src/Bar.phpsi usted diceAcme\Foo\ => src/
Seldaek
¡Muchas gracias por la explicación!
尤川豪
44
PSR-4 es más lento que PSR-0, ¿no?
Nguyen Linh
2
@NguyenLinh No lo creo. Hace lo mismo, pero posiblemente con menos niveles de directorios, por lo que en realidad podría ser un poco más rápido. Mídelo. Puede crear un paquete que pueda cambiar entre PSR-0 y PSR-4; no creo que vea una diferencia.
Sven
44

Aquí están las principales diferencias,

1. Por ejemplo, si define que el Acme\Foo\espacio de nombres está anclado src/,

  • con PSR-0 significa que buscará Acme\Foo\Barensrc/Acme/Foo/Bar.php
  • mientras que en PSR-4 buscará Acme\Foo\Baren src/Bar.php(where Bar class is).

2. PSR-4 no convierte guiones bajos en separadores de directorio

3. Preferiría usar PSR-4 con espacios de nombres

4. PSR-0 no funcionará incluso si el nombre de la clase es diferente del nombre del archivo, como considerar el ejemplo anterior:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (para la clase Bar) funcionará
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(para la clase Bar) no funcionará
Adil Abbasi
fuente
1
Ciertamente puede usar PSR-4 junto con secuencias de comandos de espacio de nombres, no existe tal restricción y lo uso (no es mi elección)
Galvani
En su 1. (primer punto), ¿de dónde vino Bar para el caso PSR-4?
cjmling
31

PSR-4 es algo así como 'ruta relativa', PSR-0, 'ruta absoluta'.

p.ej

config:

'App\Controller' => 'dir/'

Carga automática de PSR-0 :

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

Carga automática de PSR-4 :

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

Y hay algunas diferencias más en los detalles entre PSR-0 y PSR-4, vea aquí: http://www.php-fig.org/psr/psr-4/

wbswjc
fuente
10

Convención de espacio de nombres / carpeta.

Las clases deben almacenarse en carpetas de acuerdo con sus espacios de nombres.

En general, creará un directorio src / en su carpeta raíz, al mismo nivel que el proveedor /, y agregará sus proyectos allí. A continuación se muestra un ejemplo de la estructura de carpetas:

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

Diferencia entre psr-0 y psr-4

psr-0

Está en desuso. Mirando el vendor/composer/autoload_namespaces.phparchivo puede ver los espacios de nombres y los directorios a los que están asignados.

composer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • Buscando Libro \ Historia \ Estados Unidos en src / Libro / Historia / Estados Unidos.php
  • Buscando Vehicle \ Air \ Wings \ Airplane en src / Vehicle /Air/Wings/Airplane.php

psr-4

Mirando el vendor/composer/autoload_psr4.phparchivo puede ver los espacios de nombres y los directorios a los que están asignados.

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Buscando Libro \ Historia \ Estados Unidos en src /History/UnitedStates.php
  • Buscando Vehículo \ Aire \ Alas \ Avión en src /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Buscando Libro \ Historia \ UnitedStates src / Libro /Historia/UnitedStates.php
  • Buscando Vehicle \ Air \ Wings \ Airplane en src / Vehicle /Air/Wings/Airplane.php
Udhav Sarvaiya
fuente
-4

Incluso cuando lo intenté, pero Composer es un desastre. Lamentablemente, es la única alternativa del mercado.
¿Por qué es un desastre?
El autocompletado del Compositor funciona bien si usted tiene el control del código. Sin embargo, si está importando un proyecto diferente, encontrará muchos estilos y formas de crear carpetas. Por ejemplo, algunos proyectos son /company/src/class.php mientras que otros son company / class.php y otros son company / src / class / class.php

Creé una biblioteca que lo resuelve:

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

Genera una inclusión automática al escanear todas las clases de una carpeta, por lo que funciona en todos los casos (psr-0 psr-4, clases sin espacio de nombres, archivo con múltiples clases ...

editar: Y nuevamente, rechazado sin ningún motivo. ;-)

magallanes
fuente
Lea sobre la opción classmap en composer.json. getcomposer.org/doc/04-schema.md#classmap - podría ser la razón para rechazar su respuesta.
Patrick