iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
DevOps

嘿,稍等一下!別急著開發功能,先來打造 Walking Skeleton 吧!系列 第 24

【Walking Skeleton】Day24 - PHP_CodeSniffer:使用 Linter 來提升 PHP 程式碼品質吧!

  • 分享至 

  • xImage
  •  

PHP_CodeSniffer 簡稱 PHPCS,是 PHP 的 Linter 工具,它可以設定程式排版規則,讓大家有一致的 Coding Style,減少讓 git commit 變得整片紅紅綠綠的次數


安裝 PHPCS

老樣子,先來用 composer 安裝這個開發工具

composer require --dev squizlabs/php_codesniffer

https://ithelp.ithome.com.tw/upload/images/20231009/20132916UquhUZRTkD.png

還有它的 VSCode 擴充功能,我比較喜歡這一個,它會顯示違反了哪條規則,其他的都不寫我要怎麼調整設定
https://marketplace.visualstudio.com/items?itemName=wongjn.php-sniffer

不過這個擴充功能有個小小的問題,只要它找不到 phpcs.xml 就會一直顯示錯誤,所以要調一下設定
https://ithelp.ithome.com.tw/upload/images/20231009/20132916S8aqGsyxtg.png

~/AppData/Roaming/Code/User/setting.json

// 全域關閉
"phpSniffer.run": "never",

.vscode/settings.json

// 專案工作區啟用
"phpSniffer.run": "onSave",
"phpSniffer.autoDetect": true,

再來是設定檔,使用最基本的 PSR12 規則,但是讓大括號在同一行

phpcs.xml

<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PSR12" xsi:noNamespaceSchemaLocation="../../../phpcs.xsd">
    <description>The PSR-12 coding standard.</description>

    <exclude-pattern>vendor</exclude-pattern>

    <arg name="colors" />
    <arg name="basepath" value="./" />
    <arg name="tab-width" value="4" />

    <rule ref="PSR12">
        <!-- 排除類別大括號必須在下一行 -->
        <exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine" />
        <!-- 排除函式大括號必須在下一行 -->
        <exclude name="Squiz.Functions.MultiLineFunctionDeclaration.BraceOnSameLine" />
        <!-- 排除類別屬性方法必須緊貼在下一行 -->
        <exclude name="PSR12.Classes.OpeningBraceSpace" />
    </rule>

    <!-- 類別大括號必須在同一行 -->
    <rule ref="Generic.Classes.OpeningBraceSameLine.BraceOnNewLine" />
    <!-- 函式大括號必須在同一行 -->
    <rule ref="Generic.Functions.OpeningFunctionBraceKernighanRitchie.BraceOnNewLine" />
</ruleset>

大括號掉到下一行,就冒一堆紅字給你看
https://ithelp.ithome.com.tw/upload/images/20231009/20132916X0geMOQ8K3.png

平常用的 Formatter 也要改一下設定,改成 K&R 讓大括號變成在同一行

"php.format.codeStyle": "K&R",
"intelephense.format.braces": "k&r",

使用 PHPCS

PHPCS 有兩個指令,一個是 phpcs 用來檢查程式是否有違反規則,另一個是 phpcbf 用來自動修正錯誤

./vendor/bin/phpcs ./

https://ithelp.ithome.com.tw/upload/images/20231009/201329168oXrN815TR.png

現在總共有三個地方要修正,先來跑跑看自動修正

./vendor/bin/phpcbf ./

https://ithelp.ithome.com.tw/upload/images/20231009/20132916BdflwVBrWo.png
https://ithelp.ithome.com.tw/upload/images/20231009/20132916Y4d8qmTZTi.png

它幫我解決了大括號跑去下一行的問題

剩下一個是因為 class 沒有設定 namespace
https://ithelp.ithome.com.tw/upload/images/20231009/20132916rVCm2ChNrl.png

加上 namespace 後紅字就消失了
https://ithelp.ithome.com.tw/upload/images/20231009/201329167Tuwp4Pze4.png

再跑一次也沒有再出現需要修正的地方了
https://ithelp.ithome.com.tw/upload/images/20231009/20132916JKQa9gtuQr.png


我想要設定更多的規則

PHP_CodeSniffer 有提供額外的自訂設定,可以依照自己的喜好增加更多的規則
https://github.com/squizlabs/PHP_CodeSniffer/wiki/Customisable-Sniff-Properties

