NTM Solutions

Thứ Tư, 19 tháng 12, 2018

Khóa học CodeIgniter-Bài 25-Hướng dẫn định dạng PHP

#hoccodeigniter


Bài viết này mô tả các định dạng viết mã phải tuân thủ khi đóng góp xây dựng phát triển CodeIgniter. Không ai bắt buộc bạn dùng các kiểu định dạng này trong ứng dụng CodeIgniter của riêng bạn, cho dù chúng được khuyến cáo.


Nội dung bài viết:

·         Định dạng tập tin

o   TextMate

o   BBEdit

o   Notepad++

·         Thẻ đóng PHP

·         Đặt tên tập tin

·         Đặt tên lớp và phương thức

·         Đặt tên biến

·         Ghi chú

·         Hằng số

·         TRUE, FALSE, và NULL

·         Toán tử logic

·         Giá trị trả về của phép so sánh và sắp chữ

·         Mã biên dịch

·         Dòng trắng trong tập tin

·         Sự tương thích

·         Mỗi tập tin chứa 01 lớp

·         Khoảng trắng

·         Ngắt dòng

·         Thụt đầu dòng đoạn mã

·         Cặp dấu ngoặc và khoảng trắng

·         Địa phương hóa chuỗi

·         Phương thức và biến private

·         Lỗi PHP

·         Thẻ mở viết tắt

·         Mỗi dòng 01 câu lệnh

·         Chuỗi

·         Câu truy vấn SQL

·         Tham số hàm mặc định


Các tập tin nên được lưu ở định dạng bảng mã Unicode (UTF-8) . Không nên dùng BOM. Không giống UTF-16 và UTF-32, không có thứ tự byte để biểu thị  trong 01 tập tin định dạng UTF-8, và BOM có thể tạo hiệu ứng tiêu cực tác động đến việc PHP gửi dữ liệu xuất, ngăn ngừa ứng dụng có thể thiết lập các headers của riêng nó. Nên dùng dòng kết thúc của Unix (LF).

Sau đây là cách thiết lập trên vài trình soạn thảo thông dụng. Nếu trình soạn thảo của bạn có chỗ nào khác biệt hãy kiểm tra tài liệu hướng dẫn kèm theo (như mục HELP chẳng hạn)

Ghi chú:

TextMate và BBEdit là 02 trình soạn thảo dành cho mác MACS, các bạn có thể tải xuống tại đây:

·         https://macromates.com/


Notepad++ là trình soạn thảo dành cho Windows, các bạn có thể tải xuống tại đây:

https://notepad-plus-plus.org/



1.      Vào Application Preferences

2.      Bấm Advanced, và sau đó chọn tab “Saving

3.      Trong mục “File Encoding”, chọn “UTF-8 (khuyến cáo)”

4.      Trong “Line Endings”, chọn “LF (khuyến cáo)”

5.      Tùy chọn: chọn “Use for existing files as well” nếu bạn muốn sửa dòng kết thúc tập tin của tập tin hiện tại.


1.      Vào Application Preferences

2.      Chọn “Text Encodings” trong mục bên trái.

3.      Trong mục “Default text encoding for new documents”, chọn “Unicode (UTF-8, no BOM)

4.      Tùy chọn: trong mục “If file’s encoding can’t be guessed, use”, chọn “Unicode (UTF-8, no BOM)

5.      Chọn “Text Files” trong mục bên trái.

6.      Trong mục “Default line breaks”, chọn “Mac OS X and Unix (LF)

Notepad++

Vào menu Settings-> chọn References…



Thẻ đóng PHP trong 01 tập tin PHP ?> là tùy chọn đối với PHP parser. Tuy nhiên, nếu dùng, bất kỳ khoảng trắng nào theo sau thẻ đóng, có thể là do lập trình viên, người dùng, hoặc 01 chương trình FTP, có thể gây lỗi xuất dữ liệu không mong muốn, lỗi PHP, hoặc do dòng cuối bị chặn, hay là các trang rỗng. Vì lí do này, tất cả trang PHP (ngoại trừ view) PHẢI BỎ thẻ đóng PHP và thay vào đó sẽ kết thúc bằng 01 dòng trống.


Các tập tin khai báo lớp và controller PHẢI được đặt tên có chữ cái Hoa đầu từ, các loại tập tin khác (configurations, views, generic scripts, v.v.) nên đặt tên viết thường hết.

SAI:

