Maintainable PHP Source Code

         Bo-Yi Wu 吳柏毅
           2012.07.21
       http://blog.wu-boy.com/
維護 PHP 專案程式碼
  為什麼大家需要關心呢 ?
因為
我們每天花了很多時間在維護程式碼
維護 PHP 專案程式碼
    誰最關心呢 ?
公司員工 : 趕快把程式碼寫完來去看電影

公司老闆 : 請給我一個可以擴充性的架構
員工 A: 奇怪這是誰寫的 Code 這麼亂

員工 B: 員工 A 寫的架構好像怪怪的 ?
為什麼大家會有這些想法呢?
那是因為沒有共同制定的

 Coding Style
沒有好的 Coding Style
對於一個專案主管是非常痛苦
那什麼是易於維護的程式碼
   Maintainable Code
四項必定要求
   非常直覺
   容易了解
   可擴充性
   容易 Debug
進入今日主題

Code Style Guide
   程式設計師互相溝通的語言
各式各樣的編輯器

Tabs vs 4 Spaces
使用 Space 易於閱讀 Diff 程式碼
所以請將編輯器設定為
 (Replaces tabs by spaces)
4 Spaces 取代 Tabs
程式碼結尾請勿有
 多餘的空白
正規取代驗證多餘空白

^(.*[^s])?s+$
^(.*[^s])?s+$
開頭          結尾
^(.*[^s])?s+$
代表 $1   結尾符號
^(.*[^s])?s+$
   結尾無空白
^(.*[^s])?s+$
        $1 可有可無
^(.*[^s])?s+$
         結尾為空白
Geany Editor
檔案命名
請一律以小寫命名
檔案內容宣告
只使用 <?php 或 <?= 標籤
PHP5.4 以後
取消 short_open_tag
 直接使用 <?= 標籤
檔案結尾請忽略 ?> 標籤
檔案格式
use only UTF-8   without BOM for PHP code
  避免資料庫連線字元問題
如何寫程式註解
 註解上面必須空一行
如何寫函式註解
 註解上面必須空一行
變數命名
請使用
小寫英文字母或底線
常數命名
請使用
大寫英文字母或底線
 ( 定義在同一檔案內 )
PHP Keywords
true, false, null
array, integer, string
請一律用小寫
條件判斷式
(Control Structures)
if, for, foreach, while, switch
if, for, foreach, while, switch
if ($arg === true) {
    //do something here
}
elseif ($arg === null) {
    //do something else here
}
else {
    //catch all do something here
}
單行條件式過長
if (($a == $b)
    and ($b == $c)
    or ($a == $e)
){
    $a = $d;
}
if($arg === true) {
   //do something here
}
elseif($arg === null) {
   //do something else here
}
else {
   //catch all do something here
}

          條件式 if 括號旁邊請留一個空白
If, for, foreach, while, switch
<?php
for ($i = 0; $i < $max; $i++) {
   //loop here
}
<?php
for ($i=0; $i<$max; $i++) {
   //loop here
}


     邏輯符號 =,< 左右兩邊請留一個空白
If, for, foreach, while, switch
<?php
foreach ($iterable as $key => $value) {
   // foreach body
}
If, for, foreach, while, switch
<?php
while ($expr) {
  // structure body
}

<?php
do {
   // structure body;
} while ($expr);
If, for, foreach, while, switch
switch ($var) {
  case 0:
     echo 'First case, with a break';
     break;
  case 1:
     echo 'Second case, which falls through';
     // no break
  case 2:
  case 3:
     echo 'Third case, return instead of break';
     return;
  default:
     echo 'Default case';
     break;
}
判斷式內容請勿寫在同一行
替代 if 方案
取代
if (isset($var)) { $var = 'test'; }
isset($var) and $var = 'test';
if (isset($variable)) {
    $variable = 'test1';
}
else {
    $variable = 'test2';
}

               不建議此寫法
$var = isset($var) ? 'test1' : 'test2';
$var = isset($var) ?: 'default';
邏輯符號表式
請用 and or
取代 && ||
讓程式更容易閱讀
此用法僅限於
 === 或 !==
或 function 回傳值
運算元計算
請使用 && 或 ||
邏輯符號左右兩邊
 請留一個空白
if ($var == false and $other_var != 'some_value')
if ($var === false or my_function() !== false)
if ( ! $var)
PHP 物件表示
/**
* Documentation Block Here
*/
class Session
{
    // all contents of class
    // must be indented four spaces
    public function test() {}
}
/**
* Documentation Block Here
*/
class Session
{
    /**
    * Documentation Block Here
    */
    public function get_flash($name, $data)
    {
        $closure = function($a, $b) {
          // Your closure code here
        }
    }
}
物件內部變數或函式
     務必定義
private,protected,public
/**
* Documentation Block Here
*/
class Session
{
    var $test = null;
    /**
     * Documentation Block Here
     */
    function get_flash($name, $data)
    {
        // Your code here
    }
}                 請勿使用 var 定義變數
單引號或雙引號 ?
用單引號更勝於雙引號
  ( 只是為了統一 Code Style)
別再相信
單引號效能大於雙引號
有興趣請看效能評估
http://nikic.github.com/2012/01/09/Disproving-the-
       Single-Quotes-Performance-Myth.html
字串連接
Concatenation
$string = 'my string '.$var.' the rest of my string';




                變數旁邊請留空白
$string = 'my string ' . $var . ' the rest of my string';
字串如果過長呢 ?
  例如 SQL 語法
$sql = "SELECT `id`, `name` FROM `people` "
     . "WHERE `name` = 'Susan' "
     . "ORDER BY `name` ASC ";
今天就講到這裡

大家有什麼問題
參考資料
   PHP Framework Interop Group
          PSR­0
          PSR­1
          PSR­2
   Zend Framework Coding Standard for PHP 
謝謝

Maintainable PHP Source Code