Chuẩn viết code PHP
Chuẩn viết code
Chuẩn viết code (tiếng Anh gọi là coding standards, coding style hoặc coding conventions) là các quy tắc nhằm đảm bảo những thành viên trong công ty cùng viết theo 1 kiểu để giúp mọi người đọc code của nhau dễ hơn và nhanh hơn.
Chúng ta sử dụng quy tắc của WordPress và chỉnh sửa đôi chút. Các chỉnh sửa được nói cụ thể ở phần dưới.
Các quy tắc nào không được nhắc đến ở đây thì mặc định hiểu là dùng theo chuẩn của WordPress.
Môt bộ quy tắc bao gồm:
- Đặt tên biến, hằng, hàm, class, …
- Khoảng trắng, tab
- Khai báo và sử dụng biến
- Comment
- Độ dài tối đa mỗi dòng code, mỗi file, …
- …
Khai báo mảng
WordPress bắt buộc dùng kiểu khai báo mảng dạng dài array(1, 2, 3), tuy nhiên, từ bản 5.4 trở đi, PHP hỗ trợ viết theo dạng ngắn [1, 2, 3]. Vì thế, bạn nên dùng dạng ngắn để code được ngắn gọn và cùng kiểu với JavaScript (nhờ đó dễ đọc hơn).
Hàm nặc danh và lời gọi hàm nhiều dòng
WordPress yêu cầu bắt buộc những viết hàm nặc danh và lời gọi hàm nhiều dòng phải xuống dòng, VD:
// Hàm nặc danh
add_action(
'some_action',
function ( $matches ) {
echo 'Something';
}
);
// Lời gọi hàm nhiều dòng
$args = wp_parse_args(
$args,
array(
'key1' => 'value1',
'key2' => 'value2',
)
);
Tuy nhiên, việc xuống dòng này là không cần thiết và không bắt buộc. Bạn có thể viết:
// Hàm nặc danh
add_action( 'some_action', function () {
echo 'Something';
} );
// Lời gọi hàm nhiều dòng
$args = wp_parse_args( $args, [
'key1' => 'value1',
'key2' => 'value2',
] );
Code language: PHP (php)
Thẻ PHP ngắn
WordPress bắt buộc phải viết đầy đủ thẻ PHP như sau:
<?php echo 'Some text'; ?>
Tuy nhiên, từ bản 5.4, PHP đã hỗ trợ viết thẻ PHP ngắn (và tính năng này luôn được bật). Nên bạn có thể dùng nó để cho câu lệnh gọn gàng hơn:
<?= 'Some text'; ?>
Bạn có thể bỏ luôn dấu chấm phẩy cuối câu lệnh:
<?= 'Some text' ?>
Đặt tên file và class
WordPress bắt buộc tất cả các class đều phải đặt tên dạng Ten_Class (viết hoa đầu các từ và phân cách bằng dấu gạch dưới), và tên file của class phải viết dạng class-ten-class.php (có tiền tố class- và các từ trong tên class viết thường, phân cách bằng dấu gạch ngang).
Tuy nhiên, cách làm này không tốt khi dùng Composer, vì Composer tuân theo cách viết của PSR. Khi làm việc với các plugin, theme lớn, chúng ta dùng Composer để load tự động các file, do đó chúng ta sẽ tuân thủ theo quy tắc đặt tên file và class của PSR, cụ thể:
- Tên class: đặt theo dạng
TenClass(viết hoa đầu các từ và viết liền các từ) - Tên file: đặt dạng
TenClass.php(tên file trùng với tên class)
Ngoài ra, các file sẽ được đặt trong các thư mục tương ứng với namespace của chúng, VD class có tên đầy đủ là: \ALSearch\Shortcode\Field thì sẽ được đặt trong thư mục src\ShortCode với tên file là Field.php. Ở đây thư mục src được ánh xạ tới namespace ALSearch còn các phần tiếp theo trong tên class được ánh xạ tới các thư mục theo cùng phân cấp tương ứng.
Toán tử :?
WordPress không cho dùng toán tử :? ở dạng ngắn mà luôn yêu cầu viết đầy đủ:
$type = $type ? $type : 'select';
Tuy nhiên, từ bản 5.3, PHP đã cho phép viết ngắn lại để dễ đọc hơn, và công ty chúng ta cũng khuyến khích dùng cách viết này:
$type = $type ?: 'select';
Điều kiện Yoda
Khi viết điều kiện, WordPress yêu cầu chúng ta viết biến bên phải và các hằng, giá trị, lời gọi hàm bên trái:
if ( true === $the_force ) {
$victorious = you_will( $be );
}
Mục đích là để đảm bảo kiểu dữ liệu (khi so sánh PHP sẽ ép kiểu) và tránh lỗi (VD bạn viết = thay vì viết ==). Tuy nhiên, cách viết này khiến code khó đọc và khó hiểu, nhất là với người mới. Vì thế công ty không bắt buộc kiểu viết này.
PHPCS
Công cụ để kiểm tra chuẩn viết code và sửa các lỗi về chuẩn viết code được khuyến cáo dùng là PHP CodeSniffer.
Cài đặt Composer
Trước hết bạn cần cài đặt Composer.
Khi chạy install composer chọn file php.exe ở trong xampp

