อะไรคือความแตกต่างระหว่าง PSR-0 และ PSR-4


225

เมื่อเร็ว ๆ นี้ฉันได้อ่านเกี่ยวกับเนมสเปซและประโยชน์ที่ได้รับ ขณะนี้ฉันกำลังสร้างโครงการใน Laravel และพยายามย้ายจากการโหลดอัตโนมัติในคลาสแผนที่ไปยังการกำหนดเนม อย่างไรก็ตามฉันไม่สามารถเข้าใจความแตกต่างที่แท้จริงระหว่าง PSR-0 และ PSR-4 ได้

ทรัพยากรบางอย่างที่ฉันได้อ่านคือ ...

สิ่งที่ฉันเข้าใจ:

  • PSR-4 ไม่แปลงขีดล่างเป็นตัวคั่นไดเรกทอรี
  • กฎเฉพาะของนักแต่งเพลงบางอย่างทำให้โครงสร้างไดเรกทอรีมีความซับซ้อนซึ่งจะทำให้การกำหนดเนมสเปซ PSR-0 เป็นแบบละเอียดและทำให้ PSR-4 ถูกสร้างขึ้น

ตัวอย่างอธิบายความแตกต่างจะได้รับการชื่นชม


3
อ่านPSR0และPSR4 พวกเขาอธิบายทุกรายละเอียด
Sverri M. Olsen


4
☝️ใครบางคนควรพิมพ์ส่วนสำคัญของสิ่งนี้เป็นคำตอบ ... :)
พ่ายแพ้

1
IMO ส่วนใหญ่ใน PSR เป็นเรื่องเกี่ยวกับสิ่งที่พวกเขาต้องการไม่ใช่สิ่งที่เหมาะสม ...
Yousha Aleayoub

คำตอบ:


283

พวกมันคล้ายกันมากดังนั้นจึงไม่น่าแปลกใจที่มันค่อนข้างสับสน สรุปคือ PSR-0 มีคุณสมบัติความเข้ากันได้ย้อนหลังบางอย่างสำหรับชื่อคลาสสไตล์ลูกแพร์ที่ PSR-4 ลดลงดังนั้นจึงรองรับรหัสเนมสเปซเท่านั้น ด้านบนของ PSR-4 นั้นไม่ได้บังคับให้คุณมี namespace ทั้งหมดเป็นโครงสร้างไดเรกทอรี แต่มีเพียงบางส่วนที่ตามหลังจุดยึด

ตัวอย่างเช่นถ้าคุณกำหนดว่าAcme\Foo\เนมสเปซนั้นถูกยึดsrc/ด้วย PSR-0 หมายความว่ามันจะมองหาAcme\Foo\Barในsrc/Acme/Foo/Bar.phpขณะที่ใน PSR-4 มันจะมองหามันในsrc/Bar.phpซึ่งจะทำให้โครงสร้างไดเรกทอรีสั้นลง ในทางกลับกันบางคนชอบที่จะมีโครงสร้างไดเรกทอรีแบบเต็มเพื่อดูสิ่งที่อยู่ใน namespace อย่างชัดเจนดังนั้นคุณสามารถพูดได้ว่าAcme\Foo\เป็นในsrc/Acme/Fooกับ PSR-4 ซึ่งจะช่วยให้คุณเทียบเท่ากับพฤติกรรม PSR-0 ที่อธิบายข้างต้น

เรื่องสั้นสั้น ๆ สำหรับโครงการใหม่และเพื่อจุดประสงค์และจุดประสงค์ส่วนใหญ่คุณสามารถใช้ PSR-4 และลืมทุกอย่างเกี่ยวกับ PSR-0


17
มันเลือกsrc/Bar.phpว่าถ้าคุณพูดAcme\Foo\ => src/
Seldaek

ขอบคุณมากสำหรับคำอธิบาย!
尤川豪

4
PSR-4 ช้ากว่า PSR-0 ใช่ไหม
Nguyen Linh

2
@ NguyenLinh ฉันไม่คิดอย่างนั้น มันทำสิ่งเดียวกัน แต่อาจมีไดเรคทอรีระดับน้อยลงดังนั้นจึงอาจเร็วขึ้นเล็กน้อย วัดมัน คุณสามารถสร้างแพ็คเกจที่สามารถสลับระหว่าง PSR-0 และ PSR-4 - ฉันไม่คิดว่าคุณจะเห็นความแตกต่าง
สเวน

44

นี่คือความแตกต่างที่สำคัญ

1.ยกตัวอย่างเช่นถ้าคุณกำหนดว่าAcme\Foo\namespace ที่ทอดสมออยู่ในsrc/,

  • กับ PSR-0 มันหมายความว่ามันจะมองหาAcme\Foo\Barในsrc/Acme/Foo/Bar.php
  • ขณะที่อยู่ใน PSR-4 มันจะมองหาในAcme\Foo\Barsrc/Bar.php(where Bar class is)

2. PSR-4 ไม่แปลงขีดล่างเป็นตัวคั่นไดเรกทอรี

3.คุณต้องการใช้ PSR-4 กับเนมสเปซ