somelibrary.php

someLibrary.php

SOMELIBRARY.php

Some_Library.php



Application_config.php

Application_Config.php

applicationConfig.php

ĐÚNG:

Somelibrary.php

Some_library.php



applicationconfig.php

application_config.php

Thêm 01 điều nữa là , các tập tin chứa lớp nào phải trùng tên lớp đó. Ví dụ, nếu bạn có 01 lớp tên là Myclass, thì tên tập tin chứa nó phải đặt tên là Myclass.php.


Tên lớp luôn nên được bắt đầu bằng 01 ký tự viết hoa. Nếu nhiều chữ thì phân cách nhau bằng dấu gạch dưới , không dùng kiểu HoaĐầuChữ.

SAI:

class superclass

class SuperClass

ĐÚNG:

class Super_class

class Super_class {



        public function __construct()

        {



        }

}

Các phương thức trong lớp nên đặt tên viết thường hoàn toàn và đặt tên chỉ rõ tính năng của chúng, khuyến cáo các bạn nên dùng 01 động từ để đặt tên. Hãy cố tránh đặt tên dài dòng và rườm rà. Nếu tên có nhiều từ thì phân cách bằng dấu gạch dưới.

SAI:

function fileproperties()

// không chi tiết và cần dấu gạch dưới để phân cách

function fileProperties()

// không chi tiết và sử dụng Viết Hoa Đầu Từ

function getfileproperties()

// Tốt hơn rồi! Nhưng vẫn thiếu dấu gạch dưới phân cách

function getFileProperties()

// dùng Hoa Đầu Từ

function get_the_file_properties_from_the_file()

// dùng nhiều từ ngữu quá

ĐÚNG:

function get_file_properties() 

// chi tiết, có dấu gạch dưới phân cách, và tất cả viết thường




Hướng dẫn cho việc đặt tên biến thì đơn giản hơn đặt tên phương thức của lớp. Các biến chỉ nên chứa ký tự viết thường, sử dụng dấu gạch dưới để phân cách, và tên đặt cho biến phải có ý nghĩa chỉ rõ mục đích và nội dung. Những từ cực ngắn, các biến không thành từ hoàn chỉnh chỉ nên đặt cho phần tử lặp trong các vòng lặp for()

SAI:

$j = 'foo';            

// biến có tên là 01 ký tự đơn chỉ nên dùng cho vòng lặp for()

$Str                // chứa ký tự viết Hoa

$bufferedText       // dùng Hoa Đầu Từ, và có thể rút ngắn mà không làm mất ngữu nghĩa

$groupid            // có nhiều từ nhưng không có dấu gạch dưới phân cách

$name_of_last_city_used // quá dài



ĐÚNG:

for ($j = 0; $j < 10; $j++)

$str

$buffer

$group_id

$last_city




Nhìn chung, khi viết mã ta nên ghi chú cho nhiều vào. Nó không chỉ giúp mô tả dòng chảy và ý định của dòng mã cho những lập trình viên ít kinh nghiệm, mà còn vô giá khi bạn quay lại dò các dòng mã hàng tháng trời sau đó. Không có yêu cầu định dạng nào cho các dòng ghi chús, nhưng sau đây chỉ là các khuyến cáo.

Phong cách ghi chú dạng DocBlock (dạng khối) đặt trước lớp, phương thức, và phần mô tả thuộc tính và do đó chúng có thể đọc được bởi các IDE (trình soạn thảo mã)

/**

 * Super Class

 *

 * @package     Package Name

 * @subpackage  Subpackage

 * @category    Category

 * @author      Author Name

 * @link        http://example.com

 */

