1. 程式人生 > 實用技巧 >PHP 程式碼規範

PHP 程式碼規範

FIG 制定的 PHP 規範,簡稱 PSR,是 PHP 開發的事實標準。FIGFramework Interoperability Group (框架可互用小組) 的縮寫,由幾位開源框架的開發者成立於 2009 年。該組織的目的在於:以最低程度的限制,來統一各個專案的編碼規範,避免各家自行發展的風格阻礙了程式設計師開發的困擾。PSRProposing a Standards Recommendation (提出標準建議) 的縮寫。

PSR 原來有五個規範,分別是:

  • PSR-0 (Autoloading Standard) 自動載入標準。
  • PSR-1 (Basic Coding Standard)
    基礎編碼標準。
  • PSR-2 (Coding Style Guide) 編碼風格嚮導。
  • PSR-3 (Logger Interface) 日誌介面。
  • PSR-4 (Improved Autoloading) 自動載入的增強版,可以替換掉 PSR-0 了。

今天我們的程式碼規範是基於以上規範進行了整理。

1、PHP 原始檔只能使用 <?php<?= 這兩種標籤

<?php 標籤通常用於純 PHP 的腳本當中,而 <?= 通常用於模板當中。

2、PHP 原始檔必須是不帶 BOMUTF-8 編碼的檔案

BOM(Byte Order Mark),位元組順序標記,出現在文字檔案頭部,Unicode

編碼標準中用於標識檔案是採用哪種格式的編碼。

3、PHP 原始檔縮排採用 4 個空格

很多編輯器使用 Tab 作為縮排。會造成空格性問題。

4、純 PHP 程式碼的原始檔關閉標籤 ?> 必須省略

PHP 解析器在對檔案進行解釋的時候,會有效能提升。並且,這能一定程式避免在 ?> 之後有多餘的空格導致程式報錯。

5、請嚴格控制每行 120 個字元

過長的程式碼會導致多種解析度的顯示器造成相容問題。並且,過長的程式碼也會造成難以閱讀理解。如果實在太長,請把程式碼換行。

6、所有的類必須設定一個命令空間

命令空間給程式碼結構有較強的說明性,以及杜絕同名類的衝突問題。同時,也能用到 Composer 的自動載入優勢特性。

<?php
namespace core;

7、名稱空間(namespace)的聲明後面必須有一行空行

空行會讓程式碼看起來更加清晰容易閱讀。

<?php
namespace core;

use common;

8、所有的匯入(use)宣告必須放在名稱空間(namespace)宣告的下面

這樣會讓程式碼結構變得清晰容易閱讀。

<?php
namespace core;

use common;

9、一句宣告中,必須只有一個匯入(use)關鍵字

雖然 PHP 允許一行程式碼當中允許使用多個 use 關鍵字匯入一個類。但是,這會使程式碼閱讀造成障礙。

錯誤:

<?php
namespace core;

use common, library;

正確:

<?php
namespace core;

use common;
use library;

10、在匯入(use)宣告程式碼塊後面必須有一行空行

空行讓程式碼結構變得容易理解。

<?php
namespace core;

use common;
use library;

class Person {
    
}

11、PHP 關鍵字必須小寫

PHP 的關鍵字,必須小寫,boolean 值:true,false,null 也必須小寫。下面的關鍵字,也必須小寫:

'__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor'

12、繼承(extends) 和實現(implement) 必須和 class name 寫在一行,切花括號要換行寫。

<?php
namespace Lib\Databaes;
 
class Mysql extends ParentClass implements \PDO, \DB // 寫一行
{ // 換行寫{
     
}

13、成員屬性訪問修飾符必須顯示宣告不能省略

成員屬性有三種訪問修飾符:publicprotectedprivate。不能使用老式的 var 來聲音成員屬性。

<?php
namespace Lib\Databaes;
 
class Mysql extends ParentClass implements \PDO, \DB // 寫一行
{
    public    $foo  = null;
    private   $name = 'sam';
    protected $age  = '17';
}

14、成員方法訪問修飾符必須顯示宣告不能省略

成員方法有三種訪問修飾符:publicprotectedprivate

錯誤:

<?php
namespace Lib\Databases;

class MySQL
{
    function fetchOne()
    {
        // ......
    }
}

正確:

<?php
namespace Lib\Databases;

class MySQL
{
    public function fetchOne()
    {
        // ......
    }
}

15、方法的引數有多個的時候,每個引數的逗號後面必須加個空格

namespace Lib\Databaes;
 
class Mysql extends ParentClass implements \PDO, \DB // 寫一行
{
    public getInfo ($name, $age, $gender = 1)
    {
    }
}

16、當用到抽象(abstract)和終結(final)來做類宣告時,它們必須放在可見性宣告(public 還是protected還是private)的前面。而當用到靜態(static)來做類宣告時,則必須放在可見性宣告的後面。

