Giới thiệu về PSR - PHP Standard Recommendations (P1)

php Sep 16, 2020

Mở đầu.

Nếu bạn tò mò từng nhìn vào file composer.json bạn sẽ thấy có một đoạn config nhỏ như sau :

    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },

Nếu bạn đang phát triển một service provider cho laravel hẳn bạn sẽ từng đọc qua hướng dẫn và thấy tài liệu có đoạn sau


Laravel's service container implements the PSR-11 interface. Therefore, you may type-hint the PSR-11 container interface to obtain an instance of the Laravel container:
use Psr\Container\ContainerInterface;

Route::get('/', function (ContainerInterface $container) {
    $service = $container->get('Service');

    //
});

Hay như nếu bạn không đọc lướt qua quá nhanh thì có một đoạn ngắn thế này trong tài liệu của Laravel (https://laravel.com/docs/7.x/contributions#coding-style)

Laravel follows the PSR-2 coding standard and the PSR-4 autoloading standard.

OK, vậy bạn bắt đầu tự hỏi PSR là gì? Con số phía sau PSR có ý nghĩa gì?

What the heck is PSR and it's number that follow?

PSR là gì?

Chuyện rất là dài nhưng ngày xửa ngày xưa cụ thể vào năm 2009, một nhóm các nhà phát triển hàng đầu của một nhóm các framework tụ họp ở Chicago-Mỹ, ngồi lại cùng nhau để đồng ý một số tiêu chuẩn (standard) được dùng cho các dự án của họ. Mọi người đã quyết định lấy tên nhóm là PHP Standard Group và hoạt động đầu tiên là chuẩn hóa về Autoloading mà sau này gọi là PSR-0. Trải qua 2 năm khó khăn trong hoạt động, năm 2011 nhóm đã đổi tên thành Framework Interoperability Group hay PHP-FIG và dần hoạt động với mục đích làm cho các framework và các library được dễ dàng tích hợp cho sử dụng cho người dùng. Cùng nhau hoạt động và họ đã đưa ra các đặc tả được sử dụng như các tiêu chuẩn programming trong PHP được gọi với cái tên PHP Standards Recommendations hay được viết tắt lại là PSR. Các tiêu chuẩn này sau đó đã có ảnh hưởng rộng khắp tới cộng đồng sử dụng PHP. ( Cite: https://www.sitepoint.com/the-past-present-and-future-of-the-php-fig/)

Các tiêu chuẩn PSR khi được đề xuất sẽ tuân thủ theo PSR Workflow bylaw và tới thời điểm hiện tại có 18 PSR sau đây đã được chấp nhận (Accepted)  và được đánh số từ PSR0 ~ PSR18. Chi tiết :  PHP-PSR

Giờ bạn đã biết PSR là gì và con số sau đó có ý nghĩa gì chúng ta sẽ đi vào chi tiết một số PSR có ảnh hưởng lớn tới cộng đồng nhé.

PSR-0 : Autoloading Standard

Mặc dù đã bị loại bỏ "Deprecated" vào 2014-10-21 và được thay thế bởi PSR-4 nhưng PSR-0 vẫn nên được nhắc đến vì đánh dấu sự hình thành của PHP-FIG và là yếu tố then chốt cho Composer mà sau đó đã thay đổi cả hệ sinh thái PHP.

PSR-0 là một đặc tả cho việc load tự động các lớp từ đường dẫn file. Cả PSR-0 và PSR-4 đểu là các chuẩn quy ước liên quan đến namespace, tên lớp và đường dẫn file. Chúng cũng đồng thời mô tả vị trí để file để có thể được load tự động theo đúng như đặc tả

Để hiểu được về PSR-0 ta cần có một số kiến thức về autload. Autloading là một tính năng cho phép lập trình viên thêm các lớp PHP một cách tự động mà không phải viết các lệnh include/require phân mảnh khắp mọi nơi trong code ( Chắc bạn vẫn nhớ là trong PHP, định nghĩa lớp được load sử dụng require hoặc include trong file mà chúng được dùng tới )  ví dụ như sau :

include 'Model/User.php'

$user = new User()

Việc này gây ra một vấn đề là trong mỗi file ta đều cần require/include các lớp ngay tại đầu file trước khi sử dụng và xử lý conflict hoặc duplicate giữa chúng.1
Và để giải quyết vấn đề này PHP 5 đã giới thiệu magic function __autoload() với mục đích tự động được gọi khi code của bạn tham chiếu tới 1 class hoặc interface chưa được load:

function __autoload($className){
    include($className.".php");
}

Như vậy khi bạn $user = new User() và User class chưa được load thì PHP sẽ sử dụng __autoload để cố gắng include định nghĩa User class từ file User.php.  Nhược điểm của cách làm này là ta chỉ có thể gắn 1 class loader với __autoload như bạn thấy ở đây nó sẽ tìm trong thư mục hiện tại file User.php. Để xử lý nhược điểm này từ PHP 5.1.2, một autoloading function mới đã được giới thiệu spl_autoload_register . Nó cho phép programmer tạo chuỗi autoload, một chuỗi functions có thể được gọi để load một lớp hoặc interface.

Như vậy bạn thấy công việc còn lại là chuẩn hóa đầu vào của spl_autoload_register hay chính là liên quan đến việc tổ chức tên, vị trí của file để việc load được hiệu quả. PSR-0 được sinh ra với mục đích đó và đã đưa ra một số tiêu chuẩn như sau:

Tên một namespace/class tiêu chuẩn phải tuân thủ cấu trúc \<Vendor Name>\(<Namespace>\)*<Class Name>.

  • Mỗi namespace phải có 1 top-level namespace ("vendor name")
  • Mỗi namespace có thể có bao nhiêu sub-namespace tùy ý
  • Mỗi namespace separator sẽ đươc  convert thành DIRECTORY_SEPARATOR khi được load từ hệ thống file
  • Mỗi dấu _ trong tên class được convert thành DIRECTORY_SEPARATOR và dấu _ không có ý nghĩa trong namespacee
  • Tên chuẩn của namespace và lớp có suffix là .php khi được load lên từ hệ thống file
  • Các kí tự alphabet trong tên vendor, namespace và tên class có thể là sự kết hợp bất kỳ của ký tự thường và in hoa

Một số ví dụ về quy ước này :

\Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
\Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
\Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php
\namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
\namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php


Như vậy bất cứ một implementation nào thỏa mãn các điều kiện ở trên sử dụng spl-autoload-register sẽ được gọi là thỏa mãn PSR-0. Dưới đây là một ví dụ :

Tiếp theo chúng ta sẽ tìm hiểu về PSR-4 kẻ thay thế PSR-0.

Next Post : PSR-4

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.