class Super_class {

/**

 * Encodes string for use in XML

 *

 * @param       string  $str    Input string

 * @return      string

 */

function xml_encode($str)

/**

 * Data for class manipulation

 *

 * @var array

 */

public $data = array();

Sử dụng dòng ghi chú đơn đi kèm với mã, chừa ra 01 dòng trắng giữa khối ghi chú lớn và đoạn mã.

// break up the string by newlines

$parts = explode("\n", $str);



// A longer comment that needs to give greater detail on what is

// occurring and why can use multiple single-line comments.  Try to

// keep the width reasonable, around 70 characters is the easiest to

// read.  Don't hesitate to link to permanent external resources

// that may provide greater detail:

//

// http://example.com/information_about_something/in_particular/



$parts = $this->foo($parts);



Hằng số

Các hằng số được đặt tên theo cách giống như đặt tên biến,  ngoại trừ việc hằng số phải VIẾT HOA HẾT. Luôn sử dụng các hằng số CodeIgniter khi cần, ví dụ:. SLASH, LD, RD, PATH_CACHE, v.v

SAI:

myConstant      // thiếu dấu gạch dưới để phân cách và không VIẾT HOA TOÀN BỘ

N               // hằng số không được là 01 ký tự đơn

S_C_VER         // không chi tiết

$str = str_replace('{foo}', 'bar', $str);       // nên dùng các hằng số LD và RD thay cho cặp ngoặc nhọn {}

ĐÚNG:

MY_CONSTANT

NEWLINE

SUPER_CLASS_VERSION

$str = str_replace(LD.'foo'.RD, 'bar', $str);




Các từ khóa TRUE, FALSE, và NULL luôn nên VIẾT HOA TOÀN BỘ.

SAI:

if ($foo == true)

$bar = false;

function foo($bar = null)

ĐÚNG:

if ($foo == TRUE)

$bar = FALSE;

function foo($bar = NULL)




Sử dụng dấu || “or” để thay cho toán tử so sánh là rất không nên, vì rằng ở 01 số thiết bị hiển thị độ phân giải thấp nhìn giống số 11 . Trong khi dấu && được dùng thay cho toán tử AND lại được chấp nhận, và thêm 01 dấu khoảng trắng ngay trước và ngay sau dấu !

SAI:

if ($foo || $bar)

if ($foo AND $bar)  // ĐÚNG nhưng không nên dùng cho các ứng dụng có tô màu cú pháp thông thường

if (!$foo)

if (! is_array($foo))



ĐÚNG:

if ($foo OR $bar)

if ($foo && $bar) // khuyến cáo nên dùng

if ( ! $foo)

if ( ! is_array($foo))




01 vài hàm PHP trả về FALSE khi thực thi sai, nhưng đó cũng có thể là 01 giá trị hợp lệ thay cho giá trị chuỗi rỗng “” hoặc 0, vốn được trả về là FALSE khi phép so sánh sai. Các bạn cần phải rõ ràng trong kiểu biến so sánh  khi sử dụng giá trị trả về của chúng trong các biểu thức điều kiện nhằm đảm bảo giá trị trả về đúng như mong đợi, chứ không phải là giá trị có được do kết quả phép so sánh thất bại.

Các bạn cũng nên nghiêm ngặt đối với kết quả trả về và các biến tự tạo. Sử dụng dấu ===!== nếu thấy cần thiết.

SAI:

//Nếu chữ 'foo' nằm đầu chuỗi, hàm strpos sẽ trả về giá trị 0

// kết quả trả về trong điều kiện so sánh này là TRUE

if (strpos($str, 'foo') == FALSE)



ĐÚNG:

if (strpos($str, 'foo') === FALSE)

SAI:

function build_string($str = "")

{

        if ($str == "") // Ahihi!  Nếu tham số là FALSE hoặc số nguyên 0 thì chuyện gì sẽ xảy ra?

        {



        }

}

ĐÚNG:

function build_string($str = "")

{

        if ($str === "")

        {



        }

}

Các bạn cũng nên nghiên cứu về typecasting (sắp chữ), nó có thể hữu ích trong 01 số trường hợp. Sắp chữ có 01 ảnh hưởng khác biệt nhè nhẹ có thể gây ra hiệu ứng. Khi thử sắp xếp 01 biến như là 01 chuỗi, ví dụ như NULL và các biến luận lý FALSE trở thành chuỗi rỗng, 0 (và các con số khác) là các chuỗi số, và giá trị luận lý TRUE trở thành “1”:

$str = (string) $str; // sắp $str như là 01 chuỗi




ĐỪNG BAO GIỜ để sót lại mã biên dịch khi xong việc, ngay cả trường hợp đã có dòng ghi chú. Những hàm như là var_dump(), print_r(), die()/exit() KHÔNG NÊN có trong đoạn mã của bạn nếu nó không phục vụ cho mục đích khác hơn là để biên dịch.


KHÔNG CÓ dòng trắng đặt trước thẻ PHP mở hoặc sau thẻ PHP đóng. Việc xuất dữ liệu được lưu vào bộ nhớ đệm, vì vậy khoảng trống trong các tập tin của bạn có thể làm việc xuất dữ liệu bắt đầu trước khi CodeIgniter xuất dữ liệu của nó, dẫn đến lỗi và làm CodeIgniter không thể gửi các headers đúng đắn.


CodeIgniter khuyến cáo nên dùng phiên bản PHP 5.6 trở lên, nhưng nó hợp nhất với phiên bản PHP 5.3.7. Các đoạn mã của bạn cũng nên tương thích với yêu cầu này, cung cấp 01 hỗ trợ fallback thích hợp, hoặc là 01 tính năng tùy chọn biến mất 01 cách lặng lẽ  mà không ảnh hưởng gì đến 01 ứng dụng người dùng.

01 điều nữa là KHÔNG DÙNG các hàm PHP đòi hỏi các thư viện không có trong mặc định đã được cài sẵn nếu không thì trong các đoạn mã của bạn phải chứa các phương thức thay thế các hàm không có sẵn này.


Dùng mỗi tập tin chứa 01 lớp riêng ra, nếu không các lớp phải có sự liên quan mật thiết nhau. 01 ví dụ trong tập tin CodeIgniter chứa nhiều lớp là tập tin thư viện Xmlrpc (system/libraries/Xmlrpc.php)


Sử dụng dấu tabs thay cho khoảng trắng thụt đầu dòng trong mã của bạn. Điều này dường như rất nhỏ nhặt, nhưng dùng các dấu tabs sẽ cho phép các lập trình viên nhìn vào mã của bạn có 01 sự sắp xếp thứ bậc sẽ nịnh mắt hơn và dễ dàng trong tùy biến các ứng dụng khi cần . Và có 01 giá trị bên lề nữa là kết quả lưu trữ trên tập tin sẽ nhẹ hơn, vì rằng nói nào ngay lưu 01 ký tự tab thay vì 04 ký tự khoảng trắng.


Các tập tin phải được lưu với các ngắt dòng trong Unix. Đây chính là 01 vần đề phát sinh đối với lập trình viên trên hệ Windows, nhưng ở đây ta có thể chỉnh trong trình soạn thảo dùng ngắt dòng Unix.



Sử dụng thụt đầu dòng theo kiểu Allman . Ngoại trừ các mô tả Lớp, các dấu ngoặc luôn nằm 01 mình 01 dòng, và thụt dòng tương ứng với cấp của phát biểu điều khiển chứa chúng.

SAI:

function foo($bar) {

        // ...

}



foreach ($arr as $key => $val) {

        // ...

}



if ($foo == $bar) {

        // ...

} else {

        // ...

}



for ($i = 0; $i < 10; $i++)

