Hướng dẫn php style guide - hướng dẫn kiểu php

PSR có nghĩa là PHP Standards Recommendations, nó là tiêu chuẩn được khuyến nghị áp dụng khi lập trình PHP và được các lập trình viên, tổ chức chấp nhận sử dụng.

PSR được soạn thảo, đánh giá và khuyến khích sử dụng bởi một nhóm chuyên gia PHP những người phát triển cho các Framework và hệ thống PHP phổ biến (thành viên PSR).

PSR bao gồm 7 phần (http://www.php-fig.org/psr/) từ PSR-1, PSR-2, PSR-3, PSR-4, PSR-6, PSR-7. Các tiêu chuẩn thành phần hoàn chỉnh của PSR đó gồm:

  • Basic Coding Standard: Tiêu chuẩn cơ bản khi viết code PHP
  • Coding Style Guide: Tiêu chuẩn trình bày code
  • Logger Interface: Giao diện logger
  • Autoloading Standard: Tiêu chuẩn về tự động nạp
  • Caching Interface: Giao diện về Caching
  • HTTP Message Interface: Tiêu chuẩn Giao diện thông điệp HTTP

1. PSR-1 Basic Coding Standard (Tiêu chuẩn cơ bản khi viết code PHP)

PRS-1 là các nguyên tắc mỗi lập trình viên PHP nên theo để đảm bảo code dễ đọc, bảo trì, và dễ sử dụng lại cũng như chia sẻ cho đồng đội.

1. Nguyên tắc chung nhất khi code PHP

  • Các file code

    6 sử dụng thẻ

    7 hoặc

    8
  • File code PHP sử dụng encode: UTF-8 without BOOM
  • Các Files

    9 hoặc dùng để khai báo các thành phần PHP (các lớp, hàm, hằng …) hoặc dùng với mục đích làm hiệu ứng phụ (như include, thiết lập ini cho PHP …), nhưng

    0 dùng cả 2 cùng lúc trong 1 file (Xem ví dụ này ở  Ví dụ 1)
  • Các Namespace và classes

    6 theo chuẩn “autoloading” PSR: [PSR-4]
  • Tên lớp

    6 có dạng NameClass (chữ không nameclass, Nameclass, namClass …)
  • Hằng số trong class tất cả PHẢI viết HOA và chia ra bởi dấu _ (ví dụ

    3).
  • Tên phương thức của lớp

    6 ở dạng camelCase (từ đầu viết thường, ví dụ: helloWorld).

Ví dụ 1)

File PHP viết không theo chuẩn, trộn lẫn lung tung hiệu ứng phụ và khai báo các đối tượng ngôn ngữ PHP.

\n";

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

bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
4, truy cập các cookie HTTP

2. Các Namespace và tên Class

Namespace và Lớp 

6 theo chuẩn “autoloading” PSR: [PSR-4]

Có nghĩa là mỗi lớp được khai báo trên mỗi file PHP riêng và namespace tối thiểu có một cấp, cấp đầu là tên vendor.

Tên lớp lại

6 đúng dạng NameClass.

bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
4, truy cập các cookie HTTP

bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
4, truy cập các cookie HTTP

Hằng theo chuẩn ở trên, tất cả

6 viết hoa, phân cách từ bởi _

Ví dụ hằng đúng chuẩn:


2. PSR-2 Coding Style Guide (Tiêu chuẩn trình bày code)

PSR-2 sẽ tạo cho bạn thói quen viết code đúng chuẩn, dễ đọc, đẹp. sẽ tạo cho bạn thói quen viết code đúng chuẩn, dễ đọc, đẹp.

Tổng quan về trình bày code PHP

  • Code

    6 tuân thủ PSR-1
  • Code

    6 sử dụng 4 ký tự space để lùi khối (không dùng tab)
  • Mỗi dòng code

    6 dưới 120 ký tự,

    9 dưới 80 ký tự.
  • 6 có 1 dòng trắng sau namespace, và

    6 có một dòng trắng sau mỗi khối code.
  • Ký tự mở lớp {

    6 ở dòng tiếp theo, và đóng lớp }

    6 ở dòng tiếp theo của thân class.
  • Ký tự { cho hàm

    6 ở dòng tiếp theo, và ký tự } kết thúc hàm

    6 ở dòng tiếp theo của thân hàm.
  • Các visibility (public, private, protected)  

    6 được khai báo cho tất cả các hàm và các thuộc tính của lớp;
  • Các từ khóa điều khiển khối(if, elseif, else) 

    6 có một khoảng trống sau chúng; hàm và lớp thì
    0 làm như vậy.
  • Mở khối { cho cấu trúc điều khiển

    6 trên cùng một dòng; và đóng khối này } với ở dòng tiếp theo của thân khối.
  • Hằng số 
    2,
    3,
    4

    6 viết với chữ thường.
  • Từ khóa 
    6 và 
    7 phải cùng dòng với
    8.
  • implements nhiều lớp, thì mỗi lớp trên một dòng
  • keyword
    9
    0 dùng sử dụng khai báo property.
  • Tên property KHÔNG NÊN có tiền tố _ nhằm thể hiện thuộc protect hay private.
  • Tham số cho hàm, phương thức: KHÔNG được thêm space vào trước dấu
    1 và

    6 có một space sau
    1. Các tham số
    4 trên nhiều dòng, nếu làm như vậy thì

    6 mỗi dòng 1 tham số.
  • 6, 
    7 PHẢI đứng trước
    8, còn
    9 phải đi sau.

