Chuẩn coding convention trong PHP với PSR

525

Chào các bạn,

Ngày xưa lúc mới học lập trình, thì cứ vài hôm mình lại thay đổi phong cách code một lần. Lúc thì đặt tên biến kiểu ten_bien, lúc thì đặt kiểu tenbien, lúc thì tenBien,… đến lúc hoàn thành dự án, mặc dù code chạy không sai đọc lại thấy ngu không tả nổi, cảm giác cứ như nhìn vào tờ giấy nháp vậy.

Mình đặt ra câu hỏi “Làm một mình còn code khuyết tật thế này, thế làm team thì sao, chẳng lẽ lại mạnh ai người ý code à?”. Không, không thể nào như vậy được, mình cho rằng phải có một quy ước chung nào đó. Thế là mình thử lên mạng tìm hiểu xem, thì thấy có khái niệm về coding convention giải quyết được vấn đề mình gặp phải.

I. Coding convention là gì?

Coding convention dịch ra Tiếng Việt là quy ước coding. Hiểu nôm na nó là một tập hợp các quy ước về phong cách code, cách đặt tên biến, tên hàm, tên file,… để các coder tuân theo.

Coding convention sẽ đem lại lợi ích nhiều hơn khi bạn làm việc nhóm. Hãy tưởng tượng nhóm 5 người và cùng tuân theo một phong cách code, thì khi người này đọc code của người kia sẽ dễ hiểu hơn, không cảm thấy “ngứa mắt” hay muốn đánh đồng nghiệp.

Ý kiến cá nhân: Code không có convention là dấu hiệu thất bại đầu tiên khi làm phần mềm.

Ngay cả khi bạn làm một mình, thì tuân theo coding convention cũng vẫn rất quan trọng. Những dòng code chuẩn chỉ sẽ khiến bạn có hứng thú đọc hơn là những dòng code xiên xẹo đúng không.

II. PSR PHP là gì?

Coding convention nói chung rất rộng, tùy vào ngôn ngữ lập trình, tùy vào team mà có thể có coding convention khác nhau. Còn với PSR, nó là coding convention được áp dụng phổ biến nhất khi code PHP.

PSR là viết tắt của PHP Standards Recommendations – khuyến nghị về tiêu chuẩn của PHP.

Bạn có thể tìm hiểu chi tiết về PSR tại trang chủ chính thức https://www.php-fig.org, còn trong bài viết này mình sẽ tóm tắt một số ý cơ bản về PSR.

Tính đến thời điểm hiện tại (03/2020), PSR có tất cả 12 chuẩn (bao gồm cả các chuẩn đã lỗi thời), chia làm 4 nhóm:

STTNhómMô tảPhiên bản PSR
1AutoloadingQuy ước về cách code để có thể sử dụng namespace dễ dàngPSR-4
2InterfaceQuy ước về cách code thư viện liên quan tới log, cache,…PSR-3, PSR-6, PSR-11, PSR-13, PSR-14, PSR-16
3HTTPQuy ước về cách code làm sao để tương tác với các request, response HTTP một cách tốt nhấtPSR-7, PSR-5, PSR-15, PSR-17, PSR-18
4Coding stylesQuy ước về phong cách codePSR-1, PSR-12

Trong các nhóm kể trên, mình muốn nhấn mạnh vào nhóm Coding styles nhất, bởi đây chính là nhóm quy định về phong cách code, cách đặt tên biến, tên hàm, tên class,… cũng chính là nội dung mà mình muốn đề cập tới trong bài viết này. Các nhóm còn lại sẽ ít sử dụng hơn, sử dụng chủ yếu khi bạn có ý định code các thư viện hay framework cho PHP.

III. PSR-1, PSR-12, 2 chuẩn về coding styles

Tính đến thời điểm mình viết bài này, PSR-1 và PSR-12 là 2 chuẩn được sử dụng cho coding styles.

Bạn cũng có thể nghe thấy đâu đó người ta nhắc về chuẩn PSR-2 nữa, nhưng PSR-2 đã được đánh dấu là “lỗi thời” trên trang chủ của https://www.php-fig.org. Không tin thì bạn có thể đọc tại đây: https://www.php-fig.org/psr/psr-2. PSR-2 giờ đây được thay thế bằng PSR-12.

3.1 Tìm hiểu về PSR-1

3.1.1 Đối với file PHP