        {

        for ($j = 0; $j < 10; $j++)

                {

                // ...

                }

        }



try {

        // ...

}

catch() {

        // ...

}



ĐÚNG:

function foo($bar)

{

        // ...

}



foreach ($arr as $key => $val)

{

        // ...

}



if ($foo == $bar)

{

        // ...

}

else

{

        // ...

}



for ($i = 0; $i < 10; $i++)

{

        for ($j = 0; $j < 10; $j++)

        {

                // ...

        }

}



try

{

        // ...

}

catch()

{

        // ...

}


Nhìn chung, các cặp dấu ngoặc không nên dùng dư thừa khoảng trắng nào. Ngoại trừ trường hợp 01 khoảng trắng luôn có ngay sau cấu trúc điều khiển PHP là các tham số cùng cặp ngoặc (đặc tả, do-while, elseif, for, foreach, if, switch, while), giúp phân biệt chúng với hàm và tăng cường tính dễ đọc.

SAI:

$arr[ $foo ] = 'foo';

ĐÚNG:

$arr[$foo] = 'foo'; // KHÔNG để khoảng trắng quanh khóa mảng

SAI:

function foo ( $bar )

{



}

ĐÚNG:

function foo($bar) // KHÔNG để khoảng trắng quanh dấu ngoặc đơn tham số hàm

{



}

SAI:

foreach( $query->result() as $row )

ĐÚNG:

foreach ($query->result() as $row) // 01 ký tự khoảng trắng sau cấu trúc điều khiển PHP, nhưng trong cặp ngoặc thì không có


Các thư viện CodeIgniter nên xuất chuỗi trả về thông qua việc dùng các tập tin ngôn ngữ bất cứ lúc nào có thể (tiện cho sau này làm ứng dụng đa ngôn ngữ).

SAI:

return "Invalid Selection";

ĐÚNG:

return $this->lang->line('invalid_selection');




Các phương thức và các biến chỉ được truy cập nội bộ, ví dụ như là các hàm chức năng và  helper mà các phương thức public dùng cho mã trừu tượng, ta nên đặt dấu gạch dưới _ đằng trước.

public function convert_text()

private function _convert_text()




Code must run error free và không dựa trên các cảnh báo và các ghi chú được ẩn đi để khớp với yêu cầu này. Ví dụ, không bao giờ truy cập 01 biến bạn không tự khai báo (ví dụ như các khóa mảng $_POST ) mà không kiểm tra trước bằng hàm isset().

Đảm bảo rằng môi trường phát triển của bạn có kích hoạt báo cáo lỗi cho TẤT CẢ người dùng, và display_errors được kích hoạt trong môi trường PHP. Bạn có thể kiểm tra thiết lập này với dòng lệnh sau:

if (ini_get('display_errors') == 1)

{

        exit "Enabled";

}

Ở 01 vài máy chủ nơi display_errors bị vô hiệu hóa, và bạn không thể thau đổi điều này trong tập tin php.ini, bạn có thể kích hoạt nó bằng câu lệnh:

ini_set('display_errors', 1);

Ghi chú:

Thiết lập display_errors với hàm ini_set() trong khi chạy chương trình thì không giống như kích hoạt nó trong môi trường PHP. Cụ thể là, nó sẽ không có tác dụng nếu đoạn mã có lỗi fatal errors (gây đóng chương trình đang chạy).


Hãy luôn dùng các thẻ mở PHP đầy đủ, trong trường hợp máy chủ không kích hoạt short_open_tag

SAI:

<? echo $foo; ?>



<?=$foo?>

ĐÚNG:

<?php echo $foo; ?>

Ghi chú:

PHP 5.4 sẽ luôn có thẻ <?=


Không bao giờ nối nhiều phát biểu trên 01 dòng.

SAI:

$foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);

