iT邦幫忙

DAY 11
7

逐步提昇PHP技術能力系列 第 11

逐步提昇PHP技術能力 - Coding Standard 與 FIG-PSR

coding standard(代碼標準),是指程式碼的編寫風格要依照一定的格式。比較嚴謹的開發團隊通常會制定一套標準讓開發人員遵循,這樣團隊在內部交流會比較容易,使用工具來針對程式碼做檢測也比較方便。

最近,PHP社群發起了一個框架互通性的群組,希望制定一個可以給PHP大眾遵循的coding standard。在這之前,不同的團體大都有自己的coding standard,並沒有統一。不過即使目前PHP FIG已經制定了幾個標準,還是有一些團體有意見,所以...不過了解一下有這些東西還是多少有幫助。
參考:

  1. PHP Framework Interop Group(簡稱PHP FIG)
  2. https://github.com/php-fig/fig-standards

coding standard基本上就是一種寫作格式的風格,像是一些命名的格式、空格要怎樣空、一行最多多少字母、哪些地方要註解、註解的格式等等一些細節的東西。有很多是習慣,也有一些在提昇品質上會有一定幫助,或是在某些地方對專案管理有些幫助等等。(coding standard的檢查,通常是每週code review的基本工作,不過這不是重點,就不多說)

有時也可能基於程式檢查的因素制定一些coding standard規則,例如sql語句一定在同一行,要使用字串變數而不直接傳送給查詢的函數,變數名稱必須以sql開頭等等,這樣一次用grep從原始碼中抓出所有的sql語句加以查核。總之,只要有固定的格式,一方面程式碼會比較容易閱讀,工作也比較容易交接,一方面也比較容易用簡單的方式做檢查。不然就非得使用具備剖析能力的工具來做,會花比較多力氣。(不過如果工具熟悉的話,用工具還是比較快)

目前FIG已經通過的,有幾個標準:

  1. PSR-0 規範namespace與Class Autoloading
  2. PSR-1 規範基本的Coding Standard
  3. PSR-2 Coding Style的指導
  4. PSR-3 規範Logger的介面

* PSR-0

這個是規範Namespace,有幾個規定:

  1. 一個合格的namespace應該包含: \<廠商名稱>\<namespace>*\<class name>
  2. 最上層的namespace應該是廠商名稱
  3. 之後可以包含任意個namespace
  4. 每個namespace必須可以對應到目錄,所以把\代換成目錄符號時,就可以直接找到類別檔
  5. 類別名稱有底線時,也把底線改成目錄符號
  6. namespace中的底線,不需轉換

所以一個這樣的的namespace名稱與class名稱:

\GLF\Web_MVC\Views\Index_Index

假設類別目錄放在:

/var/www/html/vendor

那上述Index_Index這個類別,就會放在:

/var/www/html/vendor/GLF/Web_MVC/Views/Index/Index.php

規格中也引用了一個class loader的範例,網址在:http://gist.github.com/221634

* PSR-1

這個是基本的代碼標準。規格中會使用到MUST(必須), MUST NOT(不能), REQUIRED(需要), SHALL(應該), SHALL NOT(不應), SHOULD(可), SHOULD NOT(不可), RECOMMANDED(建議), MAY(或可), OPTIONAL(可選)等關鍵字,這些關鍵字定義在RFC 2119。(我翻的有點隨便,不過這幾個名詞代表嚴格程度,從MUST表示是一定要,到OPTIONAL表示是可有可無)

  1. 必須只使用<?php與<?=這兩種tag
  2. 檔案必須使用UTF8編碼,且不可有BOM
  3. 宣告類別或函數的程式不應與會有副作用(例如:輸出html)的程式放在同一個檔案
  4. namespace與class必須遵守PSR-0規範
  5. 類別名稱必須使用CamelCase且首字大寫
  6. 方法名稱必須使用camelCase且首字小寫
  7. 類別常數必須使用大寫字母加底線
  8. 類別屬性沒有特別規定,但是命名規則要一致

大概就是這樣

* PSR-2

這個規定了程式碼的風格,例如大括號怎麼擺,indent應該用什麼。

  1. 程式碼必須遵守PSR-1的規範
  2. 必須使用四個空格當做indent,而不是tab
  3. 不能規定每行的hard limit,但是必須規定soft limit不超過120的字元。每行可限制不超過80個字元
  4. namespace區塊之後必須空一行,use區塊之後也必須空一行
  5. 類別與方法定義用的大括號,必須在下一行
  6. 流程控制使用的大括號,必須在同一行
  7. 必須使用可視性(public, private, protected)來定義方法與屬性
  8. 方法與函數定義之後,不能有空格;流程控制之後必須有一個空格
  9. abstract與final必須放在可視性之前;static必須放在可視性之後
  10. 結束的大括號,都必須在下一行
  11. 小括號中,開始與結束不能有空格

所以一個合乎標準的類別定義,大概會長這樣:

<?php
namespace GLF/Web_MVC/Views;

use GLF/Web_MVC/Core;

class Index_Index extends View
{
    public $name;
    private $params;
    private static $count;
    public function __construct($name, $params)
    {
        $this->name = $name;
        $this->params = $params;
    }
    abstract private before()
    {
    }
    final public actionIndex($request)
    {
        if ($request->method==='post') {
            ...
        } else {
            ...
        }
    }
}

有點囉嗦就是了XD

* PSR3

這個是定義logger必須有的interface,讓他可以處理debug, info, notice, warning, error, critical, alert, emergency等八個等級的log資訊,不過這個跟coding standard就比較沒有直接關係了。

* 工具

一些舊的程式碼,想要讓他符合FIG-PSR的coding standard,一支一支改起來會很麻煩。所以有人寫了工具,幫助轉換程式碼的格式。需要的話可以試試看:
* https://github.com/fabpot/php-cs-fixer

不過我幾個月前試用的時候,還有些問題,所以在使用前最好用版本管理工具來控制好程式版本,並且在轉換後多方測試。

* 感想

開發團隊最好有一個coding standard,這樣在管理上會比較方便,也容易互相溝通。但是是否一定要遵循FIG-PSR,就...見仁見智了。說實話,批評的聲音還不少XD


上一篇
逐步提昇PHP技術能力 - Convention 與 include/require
下一篇
逐步提昇PHP技術能力 - 開發工具 : 用Composer管理相依性
系列文
逐步提昇PHP技術能力30

1 則留言

0
海綿寶寶
iT邦大神 1 級 ‧ 2013-10-11 17:22:45

以前在 Borland JBuilder 時曾用過 Checkstyle

是 for java 的
一鍵執行就把整個 project 不符 naming convention 的部份全部列出來
除了內建提供的 rule 之外
還可以自訂一些 rule
還蠻有趣的
下雨

fillano iT邦超人 1 級 ‧ 2013-10-11 17:45:16 檢舉

PHP也有類似工具,觀念大概也是從CheckStyle來的XD。這個大概是做每週code review的必備工具。常用的還有像是JDepend還有JavaNCSS。不過很久沒碰Java了...

之後應該會嘗試幾個PHP方面的程式碼品質工具。

我要留言

立即登入留言