Nguyên tắc 1: File PHP chỉ được phép sử dụng <?php<?=. <?php được sử dụng để mở đầu cho code PHP, và <?= là cú pháp short-echo (thay vì code là <?php echo $a ?>, bạn có thể code là <?= $a ?>)

Nguyên tắc 2: File code PHP sử dụng encode UTF-8 without BOM.

Nguyên tắc 3: File PHP NÊN dùng để khai báo các thành phần của PHP (class, function, const) và các hiệu ứng phụ (include, thiết lập init PHP), nhưng KHÔNG NÊN dùng cả hai trong một file. Để hiểu rõ hơn nguyên tắc này, bạn hãy xem ví dụ sau

Không nên code thế này

<?php
// hiệu ứng phụ: đổi thiết lập ini
ini_set('error_reporting', E_ALL);

// hiệu ứng phụ: nạp file vào
include "file.php";

// hiệu ứng phụ: xuất dữ liệu
echo "<html>\n";

// khai báo hàm
function foo()
{
    // function body
}

Đoạn code trên bao gồm cả việc khai báo các hiệu ứng phụ (init_set, include) và cả việc khai báo thành phần của PHP (function foo). Chúng ta KHÔNG NÊN code như vậy. Thay vào đó, hãy tách chúng ra làm 2 file.

functions.php

<?php
// functions.php

// khai báo hàm
function foo()
{
    // function body
}

index.php

<?php
// index.php

// hiệu ứng phụ: đổi thiết lập ini
ini_set('error_reporting', E_ALL);

// hiệu ứng phụ: nạp file vào
include "file.php";
include "functions.php";

// hiệu ứng phụ: xuất dữ liệu
echo "<html>\n";


3.1.2 Đối với khai báo namespace và class

Nguyên tắc 1: namespace và class phải thuân theo chuẩn “autoload” PSR-0, PSR-4.

Mỗi class được khai báo trên một file PHP riêng và có namespace tối thiểu một cấp, cấp đầu tiên là tên vendor (tên đơn vị phát hành)

Tên class PHẢI được viết dạng ClassName thay vì classname, Classname, class_name hay Class_Name

Từ PHP 5.3, PHẢI sử dụng namespace khi khai báo class.

KHÔNG ĐƯỢC code thế này.

<?php

class Classname
{
    //
}

Mà PHẢI code thế này

<?php

namespace Vendor;

class ClassName
{
    //
}

Từ phiên bản PHP 5.2.x trở về trước. bạn có thể code thế này, nhưng giờ ai còn code trên PHP 5 nữa đâu chứ đừng nói là PHP 5.2.x.

<?php

class Vendor_ClassName
{
    ///
}

3.1.3 Hằng, thuộc tính và phương thức của class

Quy tắc 1: Hằng khai báo trong class phải được viết hoa và ngăn cách bằng dấu gạch dưới.

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}

Quy tắc 2: Thuộc tính khai báo trong class có thể viết ở dạng $ten_thuoc_tinh, $TenThuocTinh hoặc $tenThuocTinh. Nhưng nếu bạn chọn một kiểu rồi thì phải thống nhất về cách code trong một phạm vi nào đó, như phạm vi trong class, trong package hoặc trong vendor.

Ý kiến cá nhân: Nên chọn $tenThuocTinh

Quy tắc 3: Tên phương thực phải được đặt ở dang tenPhuongThuc()

<?php

namespace Vendor\Model;
 
class Foo
{
    public function methodName()
    {
        //
    }
}

3.2 Tìm hiểu về PSR-12

Các quy tắc về PSR-12 khá dài, nên mình có hẳn một bài viết để trình bày riêng tại đây:

>> Code PHP theo chuẩn PSR-12

IV. Tổng kết

Code không chỉ code một lần là xong, code xong có khi còn phải sửa lên sửa xuống. Mà khi sửa, có khi còn là sửa code của người khác chứ chẳng được sửa code của mình. Để không tạo ra sự lạ lẫm, khó chịu khi người khác đọc một đoạn code không phải do mình viết ra thì cách tốt nhất là áp dụng coding convention ngay từ đầu.

Áp dụng chuẩn coding convention là bước đầu tiên thể hiện bạn đang dần trở nên chuyên nghiệp hơn.

Một bài viết ngắn chia kiến thức của mình về coding convention. Hẹn gặp lại các bạn trong những bài viết kế tiếp.