WordPress 在很早期各種 CMS 百家爭鳴的時候就已經開始佔穩市佔率的腳步了,那時還是 PHP 4,主要流行的程式碼風格和現在有很大的差異。
但核心程式碼並不是說,能改程式碼風格就能隨意改。例如類別的名稱、函式的名稱,一修改名稱就造成整個依附在核心程式碼來設計的外掛 (plugin) 及佈景主題 (theme) 出現相容性問題。因此保持著向下相容的開發原則,程式碼風格延用至今。
WordPress 的程式碼風格的官方規範文件可以在下方連結找到:
本篇文章主要著重於介紹能幫助我們修正及熟悉 WordPress 程式碼風格的工具 - PHP CodeSniffer。以及 WordPress 編碼規範的重點整理。
PHP CodeSniffer 的 GitHub 文件提供了多種安裝 PHP CodeSniffer 的方法,其中使用 Composer 的方式是筆者唯一推薦的,不僅最方便,在 Visual Studio Code 的擴充套件市集可以下載 PHP CodeSniffer 同名套件,毋須再另外設定 PHPCS 的位置,隨裝隨用。
安裝指令:
composer global require "squizlabs/php_codesniffer=*"
示範:

此指令會將 phpcs.phar 安裝至 Composer 的 bin 目錄中。
指令:
phpcs -i
示範:

結果顯示已安裝的編碼規範:MySource、PEAR、PSR1、PSR12、PSR2、Squiz、Zend。
phpcs 內建了常見的編碼規範,不過不包含 WordPress,因此必須另外安裝 WordPress 編碼規範的規則集,phpcs 才能依此 WordPress 的規則幫我們修正程式碼風格。
從 WordPress 編碼規範的 GitHub 儲存庫直接下載:
或使用 git 指令:
git clone -b main https://github.com/WordPress/WordPress-Coding-Standards.git wpcs
將 WordPress 編碼規範的規則集下載後,放到 wpcs 這個目錄中。
phpcs --config-set installed_paths /absolute/path
示範:

注意:要在全域都能使用的話,目錄必須是絕對路徑。
最使使用指令 phpcs -i 顯示 WordPress, WordPress-Core, WordPress-Docs and WordPress-Extra,表示已安裝成功。
以下是筆者覺得常用的指令:
phpcs /path/to/code/my_dir
掃描整個目錄,可空格分隔多個目錄一次掃描多個目錄。
--standardphpcs --standard=WordPress wp-load.php
phpcs /path/to/code/myfile.php
掃描單一檔案,可空格分隔多個目錄一次掃描多個檔案。
-iphpcs -i
-h, --helpphpcs -h
--config-setphpcs --config-set installed_paths wpcs
installed_paths 是選項。wpcs 是指定的目錄路徑。--report-diffphpcs --report-diff=/path/report.txt /path/src
/path/report.txt 是輸出的報表位置。/path/src 是要掃描的目錄。更多用法可以查看作者的文件頁。
phpcbf 為 PHP Code Beautifier and Fixer 的縮寫。使用時機在於,想要大量批次地一次轉換專案的 PHP 檔案到指定的程式碼風格。
使用 PHPCBF 之前,先使用 PHPCS 掃描檔案試試:
phpcs --standard=WordPress /terrylin/data/simple-cache/src/simpleCache/driver/file.php

因為是使用 PSR 的程式碼風格在寫程式,所以指定 WordPress 編碼規範來檢查,出現一堆錯誤,不意外。
如果之前寫 WordPress 外掛作品,都沒按照 WordPress 的編碼規範,那麼每個檔案都要改,實在很耗費時間。
因此,PHPCS 作者很貼心的準備了 phpbcf.phar 這支程式,在安裝 PHPCS 時已經同時裝好了。
phpcbf --standard=WordPress /terrylin/data/simple-cache/src/simpleCache/driver/file.php --suffix=.fixed
--standard 指定編碼規範。--suffix 不想直接覆寫檔案的話,可以指定檔案後輟,會產生一個新的修正檔案。示範:

phpcbf 和 phpcs 一樣有很多的指列選項,官方文件頁有詳細的範例。
下圖是經過 phpcs 轉檔後與轉檔前的比較,可以看的出,和筆者在 Day 11 所介紹的 PSR 程式碼風格指南,兩種對比,程式碼風格差異非常大。

