Apa Perbedaan Antara PSR-0 dan PSR-4?

225

Baru-baru ini saya telah membaca tentang ruang nama dan bagaimana mereka bermanfaat. Saat ini saya sedang membuat proyek di Laravel dan mencoba untuk beralih dari autoloading peta kelas ke namespacing. Namun, saya tidak bisa memahami apa perbedaan sebenarnya antara PSR-0 dan PSR-4.

Beberapa sumber yang saya baca adalah ...

Apa yang saya mengerti:

  • PSR-4 tidak mengonversi garis bawah ke pemisah direktori
  • Aturan spesifik tertentu dari komposer menyebabkan struktur direktori menjadi kompleks yang pada gilirannya membuat PSR-0 namespacing verbose dan dengan demikian PSR-4 dibuat

Contoh yang menjelaskan perbedaan akan dihargai.

Varun Nath
sumber
3
Baca PSR0 dan PSR4 . Mereka menjelaskan setiap detail.
Sverri M. Olsen
4
☝️ Seseorang harus mengetik inti dari ini sebagai jawaban ... :)
deceze
1
IMO, sebagian besar dalam PSR adalah tentang apa yang
SAYA sukai

Jawaban:

283

Mereka sangat mirip sehingga tidak mengherankan bahwa ini agak membingungkan. Ringkasannya adalah bahwa PSR-0 memiliki beberapa fitur kompatibilitas mundur untuk kelas-gaya PEAR-gaya yang menjatuhkan PSR-4, karena itu hanya mendukung kode ruang nama. Selain itu PSR-4 tidak memaksa Anda untuk memiliki seluruh namespace sebagai struktur direktori, tetapi hanya bagian yang mengikuti titik jangkar.

Sebagai contoh jika Anda menentukan bahwa Acme\Foo\namespace berlabuh di src/, dengan PSR-0 berarti itu akan mencari Acme\Foo\Bardi src/Acme/Foo/Bar.phpsementara di PSR-4 akan mencarinya di src/Bar.php, memungkinkan untuk struktur direktori yang lebih pendek. Di sisi lain beberapa lebih suka memiliki struktur direktori lengkap untuk melihat dengan jelas apa yang ada di namespace, jadi Anda juga bisa mengatakan bahwa Acme\Foo\ada di dalam src/Acme/Foodengan PSR-4 yang akan memberi Anda setara dengan perilaku PSR-0 yang dijelaskan di atas.

Singkat cerita untuk proyek baru dan untuk sebagian besar maksud dan tujuan, Anda dapat menggunakan PSR-4 dan melupakan semua tentang PSR-0.

Seldaek
sumber
17
Pilihannya src/Bar.phpjika Anda katakanAcme\Foo\ => src/
Seldaek
Terima kasih banyak atas penjelasannya!
尤川豪
4
PSR-4 lebih lambat dari PSR-0, bukan?
Nguyen Linh
2
@NguyenLinh Saya rasa tidak. Itu melakukan hal yang sama, tetapi mungkin dengan tingkat direktori yang lebih sedikit, jadi itu mungkin sebenarnya sedikit lebih cepat. Ukur itu. Anda dapat membuat paket yang bisa Anda ganti antara PSR-0 dan PSR-4 - Saya tidak berpikir Anda akan melihat perbedaan.
Sven
44

Inilah perbedaan utama,

1. Misalnya jika Anda menetapkan bahwa Acme\Foo\namespace berlabuh di src/,

  • dengan PSR-0 berarti itu akan mencari Acme\Foo\Bardisrc/Acme/Foo/Bar.php
  • sementara di PSR-4 itu akan mencari Acme\Foo\Bardi src/Bar.php(where Bar class is).

2. PSR-4 tidak mengubah garis bawah ke pemisah direktori

3. Anda lebih suka menggunakan PSR-4 dengan ruang nama

4. PSR-0 tidak akan berfungsi walaupun nama kelasnya berbeda dari nama file, seperti mempertimbangkan contoh di atas:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (untuk kelas Bar) akan berfungsi
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(untuk kelas Bar) tidak akan berfungsi
Adil Abbasi
sumber
1
Anda tentu dapat menggunakan PSR-4 bersama tanpa skrip namespace, tidak ada batasan seperti itu dan saya menggunakannya (bukan pilihan saya)
Galvani
Di 1. Anda (titik pertama) dari mana datangnya Bar untuk kasus PSR-4?
cjmling
31

PSR-4 adalah sesuatu seperti 'jalur relatif', PSR-0, 'jalur absolut'.

misalnya

konfigurasi:

'App\Controller' => 'dir/'

PSR-0 autoload:

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

Memuat otomatis PSR-4 :

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

Dan ada beberapa perbedaan lebih detail antara PSR-0 dan PSR-4, lihat di sini: http://www.php-fig.org/psr/psr-4/

wbswjc
sumber
10

Konvensi Namespace / folder.

Kelas harus disimpan dalam folder sesuai dengan ruang namanya.

Secara umum, Anda akan membuat direktori src / di folder root Anda, duduk di tingkat yang sama dengan vendor /, dan menambahkan proyek Anda di sana. Di bawah ini adalah contoh dari struktur folder:

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

Perbedaan antara psr-0 dan psr-4

psr-0

Itu sudah ditinggalkan. Melihat vendor/composer/autoload_namespaces.phpfile Anda dapat melihat ruang nama dan direktori tempat mereka dipetakan.

composer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • Mencari Buku \ History \ UnitedStates di src / Book /History/UnitedStates.php
  • Mencari Vehicle \ Air \ Wings \ Airplane di src / Vehicle /Air/Wings/Airplane.php

psr-4

Melihat vendor/composer/autoload_psr4.phpfile Anda dapat melihat ruang nama dan direktori tempat mereka dipetakan.

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Mencari Buku \ History \ UnitedStates di src /History/UnitedStates.php
  • Mencari Kendaraan \ Air \ Wings \ Airplane di src /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Mencari Buku \ History \ UnitedStates src / Book /History/UnitedStates.php
  • Mencari Vehicle \ Air \ Wings \ Airplane di src / Vehicle /Air/Wings/Airplane.php
Udhav Sarvaiya
sumber
-4

Bahkan ketika saya mencoba tetapi Komposer berantakan. Sayangnya, ini satu-satunya alternatif. Dari pasar.
Mengapa berantakan?
Autocomplete komposer berfungsi dengan baik jika Anda mengendalikan kode. Namun, jika Anda mengimpor proyek yang berbeda, Anda mendapati diri Anda memiliki banyak gaya dan cara untuk membuat folder. Sebagai contoh, beberapa proyek adalah /company/src/class.php sementara yang lain adalah perusahaan / class.php dan yang lain adalah perusahaan / src / class / class.php

Saya membuat perpustakaan yang menyelesaikannya:

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

Ini menghasilkan autoinclude dengan memindai semua kelas folder, sehingga berfungsi dalam setiap kasus (psr-0 psr-4, kelas tanpa namespace, file dengan banyak kelas ..

sunting: Dan lagi, diturunkan tanpa alasan. ;-)

magallanes
sumber
Baca tentang opsi classmap di composer.json. getcomposer.org/doc/04-schema.md#classmap - mungkin menjadi alasan untuk menurunkan jawaban Anda.
Patrick