Ví dụ:

 $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

    final public static function bar()
    {
        // method body
    }
}

5) Server-side Request  – các request tại server

PHP cung cấp các biến toàn cục:

bar($arg1);
Foo::bar($arg2, $arg3);

bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
4, truy cập các cookie HTTP

0

bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
5, truy cập các tham số của chuỗi query (query trong url)

1

FOR

2

3

TRY,CATCH

4

Trình bày Closure

5


3. PSR-3 Logger Interface (Giao diện logger)

PSR-3 Logger Interface: trình bày về các thành phần cần phải có của một Logger (ghi lại dấu vết của ứng dụng).

1. Các đặc điểm kỹ thuật

  • bar($arg1);
    Foo::bar($arg2, $arg3);
    6 với 8 phương thức ghi log theo chuẩn RFC 5424 thương sẽ được chia thành key log: debug, info, notice, warning, error, critical, alert, emergency.
  • Mọi method chỉ chấp nhận một string tin nhắn, hoặc object dùng method a__toString() để chuyển tất cả sang tring.
  • Message phải chứa placeholders với implementors phải replace giá trị từ array.
  • Tên placeholders phải phù hợp với key log.
  • Tên placeholders phải được phân cách bằng dấu ngoặc nhọn { và dấu ngoặc nhọn }.{ và dấu ngoặc nhọn }.
  • KHÔNG được chứa bất kỳ khoảng trắng giữa các ký tự tên placeholders.
  • chỉ NÊN gồm các ký tự A-Z, a-z, 0-9, dấu gạch dưới _, và thời gian,.. Việc sử dụng các ký tự khác thì để xem trong tương lai có được áp dụng không.Implementors CÓ THỂ sử dụng giữ chỗ để thực hiện các chiến lược thoát khác nhau và dịch các bản ghi để hiển thị. Người dùng KHÔNG NÊN pre-escape giá trị giữ chỗ vì họ không thể biết trong đó bối cảnh các dữ liệu sẽ được hiển thị.

Ví dụ:

6

2. Package

Các Interface và Class được mô tả chi tiết trong gói psr/log.

3. Psr\Log\LoggerInterface

7

4. Psr\Log\LoggerAwareInterface

8

5. Psr\Log\LogLevel

9


4. PSR-4 Autoloading Standard (Tiêu chuẩn về tự động nạp)

PSR-4 Autoloading Standard: trình bày về cách chỉ định ứng dụng tự động nạp (giống include, require) các file php, lớp, hàm khi nó cần dùng đến.