筆者列出其重點,更細節的部分,請詳閱官方文件唷。
使用單引號 ' 包圍字串,除非包含的內容含有變數,才使用雙引號 "。
範例:
echo '<a href="/static/link" title="Yeah yeah!">Link name</a>';
echo "<a href='$link' title='$linktitle'>$linkname</a>";
範例:
    $foo   = 'somevalue';
    $foo2  = 'somevalue2';
    $foo34 = 'somevalue3';
    $foo5  = 'somevalue4';
範例:
$args = array(
    'post_type'   => 'page',
    'post_author' => 123,
    'post_status' => 'publish',
);
( 及右括號 ) 與判斷句之間要有一個空格。elseif 而非 else if。{ 與 } 的使用如下,與旁邊字元之間要有一個空格。} 自己獨立一行。範例:
function my_function( $param1 = 'foo', $param2 = 'bar' ) {
    if ( $param1 === 'foo2' ) {
        action1();
        action2();
    } elseif ( $param1 === 'foo3' && $param2 === 'bar' ) {
        action3();
        action4();
    } else {
        defaultaction();
    }
}
, 之後永遠保持一個空格。array() 而非 []
範例:
$x = array( 1, 2, 3 );
[ 及 ]  中間為變數,則和變數之中加一空格。[ 及 ]  中間不是變數,不加空格。$x = $foo['bar']; // [O]
$x = $foo[ 'bar' ]; // [X]
 
$x = $foo[0]; // [O]
$x = $foo[ 0 ]; // [X]
 
$x = $foo[ $bar ]; // [O]
$x = $foo[$bar]; // [X]
錯誤的範例:
<? ... ?>
<?= $var ?>
範例:
if ( true === $the_force ) {
    $victorious = you_will( $be );
}
WordPress 的程式碼風格著重和空格及縮排,瞭解之後,配合 Visual Studio Code 的擴充套件,很快就能熟悉囉。
筆者在這列介紹的是 VSCode 的擴充套件。不過不論是使用 PHPStorm、Sublime Text 還是 VScode,各家編輯器都有可以設定 phpcs 的功能,仔細找找就能找到。使用編輯器寫程式的時候可以即時出現提示,比使用命令列更有效率。
搜尋 phpcs 就可以找到很多相關的。

(圖:VSCode 編輯器 - 搜尋擴充套件)
但是不要下載它!因為問題蠻多的。目前筆者用覺得最順的是這一個。
搜尋 php sniffer。

(圖:VSCode 編輯器 - 搜尋擴充套件)
安裝之後,接著下一步。
從 WordPress 的 GitHub 儲存庫下載這個 phpcs.xml.dist,放到專案的工作目錄下。這樣就啟用了。
這個擴充套件會依照順序,自動找尋工作目錄下的這四個檔案:
.phpcs.xml
phpcs.xml
.phpcs.xml.dist
phpcs.xml.dist
效果:

(圖:VSCode 編輯器 - 主區塊)
在有程式碼不符合 WordPress 編碼規範的地方會有紅色波浪底線提示。
滑鼠游標移過去則會出現訊息。

(圖:VSCode 編輯器 - console)
在編輯器的 console 也同步出現訊息。
經過筆者今天的介紹,相信要直接上手 WordPress 的程式碼風格應該能順利許多。鐵人賽終於剩下最後四天了。明天筆者要介紹的是:外掛的設定頁面的規劃及設計。
我們明天見囉。
感謝 Terry 大大超仔細分享 PHPCS for WordPress 以及非常實用的 VSCode 套件。
我發現一個問題:從 Github 載回的 wpcs 資料夾要留著不能刪除,不然 PHPCS 會找不到 WordPress Standard,我的環境是 MacOS + zsh,不知道是不是平台之間的差異?
另外在 VSCode 裡面使用 PHP Sniffer 的時候,也需要在專案的資料夾裡面再做一次 phpcs --config-set installed_paths,感覺 wpcs 沒有安裝到全域上。
demo 的動圖是相對路徑,不過要在全域使用,必須指向絕對路徑唷。phpcs --config-set installed_paths /absolute/path
謝謝回覆,我用 phpcs --config-show 查看 installed_paths 是絕對路徑沒錯,也因為是絕對路徑,所以 wpcs 資料應該是不能刪除的...吧?還是我整個搞錯絕對路徑的意思?XDD
更新一下,這個 VSCode extension 也不錯用
https://marketplace.visualstudio.com/items?itemName=shevaua.phpcs