Quais são as diferenças entre PSR-0 e PSR-4?

225

Recentemente, li sobre espaços para nome e como eles são benéficos. Atualmente, estou criando um projeto no Laravel e tentando passar do carregamento automático do mapa de classe para o namespacing. No entanto, não consigo entender qual é a diferença real entre o PSR-0 e o PSR-4.

Alguns recursos que eu li são ...

O que eu entendo:

  • O PSR-4 não converte sublinhados em separadores de diretório
  • Certas regras específicas do compositor tornam a estrutura do diretório complexa, o que torna o espaço de nomes do PSR-0 detalhado e, portanto, o PSR-4 foi criado.

Exemplos explicando a diferença seriam apreciados.

Varun Nath
fonte
3
Leia PSR0 e PSR4 . Eles explicam todos os detalhes.
Sverri M.Olsen
4
☝️ Alguém deve digitar a essência do presente como uma resposta ... :)
deceze
1
IMO, a maioria das peças em PSR é sobre o que eles gostam e não o que é certo ...
Yousha Aleayoub

Respostas:

283

Eles são muito parecidos, portanto, não é de surpreender que seja um pouco confuso. O resumo é que o PSR-0 tinha alguns recursos de compatibilidade com versões anteriores para nomes de classe no estilo PEAR que o PSR-4 eliminou, portanto, ele suporta apenas código no namespace. Além disso, o PSR-4 não força você a ter todo o espaço para nome como uma estrutura de diretórios, mas apenas a parte que segue o ponto de ancoragem.

Por exemplo, se você definir que o Acme\Foo\namespace está ancorada em src/, com PSR-0 significa que ele irá procurar Acme\Foo\Barem src/Acme/Foo/Bar.phpenquanto no PSR-4 ele vai olhar para ele em src/Bar.php, permitindo estruturas de diretórios mais curtos. Por outro lado, alguns preferem ter a estrutura de diretórios completa para ver claramente o que está em qual namespace, então você também pode dizer que Acme\Foo\está no src/Acme/FooPSR-4, o que lhe dará o equivalente ao comportamento do PSR-0 descrito acima.

Resumindo, para novos projetos e para a maioria das intenções e propósitos, você pode usar o PSR-4 e esquecer tudo sobre o PSR-0.

Seldaek
fonte
17
Ele pega src/Bar.phpse você dizAcme\Foo\ => src/
Seldaek
Muito obrigado pela explicação!
尤川豪
4
PSR-4 é mais lento que PSR-0, não é?
Nguyen Linh
2
@NguyenLinh Acho que não. Ele faz a mesma coisa, mas possivelmente com menos níveis de diretórios, portanto pode ser um pouco mais rápido. Meça isto. Você pode criar um pacote que pode alternar entre PSR-0 e PSR-4 - não acho que você verá uma diferença.
Sven
44

Aqui estão as principais diferenças,

1. Por exemplo, se você definir que o Acme\Foo\espaço para nome está ancorado src/,

  • com PSR-0, significa que procurará Acme\Foo\Baremsrc/Acme/Foo/Bar.php
  • enquanto no PSR-4 vai procurar Acme\Foo\Barno src/Bar.php(where Bar class is).

2. PSR-4 não converte sublinhados em separadores de diretório

3. Você prefere usar o PSR-4 com namespaces

4. PSR-0 não funcionará mesmo que o nome da classe seja diferente do nome do arquivo, como no exemplo acima:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (para a classe Bar) funcionará
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(para a classe Bar) não funcionará
Adil Abbasi
fonte
1
Você certamente pode usar PSR-4 juntamente com sem scripts de nomes, não existe tal restrição a e eu usá-lo (não minha escolha)
Galvani
No seu 1. (primeiro ponto) de onde veio Bar para o caso PSR-4?
cjmling
31

PSR-4 é algo como 'caminho relativo', PSR-0, 'caminho absoluto'.

por exemplo

config:

'App\Controller' => 'dir/'

Carregamento automático PSR-0 :

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

Carregamento automático PSR-4 :

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

E há mais algumas diferenças nos detalhes entre PSR-0 e PSR-4, veja aqui: http://www.php-fig.org/psr/psr-4/

wbswjc
fonte
10

Convenção de namespace / pasta.

As classes devem ser armazenadas em pastas de acordo com seus namespaces.

Em geral, você criará um diretório src / na sua pasta raiz, no mesmo nível do fornecedor /, e adicionará seus projetos lá. Abaixo está um exemplo da estrutura de pastas:

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

Diferença entre psr-0 e psr-4

psr-0

Está obsoleto. Olhando para o vendor/composer/autoload_namespaces.phparquivo, você pode ver os espaços para nome e os diretórios para os quais eles são mapeados.

compositer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • Procurando por Book \ History \ UnitedStates em src / Book /History/UnitedStates.php
  • Procurando Vehicle \ Air \ Wings \ Airplane em src / Vehicle /Air/Wings/Airplane.php

psr-4

Olhando para o vendor/composer/autoload_psr4.phparquivo, você pode ver os espaços para nome e os diretórios para os quais eles são mapeados.

compositer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Procurando por Book \ History \ UnitedStates em src /History/UnitedStates.php
  • Procurando Veículo \ Ar \ Asas \ Avião em src /Air/Wings/Airplane.php

compositer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Procurando por Book \ History \ UnitedStates src / Book /History/UnitedStates.php
  • Procurando Vehicle \ Air \ Wings \ Airplane em src / Vehicle /Air/Wings/Airplane.php
Udhav Sarvaiya
fonte
-4

Mesmo quando tentei, mas o Composer está uma bagunça. Infelizmente, é a única alternativa. Do mercado.
Por que está uma bagunça?
O preenchimento automático do compositor funciona bem se você estiver no controle do código. No entanto, se você estiver importando um projeto diferente, encontrará muitos estilos e maneiras de criar pastas. Por exemplo, alguns projetos são /company/src/class.php, enquanto outros são company / class.php e outros são company / src / class / class.php

Eu criei uma biblioteca que a resolve:

https://github.com/EFTEC/AutoLoadOne (é grátis, MIT).

Ele gera uma inclusão automática, varrendo todas as classes de uma pasta, para que funcione em todos os casos (psr-0 psr-4, classes sem espaço para nome, arquivo com várias classes).

editar: E, novamente, votou sem motivo. ;-)

Magallanes
fonte
Leia sobre a opção de mapa de classe em composer.json. getcomposer.org/doc/04-schema.md#classmap - pode ser o motivo da votação negativa da sua resposta.
1011 Patrick