撰寫習慣、細節觀念
每種程式語言都有屬於它自己的特性,良好的撰寫習慣可能程式具有可閱讀性,幫助理解方便維護。能夠充分熟悉它的人在撰寫時越容易避免預期外的錯誤,以減少不必要的除錯動作,增加工作效率,因此此篇文章主要用來整理在學習 PHP 過程中應培養的撰寫習慣及應注意的細節觀念…等等的心得。
基本的撰寫習慣
- 檔案開頭以
<?php
做為 PHP 的起始標籤,盡量避免使用縮寫<?
。 - 檔案若為單純的 PHP 程式碼,則應省略 PHP 的結尾標籤
?>
,僅於結尾處加上註解表示檔案結尾。?>
結尾標籤在 PHP 編譯器中是非必要的。- 可避免他人在結尾標籤之後加上不可見的字元(空白、換行、TAB等等),可能會破壞頁面輸出的字元。
- 本網誌的範例程式碼會使用
?>
做為結尾符號,以保持程式碼一致性。
- 習慣為程式碼加上必要的註解。
- 養成加上註解的習慣,不但能幫助自己記憶,也能讓別人更容易看懂程式碼的用途。
- 手動對變數做初始化的動作。
- 在 PHP 中使用變數時,若該變數尚未被定義,PHP 編譯器會丟出 E_NOTICE 訊息,並自動替變數做初始化的動作。
- 雖然 E_NOTICE 訊息並不會影響程式執行,卻容易使程式碼變得不嚴謹且產生模糊地帶。
- 建議習慣手動對變數做初始化的動作,以增加程式嚴謹性。
- 純字串使用單引號 (Single Quote) 為主。
- 若字串僅為純文字,不需要經過轉換特殊字元的動作,建議使用單引號即可,避免 PHP 編譯器進行多餘的動作可增加效能。
- 使用單引號僅會對字串進行少數幾個特殊字元轉換的動作,如
\'
\\
。 - 雙引號包覆的字串內容則會經過完整的轉換,例如變數內容置換、特殊字元轉換等操作,如\n(換行)、\(製表符)...。
- 記住一個html的觀念,就是換行或是空白,是要透過<br /> <p> 等等去輸出的你在原始碼內換行是沒有作用的,瀏覽器不會自動幫你顯示出來(原始碼的換行只是好看好整理用的)
- 提供你兩個作法
- <pre>的作用是原始碼排版即顯示結果
- nl2br($output); 作用是幫你把換行字元轉成<br>
- 使用陣列時,其陣列索引應盡量以單引號或雙引號括起來。
- 若以嚴謹標準來看
$array[ID]
的寫法是錯誤的,其陣列索引應該要被引號括起來為$array['ID']
較為正確。 - PHP 編譯器會將沒有括起來的字串索引當作「祼字符」,先將它解釋成
Constant
後找不到其定義時,才再將它重新解釋成字串,因此$array[ID]
是在這項特性之下被正常執行的。- 這項特性所提供的彈性是用執行效能換來的 :
$array['ID']
的執行速度是$array[ID]
的七倍。 - 即使陣列索引本身是數值,其
$array[0]
與 `$array['0'] 都是指向同一個陣列元素。
- 這項特性所提供的彈性是用執行效能換來的 :
- 因此建議在非必要的情況下,使用陣列時務必將索引括起來。
- 若以嚴謹標準來看
- 使用外來變數時,先利用
isset()
或array_key_exists()
等相關機制來檢查變數是否存在。- 直接使用未被定義的變數時,PHP 會丟出 E_NOTICE 訊息。
- E_NOTICE 訊息不影響程式執行,且可透過設定 ERROR_REPORTING | DISPLAY_ERROR 的機制來忽略這類訊息。
- 但為避免非預期性的錯誤,建議在使用 $GET, $POST, $REQUEST 等外來變數,或無法確保變數是否已存在的情況時,記得先檢查該變數是否存在。
- 直接使用未被定義的變數時,PHP 會丟出 E_NOTICE 訊息。
- 在使用
==
,!=
,===
,!==
比較運算子時,必須多加注意以避免預期外的錯誤。- 例如比較
Boolean
布林值時應盡量使用===
,!==
比較運算子以增加程式嚴謹度。 - 基於 PHP 自動轉換變數型態的特性,因此需注意比較運算子的差異。
==
,!=
比較的只有變數內容,當型態不同時會自動轉換成相同型態。===
,!==
除變數內容以外,還會比較變數的型態。- 更多詳細內容請參考官方手冊: PHP type comparison tables
- 例如比較
增加程式可讀性的撰寫習慣
- 找一個多數人認同的程式碼撰寫規範來遵守。
- 遵守一個多數人認同的程式碼規範,不僅可提高程式碼的可讀性,亦能讓團隊成員共同撰寫出具有相同規則的程式碼。
- PSR Coding Style for PHP (待補充)
優化效能的撰寫習慣
- 使用迴圈時,非必要應避免在迴圈條件式中直接使用函數。
- 若函式被寫在迴圈條件式中,在每次迴圈檢查條件式時都會執行該函式一次。
- 若函式回傳值在迴圈的過程中不會改變,則應避免將函式寫在迴圈條件式中。 (反覆執行函式卻取得同樣的結果,只是浪費系統資源及降低程式效能。)
- 盡量避免使用正規表達式 (Regular Expression) 。
- 在進行字串操作時,非必要應盡量避免使用正規表達式。
- 例如
str_replace()
的執行效率會比preg_replace()
快,
- 例如
- 在必要時仍以使用正規表達式達到簡化工作,容易維護為主。
- 例如檢查 Email 格式若以其他方式來完成,除了得費一番功夫以外,也不易維護。
- 在進行字串操作時,非必要應盡量避免使用正規表達式。
- 使用完變數之後,必要時手動釋放變數資源。
- 當變數被用以儲存龐大資料時,建應於使用完畢後立即使用
unset
以釋放該變數所佔有的資源。
- 當變數被用以儲存龐大資料時,建應於使用完畢後立即使用
其他程式相關的細節
- 陣列宣告時,最後一個元素之後可以有多餘的逗點。
- 雖然有彈性但不建議用,因為在程式撰寫時還是保有一定的嚴謹度,以減少不可預期的錯誤。
- 陣列
$array[0]
與$array['0']
是指向同一個陣列元素。- 由於 PHP 具有自動轉換變數型態的特性,透過變數操作陣列時就產生了一個疑問:
- 若
$index = '5'
時,$array[$index]
究竟是 $array['5'] 還是 $array[5]?
- 若
- 因此就撰寫了簡單的測試碼,得出以下結果:
- 由於 PHP 具有自動轉換變數型態的特性,透過變數操作陣列時就產生了一個疑問:
- 使用函式傳遞參數時,若傳遞的參數是物件時為 Call-Time Pass By Reference 。
- 陣列及一般變數為 Pass By Value 的方式,可在函式定義時加上
&
符號強制改以 Pass By Reference 傳入。- PHP 5.3 時對 Call-Time Pass By Reference 做了些改變,當有 Pass By Reference 的需求時,必須在定義函式時明確指定該引數的傳入方式,且不可在呼叫函式時使用
&
符號。
- PHP 5.3 時對 Call-Time Pass By Reference 做了些改變,當有 Pass By Reference 的需求時,必須在定義函式時明確指定該引數的傳入方式,且不可在呼叫函式時使用
- 請參考以下範例:
留言