Sự khác biệt giữa PSR-0 và PSR-4 là gì?


225

Gần đây tôi đã đọc về không gian tên và cách chúng có ích. Tôi hiện đang tạo một dự án ở Laravel và đang cố gắng chuyển từ tự động tải bản đồ lớp sang không gian tên. Tuy nhiên, tôi dường như không thể nắm bắt được sự khác biệt thực sự giữa PSR-0 và PSR-4.

Một số tài nguyên mà tôi đã đọc là ...

Những gì tôi hiểu:

  • PSR-4 không chuyển đổi dấu gạch dưới thành dấu tách thư mục
  • Một số quy tắc cụ thể của nhà soạn nhạc khiến cấu trúc thư mục trở nên phức tạp, từ đó tạo ra không gian tên PSR-0 và do đó PSR-4 đã được tạo

Các ví dụ giải thích sự khác biệt sẽ được đánh giá cao.


3
Đọc PSR0PSR4 . Họ giải thích từng chi tiết.
Sverri M. Olsen


4
☝️ Ai đó nên gõ lên những ý chính về điều này như một câu trả lời ... :)
deceze

1
IMO, hầu hết các phần trong PSR là về những gì họ THÍCH chứ không phải QUYỀN ...
Yousha Aleayoub

Câu trả lời:


283

Chúng rất giống nhau nên không có gì đáng ngạc nhiên khi nó hơi khó hiểu. Tóm tắt là PSR-0 có một số tính năng tương thích ngược cho các tên lớp kiểu PEAR mà PSR-4 đã bỏ, do đó nó chỉ hỗ trợ mã được đặt tên. Trên hết, PSR-4 không bắt buộc bạn phải có toàn bộ không gian tên như một cấu trúc thư mục, mà chỉ là phần theo sau điểm neo.

Ví dụ: nếu bạn xác định rằng Acme\Foo\ không gian tên được neo vào src/, với PSR-0, điều đó có nghĩa là nó sẽ tìm kiếm Acme\Foo\Bartrong src/Acme/Foo/Bar.phpkhi trong PSR-4, nó sẽ tìm kiếm nó src/Bar.php, cho phép các cấu trúc thư mục ngắn hơn. Mặt khác, một số người thích có cấu trúc thư mục đầy đủ để thấy rõ những gì trong không gian tên, vì vậy bạn cũng có thể nói rằng Acme\Foo\trong src/Acme/FooPSR-4 sẽ cung cấp cho bạn tương đương với hành vi PSR-0 được mô tả ở trên.

Câu chuyện dài cho các dự án mới và cho hầu hết các ý định và mục đích, bạn có thể sử dụng PSR-4 và quên tất cả về PSR-0.


17
Nó chọn src/Bar.phpnếu bạn nóiAcme\Foo\ => src/
Seldaek

Cảm ơn bạn rất nhiều vì lời giải thích!
尤川豪

4
PSR-4 chậm hơn PSR-0, phải không?
Nguyễn Linh

2
@NguyenLinh Tôi không nghĩ vậy. Nó làm điều tương tự, nhưng có thể với ít cấp độ thư mục hơn, vì vậy nó thực sự có thể nhanh hơn một chút. Đo lường nó. Bạn có thể tạo một gói mà bạn có thể chuyển đổi giữa PSR-0 và PSR-4 - Tôi không nghĩ bạn sẽ thấy sự khác biệt.
Sven

44

Dưới đây là những khác biệt chính,

1. Ví dụ: nếu bạn xác định rằng Acme\Foo\không gian tên được neo vào src/,

  • với PSR-0, điều đó có nghĩa là nó sẽ tìm kiếm Acme\Foo\Bartrongsrc/Acme/Foo/Bar.php
  • trong khi ở PSR-4, nó sẽ tìm kiếm Acme\Foo\Bartrong src/Bar.php(where Bar class is).

2. PSR-4 không chuyển đổi dấu gạch dưới thành dấu tách thư mục