Xóa dấu ; ở trước extension=php_openssl.dll trong file php.ini

Thêm đường dẫn của php (E:\xampp\php) vào Path

Cài PHPCS
Bật cmd chạy lệnh:
composer global require dealerdirect/phpcodesniffer-composer-installer wp-coding-standards/wpcs phpcompatibility/phpcompatibility-wp
# Kiểm tra chuẩn viết code phpcs --standard=WordPress /path/to/folder/ # Sửa các lỗi về chuẩn viết code phpcbf --standard=WordPress /path/to/folder/
File cấu hình
Tham khảo file cấu hình.
Best Practices
Phần này mô tả các kỹ thuật giúp cho code được viết tối ưu hơn, dễ bảo trì hơn và dễ đọc hơn.
Viết code thống nhất
Viết cùng 1 kiểu trong 1 hàm, class hoặc file. Tránh viết các kiểu khác nhau cho các đoạn code tương tự.
VD viết sai:
<?php if ( $args['label'] ) : ?>
<span class="als-field__label"><?php echo esc_html( $args['label'] ); ?></span>
<?php endif; ?>
<?php
if ( $args['prefix'] ) {
echo '<span class="als-field__prefix">' . esc_html( $args['prefix'] ) . '</span>';
}
Đoạn code trên hiển thị label và prefix. Tuy cách hiển thị giống nhau, nhưng cách viết lại khác nhau. Cách viết đúng như sau:
if ( $args['label'] ) {
echo '<span class="als-field__label">', esc_html( $args['label'] ), '</span>';
}
if ( $args['prefix'] ) {
echo '<span class="als-field__prefix">', esc_html( $args['prefix'] ), '</span>';
}
Trả về sớm
Việc viết các khối điều kiện quá lớn khiến code rất khó đọc và khó theo dõi logic. Để khắc phục điều này, cần phải viết các khối điều kiện nhỏ lại. Một trong những kỹ thuật đó là trả về sớm sớm ngay khi có thể, tiếng Anh gọi là “early return”.
VD khi chưa tối ưu:
if ( 'none' !== $field['sanitize_callback'] ) {
if ( is_callable( $field['sanitize_callback'] ) {
$value = call_user_func( $field['sanitize_callback'], $value, $args );
} else {
// Đoạn code rất dài.
}
}
return $value;
Cách viết dùng trả về sớm:
if ( 'none' === $field['sanitize_callback'] ) {
return $value;
}
if ( is_callable( $field['sanitize_callback'] ) {
return call_user_func( $field['sanitize_callback'], $value, $args );
}
// Đoạn code rất dài.
return $value;
Đặt giá trị mặc định
Đặt giá trị mặc định giúp chúng ta loại bỏ các câu điều kiện kiểm tra sự tồn tại của giá trị đó, qua đó giúp code đơn giản, dễ đọc hơn.
VD khi chưa tối ưu:
if ( isset( $args['prefix'] ) && $args['prefix'] !== '' ) {
echo '<span class="als-field__prefix">', esc_html( $args['prefix'] ), '</span>';
}
if ( isset( $args['label'] ) && $args['label'] !== '' ) {
echo '<span class="als-field__label">', esc_html( $args['label'] ), '</span>';
}
Code language: PHP (php)
Khi dùng giá trị mặc định:
$args = wp_parse_args( $args, [
'prefix' => '',
'label' => '',
] );
if ( $args['prefix'] ) {
echo '<span class="als-field__prefix">', esc_html( $args['prefix'] ), '</span>';
}
if ( $args['label'] ) {
echo '<span class="als-field__label">', esc_html( $args['label'] ), '</span>';
}
Output nhiều giá trị với echo
Khi cần output nhiều đoạn text, thường chúng ta viết dạng:
echo '<span class="als-field__prefix">' . esc_html( $args['prefix'] ) . '</span>';
Tuy nhiên, hàm echo cho phép chúng ta truyền nhiều tham số 1 lúc, và do đó hoạt động sẽ nhanh hơn:
echo '<span class="als-field__prefix">', esc_html( $args['prefix'] ), '</span>';
Khai báo muộn và khai báo khi cần thiết
Các biến được khai báo chỉ khi nào cần thiết. Khai báo ở đây bao gồm cả việc khởi tạo giá trị ban đầu. Và việc khai báo nên để muộn nhất có thể, tốt nhất là ngay trên đoạn code sử dụng biến đó.
VD về việc khai báo biến thừa:
$date = parent::get_date();
$format = ''; // Khai báo thừa, vì biến này được khai báo lại ở đoạn code dưới
if ( $meta ) {
$format = 'Y-m-d';
return date( $format, $date );
}
Code đúng:
$date = parent::get_date();
if ( $meta ) {
$format = 'Y-m-d';
return date( $format, $date );
}
VD về việc khai báo biến quá sớm, chưa dùng đến:
$format = 'Y-m-d'; // Đoạn code rất dài. return date( $format, $date );
Biến $format chỉ nên khai báo ngay trước đoạn code dùng nó:
// Đoạn code rất dài. $format = 'Y-m-d'; return date( $format, $date );