以下是一些比較常見的規則

phpcs.xml

    <!-- 必須要有 declare(strict_types=1); -->
    <rule ref="Generic.PHP.RequireStrictTypes.MissingDeclaration" />
    <!-- 必須使用 ===、!== -->
    <rule ref="Squiz.Operators.ComparisonOperatorUsage.NotAllowed" />
    <!-- 多行陣列最後一項後面必須要有逗號,單行陣列最後一項後面禁止逗號 -->
    <rule ref="NormalizedArrays.Arrays.CommaAfterLast" />
    <!-- 行尾不可以有空格 -->
    <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndLine" />

    <!-- 禁用 array() -->
    <rule ref="Generic.Arrays.DisallowLongArraySyntax" />

    <!-- 禁用一些函式 -->
    <rule ref="Generic.PHP.ForbiddenFunctions">
        <properties>
            <property name="forbiddenFunctions" type="array">
                <element key="sizeof" value="count" />
                <element key="delete" value="unset" />
                <element key="print" value="echo" />
                <element key="is_null" value="null" />
                <element key="create_function" value="null" />
            </property>
        </properties>
    </rule>
    <!-- 檢查未使用的變數 -->
    <rule ref="Generic.CodeAnalysis.UnusedFunctionParameter">
        <properties>
            <property name="ignoreTypeHints" type="array">
                <element value="InputInterface"/>
            </property>
        </properties>
    </rule>
    <!-- 「.」前後必須是一格空格 -->
    <rule ref="Squiz.Strings.ConcatenationSpacing">
        <properties>
            <property name="ignoreNewlines" value="true" />
            <property name="spacing" value="1" />
        </properties>
    </rule>
    <!-- 檢查「!」後的間距 -->
    <rule ref="Generic.Formatting.SpaceAfterNot">
        <properties>
            <property name="spacing" value="0" />
        </properties>
    </rule>
    <!-- 檢查認知複雜度 -->
    <rule ref="Generic.Metrics.CyclomaticComplexity">
        <properties>
            <property name="complexity" value="7" />
            <property name="absoluteComplexity" value="7" />
        </properties>
    </rule>
    <!-- 檢查巢狀層次 -->
    <rule ref="Generic.Metrics.NestingLevel">
        <properties>
            <property name="nestingLevel" value="3" />
            <property name="absoluteNestingLevel" value="3" />
        </properties>
    </rule>

我想要設定更多更多的規則

當然可以,當然有更多的設定
https://github.com/PHPCSStandards/PHPCSExtra#sniffs

安裝 PHPCSExtra

composer require --dev phpcsstandards/phpcsextra

問你說要不要信任這個程式,信任就輸入 y

Do you trust "dealerdirect/phpcodesniffer-composer-installer" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?]

然後就可以在設定檔中加入更多規則

phpcs.xml

    <!-- 使用 __DIR__,而不是 dirname(__FILE__) -->
    <rule ref="Modernize" />
    <!-- 檢查 Array 排版 -->
    <rule ref="NormalizedArrays" />

我想要設定更多更多更多的規則

沒問題,這裡還有一個
https://github.com/slevomat/coding-standard/tree/master/doc

安裝 Slevomat Coding Standard

composer require --dev slevomat/coding-standard

增加更多的規則

phpcs.xml

    <!-- 檢查函式參數類型定義 -->
    <rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint" />
    <!-- 檢查函式返回類型定義 -->
    <rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint" />
    <!-- 不允許在字串內進行變數解析 -->
    <rule ref="SlevomatCodingStandard.Strings.DisallowVariableParsing">
        <properties>
            <property name="disallowDollarCurlySyntax" value="true" />
            <property name="disallowCurlyDollarSyntax" value="false" />
            <property name="disallowSimpleSyntax" value="true" />
        </properties>
    </rule>

以上三個設定文件夠玩好幾個月了,如果還不夠的話可以在網路上找找看其他人寫的,或是乾脆自己寫(O


上一篇
【Walking Skeleton】Day23 - 用 PHPUnit 來自動測試程式是否有按照預期運作
下一篇
【Walking Skeleton】Day25 - 在 Github Actions 中加入自動測試和 Linter
系列文
嘿,稍等一下!別急著開發功能,先來打造 Walking Skeleton 吧!34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言