PSR-2: Chuẩn trình bày code PHP đẹp
PSR-2: Coding Style Guide Bộ quy tắc này được tạo ra nhằm giảm bới những khó khăn trong việc đọc code của người khác, trình bày theo quy tắc ở đây áp dụng cho tất cả các Project, giúp cho code sáng sủa, dễ hiểu, dễ bảo trì hơn. Bài viết này yêu cầu bạn xem qua PSR-1: Chuẩn viết code PHP cơ bản bởi vì chuẩn PSR-2 dựa trên PSR-1 và mở rộng thêm
1. Nguyên tắc chung
1.1. Tuân thủ PSR-1
PSR-2 dựa trên PSR-1 và mở rộng thêm cho nên tuân thủ theo PSR-1 là điều hoàn toàn dễ hiểu phải không nào, đọc ngay PSR-1 tại đây: PSR-1: Chuẩn viết code PHP cơ bản
1.2. Đối với file php
- Mọi PHP files phải dùng Unix LF (linefeed) line ending.
- Mọi PHP files phải kết thúc bằng một dòng trống.
- Trong một file chỉ bao gồm code PHP thì không được viết tag đóng
?>
nhé.
Nếu bạn dùng Editor/IDE, bạn nên cài EditorConfig để Editor/IDE giúp bạn trong việc này nhé, đọc ở đây Chuẩn hóa code style trên Editor/IDE bằng EditorConfig, trên sublime text Editor sẽ là end_of_line = lf
và insert_final_newline = true
1.3. Lines - Về các dòng code
- Không có hard limit về độ dài của một dòng. Tức là bạn có thể code 1 dòng dài đến tận cùng thế giới vẫn được.
- Soft limit của độ dài một dòng phải là 120 chữ. Chương trình check style tự động phải báo warning nhưng không được báo error khi vượt quá soft limit.
- Một dòng nên có không quá 80 chữ. Dòng mà dài quá 80 chữ thì nên chia nhỏ ra thành nhiều dòng với độ dài mỗi dòng không quá 80 chữ.
Trong Sublime Text, bạn có thể chỉnh như sau để biết mình quá 80 ký tự hay không nha, ở trên thanh menu các bạn chọnView
➡Ruler
➡80
- Một dòng mà có ký tự thì không được dư khoảng trắng ở cuối dòng.
public function foo() { return true;・・・・ } // ・・・・ chính là khoảng trắng
- Không được phép có quá một statement (lệnh) trên một dòng.
// sai quá sai $website = 'https://chungnguyen.xyz'; $name = 'Chung Nguyễn Blog'; // phải như vầy $website = 'https://chungnguyen.xyz'; $name = 'Chung Nguyễn Blog';
1.4. Indenting - Canh lề
Canh lề không dùng tab mà phải dùng 4 dấu cách. Các Editor/IDE thông minh sẽ tự convert nút tab trên bàn phím thành dấu cách, các bạn search google sẽ ra nhé. Hình dưới là cách cấu hình cho sublime text
1.5. Keywords và True/False/Null
Những keywords của PHP phải được viết thường. (không viết hoa)
Những constants của PHP là true
, false
, và null
cũng cần phải viết thường. TRUE, True gì cơ bản là sai nguyên tắc hết nhé.
2. Khai báo Namespace và Use
- Cần phải có một dòng trắng phía sau khai báo
namespace
. - Những phần khai báo
use
phải được đặt phía sau phần khai báonamespace
. - Phải dùng một từ
use
cho mỗi khao báo. - Phải có một dòng trắng phía sau đoạn code
use
.
Ví dụ:
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
use Auth, View, Session; // sai, phải tách thành 3 dòng use
// ... additional PHP code ...
3. Classes, Properties, and Methods (Lớp, Thuộc tính và Phương thức - hàm)
Từ class ở đây được hiểu là cả những class bình thường, hay cả interfaces và traits.
3.1. Extends và Implements
Từ khoá extends
và implements
phải được viết cùng dòng với tên class.
Dấu mở ngoặc nhọn của class phải đứng trên một dòng riêng. Dấu đóng ngoặc phải được viết ở dòng sau của phần body.
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
// constants, properties, methods
}
Danh sách những interface được implements
có thể được viết trên nhiều dòng, trong đó mỗi dòng theo sau được indent (canh lề) 1 lần. Khi thực hiện việc đó thì tên interface đầu tiên phải được đặt trên 1 dòng mới, và mỗi dòng chỉ được phép chứa tên 1 interface.
Ví dụ
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// constants, properties, methods
}
3.2. Properties - thuộc tính
Tính Visibility (public, protected, private) phải được khai báo ở mọi properties.
Không được dùng từ khoá var
để khai báo một property.
Trên một dòng thì không được khai báo quá một property.
Tên property không nên được prefix bởi dấu gạch dưới _
để biểu thị tính protected hay private.
Khai báo property giống như sau.
<?php
namespace Vendor\Package;
class ClassName
{
public $foo = null;
}
3.3. Methods
Tương tự với property, tính Visibility phải được khao báo ở mọi methods
Tên Method không nên được prefix bởi dấu gạch dưới _
để biểu thị tính protected hay private.
Khi khai báo tên method thì không được để một khoảng trắng ở phía sau tên method. Dấu mở ngoặc nhọn phải được nằm trên một dòng riêng, và dấu đóng ngoặc phải được nằm trên dòng ngay sau phần thân của method. Không được có khoảng trắng sau dấu mở ngoặc tròn, và không được có khoảng trắng phía trước dấu đóng ngoặc tròn.
Khai báo một hàm giống như sau. Chú ý đến vị trí của dấu ngặc đơn, dấu phẩy, khoảng trắng và dấu ngoặc nhọn.
<?php
namespace Vendor\Package;
class ClassName
{
public function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// method body
}
}
3.4. Method Arguments - Tham số của phương thức
Trong danh sách argument (tham số - đối số) thì không được có khoảng trắng trước mỗi dấu phẩy, và phải có một khoảng trắng sau mỗi dấu phẩy. Giống y như chính tả của ta vậy.
Những tham số mà có giá trị mặc định phải được đặt ở cuối của danh sách tham số. Ví du:
<?php
namespace Vendor\Package;
class ClassName
{
public function foo($arg1, &$arg2, $arg3 = [], $arg4 = true)
{
// method body
}
}
Danh sách argument có thể được tách thành nhiều dòng, trong đó mỗi dòng theo sau được indent một lần. Khi làm vậy thì argument đầu tiên trong danh sách phải được đặt ở trên một dòng mới, và mỗi dòng chỉ được phép có một argument.
Khi mà danh sách argument được chia làm nhiều dòng, thì dấu đóng ngoặc tròn và dấu mở ngoặc nhọn phải được đặt cùng nhau trên một dòng, với một khoảng trắng ở giữa.
<?php
namespace Vendor\Package;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = [],
$arg4 = true
) {
// method body
}
}
3.5. abstract
, final
, và static
Khi được sử dụng, abstract
và final
phải được đặt trước phần khai báo visibility.
Khi được sử dụng, static
phải được đặt sau phần khai báo visibility.
<?php
namespace Vendor\Package;
abstract class ClassName
{
protected static $foo;
abstract protected function zim();
final public static function bar()
{
// method body
}
}
3.6. Gọi Method và Function
Khi gọi một method hay một function thì
- không được phép có khoảng trắng giữa tên của method hay function và dấu mở ngoặc tròn.
- Không được phép có khoảng trắng sau dấu mở ngoặc tròn.
- Và không được phép có khoảng trắng trước dấu đóng ngoặc tròn.
- Trong danh sách argument, không được phép có khoảng trắng trước mỗi dấu phẩy, và phải có một khoảng trắng sau mỗi dấu phẩy.
<?php
bar (); // sai cái số 1
bar() ; // sai cái số 2
bar( ); // sai cái số 3
bar($arg1 , $arg2); // sai cái số 4
// đúng phải như vầy
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
Danh sách tham số có thể được tách ra thành nhiều dòng, trong đó mỗi dòng theo sau được indent một lần. Khi làm như vậy thì tham số đầu tiên phải được đặt trên một dòng mới, và mỗi dòng chỉ được phép chứa một tham số.
<?php
$foo->bar($firstArgument // sai vì tham số đầu tiên phải ở dòng mới
$longArgument, // sai vì k có 1 canh lề
$longerArgument, $longerArgument2, // sai vì có 2 tham số trên 1 dòng
$muchLongerArgument
);
// chuẩn
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
4. Control Structures - cấu trúc điều khiển
Những quy tắc chung khi viết Control Structures bao gồm:
- Phải có một khoảng trắng sau control structure keyword
- Không được có một khoảng trắng sau dấu mở ngoặc tròn
- Không được có một khoảng trắng trước dấu đóng ngoặc tròn
- Phải có một khoảng trắng sau đấu đóng ngoặc tròn và trước dấu mở ngoặc nhọn
- Phần thân của structure phải được indent một lần
- Dấu đóng ngoặc nhọn phỉa được đặt trên một dòng mới sau phần thân
Phần thân của mỗi structure phải được đặt trong dấu đóng mở ngoặc kép. Điều này sẽ làm tiêu chuẩn hoá cách viết structures, và làm giảm thiểu việc phát sinh ra lỗi khi mà có những dòng mới được thêm vào phần thân.
5.1. if
, elseif
, else
Một if
structure được viết như sau. Hãy chú ý đến vị trí của dấu ngoặc tròn, khoảng trắng, dấu ngoặc nhọn. else
và elseif
được đặt trên cùng một dòng với dấu đóng ngoặc nhọn của phần body phía trước.
<?php
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
5.2. switch
, case
Một switch
structure được viết như sau. Hãy chú ý đến vị trí của dấu ngoặc tròn, khoảng trắng và dấu ngoặc nhọn. Phần case
phải được indent một lần so với switch
, và break
keyword (hay các keyword ngắt khác) phải được indent giống với phần thân của case
. Phải có một comment kiểu như // no break
nếu phần thân của case
không trống, và được cố tình cho qua (không có break)
<?php
switch ($expr) {
case 0:
echo 'First case, with a break';
break;
case 1:
echo 'Second case, which falls through';
// no break
case 2:
case 3:
case 4:
echo 'Third case, return instead of break';
return;
default:
echo 'Default case';
break;
}
5.3. while
, do while
Một câu lệnh while
được viết như sau. Hãy chú ý vào vị trí của dấu ngoặc tròn, khoảng trắng và dấu ngoặc nhọn.
<?php
while ($expr) {
// structure body
}
Tương tự như vậy, một câu lệnh do while
được viết như sau. Hãy chú ý vào vị trí của dấu ngoặc tròn, khoảng trắng và dấu ngoặc nhọn.
<?php
do {
// structure body;
} while ($expr);
5.4. for
Một câu lệnh for
được viết như sau. Hãy chú ý vào vị trí của dấu chấm phẩy, dấu ngoặc tròn, khoảng trắng và dấu ngoặc nhọn.
<?php
for ($i = 0; $i < 10; $i++) {
// for body
}
5.5. foreach
Một câu lệnh foreach
được viết như sau. Hãy chú ý vào vị trí của =>
, dấu ngoặc tròn, khoảng trắng và dấu ngoặc nhọn.
<?php
foreach ($iterable as $key => $value) {
// foreach body
}
5.6. try
, catch
Một block try catch
được viết như sau. Hãy chú ý vào vị trí của dấu ngoặc tròn, khoảng trắng và dấu ngoặc nhọn.
<?php
try {
// try body
} catch (FirstExceptionType $e) {
// catch body
} catch (OtherExceptionType $e) {
// catch body
}
5. Closures
Closures phải được định nghĩa mới một khoảng trắng phía sau keywork function
, và một khoảng trắng ở phía trước cũng như phía sau của keywork use
.
Dấu mở ngoặc ngọn phải được đặt ở cùng dòng, và dấu đóng ngoặc nhọn phải được đặt ở một dòng mời phía sau phần thân.
Không được phép có một khoảng trắng ở phía sau dấu mở ngoặc tròn của phần khai báo danh sách argument hay variable, và không được phép có một khoảng trắng ở phía trước dấu đóng ngoặc tròn của phần khai báo danh sách argument hay variable.
Trong danh sách arugment hay variable, không được phép có khoảng trắng trước mỗi dấu phẩy, và phải có một khoảng trắng phía sau mỗi dấu phẩy.
Arguments của Closure mà có giá trị mặc định thì phải được đặt ở cuối của danh sách argument.
Cách định nghĩa một closure trông như sau.
A closure declaration looks like the following. Hãy chú ý vào vị trí của dấu ngoặc tròn, dấu phẩy, khoảng trắng và dấu ngoặc nhọn.
Danh sách argument và danh sách variable có thể được tách ra làm nhiều dòng, trong đó mỗi dòng theo sau được indent một lần. Khi làm như vậy thì argument hay variable đầu tiên phải được đặt ở trên một dòng mới, và mỗi dòng chỉ được phép chứa một argument hay một variable.
Khi mà kết thúc của danh sách (kể cả arguments hay variables) được chia thành nhiều dòng, thì dấu đóng ngoặc tròn và dấu mở ngoặc nhọn phải được đặt cùng nhau trên một dòng, với một khoảng trắng ở giữa.
Dưới đây là những ví dụ về các closures có và không có danh sách argument hay variable được chia thành nhiều dòng.
Chú ý rằng những quy tắc trên còn được áp dụng khi một closure được sử dụng trục tiếp như một argument trong một lời gọi hàm hay method.
6. Kết luận
Có rất nhiều yếu tố về style hay practice khác được cố tình bỏ qua trong hướng dẫn này. Có thể kể ra như:
-
Khai báo biến global (global variables) hay hằng global (global constants)
-
Khai báo hàm (functions)
-
Toán tử và phép gán
-
Inter-line alignment
-
Khối Comments và Documentation
-
Tiền tố và hậu tố trong tên Class
-
Best practices
Những recommendations sau này có thể xem xét lại và mở rộng hướng dẫn này để đề cập đến những yếu tố về style hay practice ở trên hay hoàn toàn khác.
Chúc các bạn nhớ hết các nguyên tắc này nhé 😂😂😂
Ủng hộ Chung Nguyễn Blog
Chung Nguyễn Blog sử dụng FlashVPS - Dịch vụ quản trị máy chủ chuyên nghiệp để quản lý VPS
#FlashVPS là dịch vụ cloud panel trên nền tảng web hỗ trợ khách hàng:
- * Quản lý máy chủ số lượng nhiều
- * Không có kinh nghiệm quản lý máy chủ
- * Thích sử dụng giao diện web đơn giản, trực quan hơn terminal
- * Quá nhàm chán với việc ghi nhớ và lặp lại việc gõ các câu lệnh
- * Muốn tự động hóa mọi thao tác
- * Muốn tiết kiệm thời gian quản trị máy chủ
- * Muốn tiết kiệm tiền bạc, nhân lực quản trị máy chủ 👉 https://flashvps.dev
Các bài viết trên website thường xuyên được đăng tải và cập nhật trên trang Facebook Chung Nguyễn Blog hãy tặng cho Chung một LIKE nhé! Mãi yêu các bạn!
813 👍
Bình luận
Võ Tiến Dũng
bài viết rất hay!