<?php
namespace Vendor\Package;
 
abstract class ClassName
{
    protected static $foo; // static 放後面
 
    abstract protected function zim(); // abstract 放前面
 
    final public static function bar() // final 放前面,static 放最後。
    {
        // 方法主體部分
    }
}

17、控制結構花括號、換行、空格等規範

if、else、elseif、switch、for、foreach、case、while、go、try、catch 等關鍵詞後面必須加空格。可以說,沒有特殊說明的情況下,基本上所有的 PHP 關鍵詞後面都必須加空格。

流程控制語句起始的花括號是不需要另起一行。

if ($expr1) { // 左右空格
    // if body
} elseif ($expr2) { // elesif 連著寫
    // elseif body
} else {
    // else body;
}

switch ($expr) { // 左右空格
    case 0:
        echo 'First case, with a break'; // 對齊
        break; // 換行寫break,也對齊。
    case 1:
        echo 'Second case, which falls through';
        // no break
    case 2:
    case 3:
    case 4:
        echo 'Third case, return instead of break';
        return;
    default:
        echo 'Default case';
        break;
}

while ($expr) { // 左右空格
    // structure body
}
 
do {
    // structure body; // 左右空格
} while ($expr);

for ($i = 0; $i < 10; $i++) { // 注意幾個引數之間的空格
    // for body
}

foreach ($iterable as $key => $value) { // 還是空格問題
    // foreach body
}

try {
    // try body
} catch (FirstExceptionType $e) { // 同樣也是注意空格。
    // catch body
} catch (OtherExceptionType $e) {
    // catch body
}

18、類名必須與檔名一樣

這個很容易理解,沒啥好補充說明的。除非框架有特殊的載入規則。

19、類的命名必須遵循 StudlyCaps 大寫開頭的駝峰命名規範

StudlyCaps 即單詞首字母大寫風格。有些人也稱它為大駝峰。

20、方法名稱必須符合 camelCase 式的小寫開頭駝峰命名規範

camelCase 即第一個單詞首字母小寫後面的單詞首字母大寫的風格。

21、類中的常量所有字母都必須大寫,單詞間用下劃線分隔

CONST ORDER_STATUS = 1;

22、變數必須使用小駝峰命名風格

$cardNo   = ''; // 卡號。 
$idCardNo = ''; // 身份證號。

23、引數必須使用駝峰命名風格

引數也是變數的一種。故與變數的命名風格一致。

24、所有方法的起始花括號必須另起一行。

雖然以下兩種在實際開發中都是允許的。但是,為了保持程式碼一致。所以,必須強制使用。

錯誤:

<?php

class MySQL
{
    public function fetchOne() {
        
    }
}

正確:

<?php

class MySQL
{
    public function fetchOne() 
    {
        
    }
}

25、直接在方法中寫陣列引數時格式如下

$object->callFunc([
    'userId'   => 1,
    'username' => 'sam',
    'age'      => 20,
    'sex'      => 'male'
]);

26、方法引數註釋

/**
 * 管理後臺獲取優惠券傳送記錄。
 *
 * @author 7031 2018-02-23
 * @modify 7031 2019-02-25 修復了 SQL 效能問題。
 *
 * @param int    $couponId      優惠券ID。
 * @param string $username      使用者名稱。
 * @param string $mobilephone   使用者手機號。
 * @param int    $page          當前分頁頁碼。
 * @param int    $count         每頁顯示條數。
 * @param array  $data          請求引數。
 *
 * ------------------- eg:start ---------------------
 * $data = [
 *     'username' => '使用者賬號,沒有時傳空字串',
 *     'age'      => '使用者年齡,沒有時傳0',
 * ];
 * ------------------- eg:end -----------------------
 *
 * @return array
 */
public static function getBackendSendHistory($couponId = -1, $username, $mobilephone, $page, $count, $data) {

}

可以看出,有以下幾個註釋特點:

1)方法說明。

2)建立方法的同事編號以及時間。

3)修改方法的同事編號以及時間與修改的內容。

4)引數註釋:型別、名稱、引數說明。引數與其他註釋之間要有空行。

5)引數示例:如果引數當中有複雜的引數。可以在引數下方給出示例以增強說明。

6)返回值。需要給出返回的型別。

27、方法的程式碼行數不能超過一屏

每個人的顯示器解析度不一樣。既然不超過一屏也會出現別的同事一屏會超出的情況。所以,即使未超過一屏,也儘量保證程式碼行在 40 行以內。如果發現自己的程式碼超過了 40 行,那麼就需要考慮自己的程式碼是不是有拆分不合理的地方。特殊情況允許超過 40 行。但是,整個方法裡面的程式碼必須是簡單的判斷邏輯。不包含複雜的業務判斷邏輯。因為,不同的業務判斷最佳實踐是單獨封裝一個方法。




原文連結:https://www.jianshu.com/p/fa7830236de3