Các lớp có thể được load tự động khi dùng đến bằng cách sử dụng cơ chế autoload của PHP (http://php.net/autoload).

Để thống nhất và sử dụng dễ dàng, phù hợp với nhiều mã Autoload khác nên viết các lớp theo quy tắc sau:

* “lớp” ở đây ám chỉ cho:  class, interface,traits

* Tên xác định đầy đủ của một lớp có dạng:

0
  • Tên xác định đầy đủ PHẢI có một namespace gốc (hiểu là tên vendor)PHẢI có một namespace gốc (hiểu là tên vendor)
  • Tên xác định đầy đủ có thể có một hoặc nhiều namespace con.
  • Tên đầy đủ nó phải có một tên lớp kết thúc (ClassName)

* Khi một nạp một file thì nó phải tương ứng với một tên xác định đầy đủ của lớp.

  • Mỗi tên xác định đầy đủ phải tương ứng với một cấu trúc thư mục
  • Tên lớp kết thúc tương ứng với tên file:

Khi viết các lớp, theo quy tắc đó thì dễ dàng phát triển một bộ tự động nạp. Autoloader để khởi tạo ứng dụng.

Tham khảo mẫu Autoloader tự động đăng ký các lớp tự động tải vào khi dùng đến, với điều kiện các lớp viết theo PSR-4.

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md

Các Framework PHP phổ biến hầu hết theo chuẩn PSR-4, nên chúng đều có bộ Autoloader tương tự.


5. PSR-6 Caching Interface (Giao diện về Caching)

PSR-6 Caching Interface là tiêu chuẩn cần có của một bộ ứng dụng caching (lưu tạm dữ liệu và database, đĩa, RAM …)

Tham khảo thông tin tại đây


6. PSR-7 HTTP Message Interface (Tiêu chuẩn Giao diện thông điệp HTTP)

PSR-7 HTTP Message Interface là tiêu chuẩn về giao diện (thành phần cần có) của một ứng dụng sử dụng thông điệp HTTP (HTTP Message – request và respone), nó căn cứ vào các tiêu chuẩn RFC 7230, RFC 7231, RFC 3986.

Thông điệp HTTP là nền tảng của ứng dụng web. Các Web Browser và các trình khách HTTP như cURL tạo ra một thông điệp HTTP (

bar($arg1);
Foo::bar($arg2, $arg3);
7), rồi gửi nó đến web server, server nhận được thông điệp (có thể hiểu là yêu cầu) đó, nó sẽ gửi về một thông điệp HTTP (
bar($arg1);
Foo::bar($arg2, $arg3);
8).

Hướng dẫn php style guide - hướng dẫn kiểu php

Cấu tạo các HTTP MESSAGE

Các HTTP message thường thì không được nhìn thấy, không cần phải hiểu bởi người dùng, nhưng với người phát triển web thì rất nên hiểu về cấu trúc để sử dụng chúng thi hành các tác vụ theo yêu cầu.

Mọi HTTP Request Message đều có dạng:

1

Dòng đầu tiên yêu cầu, theo thứ tự chứa thông tin: phương thức yêu cầu (POST,GET …), đích yêu cầu (thường là URI hoặc đường dẫn trên web), và phiên bản của giao thức HTTP. Theo sau là các dòng HTTP header nếu nó, một dòng trống, cuối cùng là nội dung message.

Mọi HTTP Response Message đều có dạng:

2

Dòng đầu là dòng trạng thái, theo thứ tự chứa phiên bản giao thức HTTP, mã trả về, và dòng mô tả mã. Tiếp theo là các dòng header nếu có, tiếp theo một dòng trống và cuối cùng là nội dung của HTTP Response Message.

Thuật ngữ gợi ý của PSR bạn lưu ý đó là: PHẢI, KHÔNG PHẢI, KHUYẾN NGHỊ … đó là các từ để căn cứ để bạn quyết định áp dụng phần nào của kỹ thuật vào ứng dụng.

Tiếp theo là các mô tả và namespace, interface class, các phương thức nên theo.

Các đặc điểm kỹ thuật về HTTP MESSAGE

1) Thông điệp (Message)

Một thông điệp HTTP có thể là yêu cầu gửi đi từ client hoặc thông điệp đáp trả từ server cho client. Như vậy cần phải có các lớp định nghĩa giao diện cho các thông điệp yêu cầu (request) Psr\Http\Message\RequestInterface và giao diện thông điệp đáp trả (response) Psr\Http\Message\ResponseInterface. Cả hai loại thông điệp này đều kế thừa từ một giao diện chung có Psr\Http\Message\MessageInterface.

Psr\Http\Message\MessageInterface

4được viết trực tiếp, nhưng bạn

9 có kế từ cho Psr\Http\Message\RequestInterface và Psr\Http\Message\ResponseInterface.
4
được viết trực tiếp, nhưng bạn

9
 có kế từ cho Psr\Http\Message\RequestInterface và Psr\Http\Message\ResponseInterface.

2) Về các HTTP Header

Không phân biệt chữ hoa – thường

Các header được truy cập bởi tên của header đó trong bởi phương thức (withHeader) trong MessageInterface và phương thức này không phân biệt chữ hoa và chữ thường.

Ví dụ:

3

Bởi vì tên của header khi các server trả về có chữ hoa, chữ thường nên bạn

6 xử lý việc này trong hàm getHeaders().

6
xử lý việc này trong hàm getHeaders().

Header nhiều giá trị

Thông lệ thì các header với nhiều giá trị vẫn được dùng, header có thể nhận được từ MessageInterface như là một mảng hoặc chuỗi. Sử dụng phương thức getHeaderLine() để nhận chuỗi có chứa giá trị phân cách bởi dấu

1. Sử dụng getHeader để nhận mảng tất cả giá trị header.

Ví dụ:

4

Bởi vì tên của header khi các server trả về có chữ hoa, chữ thường nên bạn