ĐÚNG:

$foo = 'this';

$bar = 'that';

$bat = str_replace($foo, $bar, $bag);




Hãy sử dụng dấu ngoặc đơn bao quanh chuỗi trừ trường hợp bạn cần đưa các biến vào chuỗi, và trong trường hợp đó ở nơi đặt biến , ta dùng dấu ngoặc đơn để ngăn ngừa hiển thị không như mong muốn. Bạn cũng có thể dùng dấu ngoặc kép bao quanh chuỗi nếu chuỗi chứa các dấu ngoặc đơn, thay vì phải dùng các ký tự thoát (thư mục) \

SAI:

"My String" // không chứa biến bên trong, vì vậy không dùng dấu ngoặc kép

"My string $foo" // cần dấu ngoặc đơn bao quanh biến

'SELECT foo FROM bar WHERE baz = \'bag\''    // không đẹp

ĐÚNG:

'My String'

"My string {$foo}"

"SELECT foo FROM bar WHERE baz = 'bag'"




Các từ khóa của ngôn ngữ SQL luôn VIẾT HOA: SELECT, INSERT, UPDATE, WHERE, AS, JOIN, ON, IN, v.v.

Ngắt các câu truy vấn quá dài thành nhiều dòng cho dễ đọc, nên ngắt dòng ở mỗi từ khóa cho rõ ràng.

SAI:

// các từ khóa viết thường và cây truy vấn thì qua dài đối với 01 dòng đơn(... cho biết sự tiếp nối dòng)

$query = $this->db->query("select foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses

...where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100");

ĐÚNG:

$query = $this->db->query("SELECT foo, bar, baz, foofoo, foobar AS raboof, foobaz

                                FROM exp_pre_email_addresses

                                WHERE foo != 'oof'

                                AND baz != 'zab'

                                ORDER BY foobaz

                                LIMIT 5, 100");


Bất kỳ lúc nào thích hợp, ta nên cung cấp tham số hàm mặc định, giúp ngăn ngừa lỗi PHP xảy ra khi gọi nhầm và cung cấp các giá trị dự phòng giúp tiết kiệm được vài dòng mã. Ví dụ:

function foo($bar = '', $baz = FALSE)

Nếu vẫn chưa rõ các bạn xem thêm video clip sau:




By #tiensim

Nguồn: User Guide – General Topics

Không có nhận xét nào:

Đăng nhận xét

Facebook Youtube RSS