4. PSR-0 จะไม่ทำงานแม้ว่าชื่อคลาสจะแตกต่างจากชื่อไฟล์เช่นพิจารณาจากตัวอย่างด้านบน:

  • Acme\Foo\Bar ---> src/Acme/Foo/Bar.php (สำหรับคลาสบาร์) จะใช้งานได้
  • Acme\Foo\Bar ---> src/Acme/Foo/Bar2.php(สำหรับคลาสบาร์) จะไม่ทำงาน

1
แน่นอนคุณสามารถใช้ PSR-4 พร้อมกับไม่มีสคริปต์ namespace ไม่มีข้อ จำกัด ดังกล่าวและฉันจะใช้มัน (ไม่ใช่ตัวเลือกของฉัน)
Galvani

ใน 1. (จุดแรก) ของคุณบาร์มาจากไหนสำหรับเคส PSR-4?
cjmling

31

PSR-4 คือ 'เส้นทางสัมพัทธ์', PSR-0, 'เส้นทางสัมบูรณ์'

เช่น

การตั้งค่า:

'App\Controller' => 'dir/'

PSR-0 ข้อความอัตโนมัติ:

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

โหลดอัตโนมัติPSR-4 :

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

และมีรายละเอียดที่แตกต่างกันระหว่าง PSR-0 และ PSR-4 ดูที่นี่: http://www.php-fig.org/psr/psr-4/


10

แบบแผนเนมสเปซ / โฟลเดอร์

คลาสควรถูกเก็บไว้ในโฟลเดอร์ตามเนมสเปซของพวกเขา

โดยทั่วไปคุณจะสร้าง src / ไดเรกทอรีในโฟลเดอร์รูทของคุณอยู่ในระดับเดียวกับผู้ขาย / และเพิ่มโครงการของคุณที่นั่น ด้านล่างเป็นตัวอย่างของโครงสร้างโฟลเดอร์:

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

ความแตกต่างระหว่าง psr-0 และ psr-4

PSR-0

มันเลิกใช้แล้ว การดูvendor/composer/autoload_namespaces.phpไฟล์คุณสามารถเห็นเนมสเปซและไดเรกทอรีที่แมปไว้

composer.json

"autoload": {
        "psr-0": {
            "Book\\": "src/",
            "Vehicle\\": "src/"
        }
} 
  • กำลังมองหาหนังสือ \ ประวัติ \ ประเทศสหรัฐอเมริกาในsrc / หนังสือ /History/UnitedStates.php
  • กำลังมองหายานพาหนะ \ อากาศ \ ปีก \ เครื่องบินsrc / ยานพาหนะ /Air/Wings/Airplane.php

PSR-4

การดูvendor/composer/autoload_psr4.phpไฟล์คุณสามารถเห็นเนมสเปซและไดเรกทอรีที่แมปไว้

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/",
        "Vehicle\\": "src/"
    }
}   
  • กำลังมองหาหนังสือ \ ประวัติ \ UnitedStates ในsrc /History/UnitedStates.php
  • กำลังมองหายานพาหนะ \ Air \ Wings \ Airplane ในsrc /Air/Wings/Airplane.php

composer.json

"autoload": {
    "psr-4": {
        "Book\\": "src/Book/",
        "Vehicle\\": "src/Vehicle/"
    }
}    
  • กำลังมองหาหนังสือ \ ประวัติ \ ประเทศสหรัฐอเมริกาsrc / หนังสือ /History/UnitedStates.php
  • กำลังมองหายานพาหนะ \ อากาศ \ ปีก \ เครื่องบินsrc / ยานพาหนะ /Air/Wings/Airplane.php

-4

แม้ว่าฉันจะพยายาม แต่ Composer ก็เป็นระเบียบ น่าเศร้าที่มันเป็นทางเลือกเดียวของตลาด
ทำไมเป็นระเบียบ?
การเติมข้อความอัตโนมัติของนักแต่งเพลงทำงานได้ดีถ้าคุณอยู่ในการควบคุมของรหัส อย่างไรก็ตามหากคุณกำลังนำเข้าโครงการที่แตกต่างคุณจะพบกับสไตล์และวิธีการสร้างโฟลเดอร์มากมาย ตัวอย่างเช่นบางโครงการเป็น /company/src/class.php ในขณะที่โครงการอื่น ๆ คือ บริษัท / class.php และโครงการอื่น ๆ เป็น บริษัท / src / class / class.php

ฉันสร้างห้องสมุดที่แก้มันได้:

https://github.com/EFTEC/AutoLoadOne (ฟรี MIT)

มันสร้าง autoinclude โดยสแกนคลาสทั้งหมดของโฟลเดอร์ดังนั้นจึงสามารถทำงานได้ในทุกกรณี (psr-0 psr-4, คลาสที่ไม่มี namespace, ไฟล์ที่มีหลายคลาส ..

แก้ไข: และอีกครั้ง downvote โดยไม่มีเหตุผลใด ๆ ;-)


อ่านเพิ่มเติมเกี่ยวกับตัวเลือก classmap ใน composer.json getcomposer.org/doc/04-schema.md#classmap - อาจเป็นสาเหตุของการ downvoting คำตอบของคุณ
แพทริค
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.