3. Bạn muốn sử dụng PSR-4 với các không gian tên

4. PSR-0 sẽ không hoạt động ngay cả khi tên lớp khác với tên tệp, như xem xét ví dụ trên:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (đối với lớp Bar) sẽ hoạt động
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(đối với lớp Bar) sẽ không hoạt động

1
Bạn chắc chắn có thể sử dụng PSR-4 cùng với không có tập lệnh không gian tên, không có hạn chế nào như vậy và tôi sử dụng nó (không phải lựa chọn của tôi)
Galvani

Trong 1. (điểm đầu tiên), Bar đến từ đâu cho trường hợp PSR-4?
cjmling

31

PSR-4 là một cái gì đó như 'đường dẫn tương đối', PSR-0, 'đường dẫn tuyệt đối'.

ví dụ

cấu hình:

'App\Controller' => 'dir/'

Tự động tải PSR-0 :

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

Tự động tải PSR-4 :

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

Và có một số khác biệt về chi tiết giữa PSR-0 và PSR-4, xem tại đây: http://www.php-fig.org/psr/psr-4/


10

Quy ước không gian / thư mục.

Các lớp nên được lưu trữ trong các thư mục theo không gian tên của chúng.

Nói chung, bạn sẽ tạo một thư mục src / trong thư mục gốc của mình, ngồi cùng cấp với nhà cung cấp / và thêm các dự án của bạn vào đó. Dưới đây là một ví dụ về cấu trúc thư mục:

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

Sự khác biệt giữa psr-0 và psr-4

ps-0

Nó bị phản đối Nhìn vào vendor/composer/autoload_namespaces.phptập tin, bạn có thể thấy các không gian tên và các thư mục mà chúng được ánh xạ tới.

composer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • Tìm kiếm Sách \ Lịch sử \ UnitedStates trong src / Sách /History/UnitedStates.php
  • Tìm kiếm Xe \ Air \ Wings \ Máy bay trong src / Xe /Air/Wings/Airplane.php

psr-4

Nhìn vào vendor/composer/autoload_psr4.phptập tin, bạn có thể thấy các không gian tên và các thư mục mà chúng được ánh xạ tới.

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • Tìm kiếm Sách \ Lịch sử \ UnitedStates trong src /History/UnitedStates.php
  • Tìm kiếm Xe \ Air \ Wings \ Airplane trong src /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • Tìm kiếm Sách \ Lịch sử \ UnitedStates src / Sách /History/UnitedStates.php
  • Tìm kiếm Xe \ Air \ Wings \ Máy bay trong src / Xe /Air/Wings/Airplane.php

-4

Ngay cả khi tôi đã cố gắng nhưng Composer là một mớ hỗn độn. Đáng buồn thay, đó là sự thay thế duy nhất. Của thị trường.
Tại sao là một mớ hỗn độn ?.
Trình tự động hoàn thành của Trình biên dịch hoạt động tốt nếu bạn kiểm soát mã. Tuy nhiên, nếu bạn đang nhập một dự án khác, bạn sẽ thấy mình có rất nhiều kiểu dáng và cách tạo thư mục. Ví dụ: một số dự án là /company/src/ class.php trong khi các dự án khác là company / class.php và các dự án khác là company / src / class / class.php

Tôi đã tạo một thư viện giải quyết nó:

https://github.com/EFTEC/AutoLoadOne (miễn phí, MIT).

Nó tạo ra một tự động loại trừ bằng cách quét tất cả các lớp của một thư mục, do đó, nó hoạt động trong mọi trường hợp (psr-0 psr-4, các lớp không có không gian tên, tệp có nhiều lớp ..

chỉnh sửa: Và một lần nữa, downvote mà không có lý do. ;-)


Đọc về tùy chọn classmap trong composer.json. getcomposer.org/doc/04-schema.md#groupmap - có thể là lý do để hạ thấp câu trả lời của bạn.
Patrick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.