6 xử lý việc này trong hàm getHeaders().

Header nhiều giá trị

6 thiết lập Host header từ một URI nếu Host chưa được thiết lập. Hàm RequestInterface::withUri() làm điều này.

Thông lệ thì các header với nhiều giá trị vẫn được dùng, header có thể nhận được từ MessageInterface như là một mảng hoặc chuỗi. Sử dụng phương thức getHeaderLine() để nhận chuỗi có chứa giá trị phân cách bởi dấu
1. Sử dụng getHeader để nhận mảng tất cả giá trị header.

Host trong Header

Khi khởi tạo thông điệp Request 

6 thiết lập Host header từ một URI nếu Host chưa được thiết lập. Hàm RequestInterface::withUri() làm điều này.

3) Streams – Các luồng

HTTP message chứa dòng bắt đầu, các header và body(nội dung). Phần body của thông điệp có thể rất nhở hoặc rất lớn. Nếu cố tình nhét tất cả dữ liệu vào body với kiểu chuỗi thì có vẻ dễ nhưng nhiều trường hợp ảnh hưởng nghiêm trọng đến bộ nhớ lưu giữ body.  Khi dữ liệu lớn bạn sẽ sử dụng StreamInterface để diễn tả dữ liệu được đọc/ghi của body. Nhưng trường hợp này chuỗi dữ liệu body của thông điệp được sử dụng từ php://memory hoặc php://temp. (php://memory và php://temp là luồng chuẩn PHP xem tại php://)

Các Stream có thể dùng ba phương thức: isReadable(), isWritable(), isSeekable() để kiểm tra giới hạn của Stream (đọc, ghi, tìm).

  • Cuối cùng StreamInterface định nghĩa phương thức __toString() để nhận hoặc chuyển dữ liệu., chứa đường dẫn URL
  • 4) Request Targets và URIs, chứa scheme và người gửi authority (“[user-info@]host[:port]”)
  • Request target(mục tiêu – đích của HTTP mgs) có thể ở dạng sau:, chỉ chứa authority
  • origin-form, chứa đường dẫn URL, kiểm tra khả năng.

absolute-form, chứa scheme và người gửi authority (“[user-info@]host[:port]”)

Ví dụ:

5
Bởi vì tên của header khi các server trả về có chữ hoa, chữ thường nên bạn

6 xử lý việc này trong hàm getHeaders().

Header nhiều giá trị

  • Thông lệ thì các header với nhiều giá trị vẫn được dùng, header có thể nhận được từ MessageInterface như là một mảng hoặc chuỗi. Sử dụng phương thức getHeaderLine() để nhận chuỗi có chứa giá trị phân cách bởi dấu
    1. Sử dụng getHeader để nhận mảng tất cả giá trị header.
  • Host trong Header
  • Khi khởi tạo thông điệp Request 

    6 thiết lập Host header từ một URI nếu Host chưa được thiết lập. Hàm RequestInterface::withUri() làm điều này.
  • 3) Streams – Các luồng
  • HTTP message chứa dòng bắt đầu, các header và body(nội dung). Phần body của thông điệp có thể rất nhở hoặc rất lớn. Nếu cố tình nhét tất cả dữ liệu vào body với kiểu chuỗi thì có vẻ dễ nhưng nhiều trường hợp ảnh hưởng nghiêm trọng đến bộ nhớ lưu giữ body.  Khi dữ liệu lớn bạn sẽ sử dụng StreamInterface để diễn tả dữ liệu được đọc/ghi của body. Nhưng trường hợp này chuỗi dữ liệu body của thông điệp được sử dụng từ php://memory hoặc php://temp. (php://memory và php://temp là luồng chuẩn PHP xem tại php://)

Các Stream có thể dùng ba phương thức: isReadable(), isWritable(), isSeekable() để kiểm tra giới hạn của Stream (đọc, ghi, tìm).

Cuối cùng StreamInterface định nghĩa phương thức __toString() để nhận hoặc chuyển dữ liệu.

4) Request Targets và URIs

Request target(mục tiêu – đích của HTTP mgs) có thể ở dạng sau:

origin-form, chứa đường dẫn URL

absolute-form, chứa scheme và người gửi authority (“[user-info@]host[:port]”)

authority-form, chỉ chứa authority

asterisk-form, kiểm tra khả năng.

URL được định nghĩa bởi UriInterface, nó cung cấp __toString() để lấy URI. Nhận request target bằng phương thức getRequestTarget().


5) Server-side Request  – các request tại server

PHP cung cấp các biến toàn cục: Bạn có thể tham khảo tại http://www.php-fig.org/psr/