跳到主要內容

《面試官別再問》PHP Coding Style指南PSR-2

這個指南是在PSR-1上的延伸和擴展,基本的編碼標準

本指南的目的是減少認知摩擦(風格不統一而造成不便),當瀏覽不同作者的代碼時。它做的這些關於如何格式化PHP代碼通過列舉一個共享的規則設置和期望

此處樣式規則衍生均來自各成員項目間的共性。當不同作者在多個項目間合作時,有一個設置的指南,它有助於被用來在所有這些項目中使用。因此,本指南的好處不在規則本身,而是這個規則的共享

PSR是PHP Standards Recommendations(PHP標準建議) 的簡寫,是由PHP-FIG組織(PHP Framework Interop Group-PHP框架交互操作組織)提出。 PHP-FIG的工作是尋找項目之間的共性,以及讓開發者能更好協同工作的方式。讀者可能在瀏覽一些PHP技術文章的時候,可能會看到PSR-1,PSR-2,PSR-4,PSR-7等,這些是PHP-FIG的標準建議,這些標準建議的命名構成是以' PSR-'+'序號',每個PHP_FIG標準建議都是為了解決大部分框架頻繁遇到的一個特定的問題,而與此同時框架不需要自己再去重複解決問題,而是遵循PSR標準建議,採納共享的解決方案.

在此介紹一項工具

PHP Code Sniffer 簡稱 phpcs,可以用來檢查你寫的PHP是否符合PSR-2我們可以用Composer 來安裝他

安裝
composer require squizlabs/php_codesniffer

測試
phpcs --version

檢查程式

phpcs --standard=PSR2 專案資料夾

OverView (概覽)

PHP文件(MUST)必須只使用<?php 和<?= 標籤.
PHP文件(MUST)必須只能使用無BOM頭的UTF-8編碼格式.
PHP文件(SHOULD)應該要么聲明classe,functions。 constants 等等,或者general ouput(通用輸出?),改變php.ini的配置等等,但是(SHOULD Not)不應該兩個都有.
命名空間和類(MUST)必須要遵循自動加載的PSR規範[PSR-0,PSR-4];
類名明明(MUST)必須以大駝峰式.
類中的常量的命名(MUST)必須為以下劃線分割的大寫字母.
方法名(MUST)必須為小駝峰式.
PHP代碼(MUST)必須只使用無BOM頭的UTF-8編碼格式.

Side Effects

一個PHP文件(SHOULD)必須要聲明一些class,function,constant等,並且沒有side effects (執行邏輯),或者(SHOULD)應該有side effects(執行邏輯),但是(SHOULD NOT)不應該兩個都同時存在.

   'side effects'代表的就是和聲明class,function,constant等不直接相關聯的執行邏輯,僅僅來自這個包含的文件。

  'Side effects' 包含以下操作,但不僅限於此:general output(通用輸出), 'require'和'include'的使用,連接外部服務,修改php.ini的設置,觸發錯誤或者拋出異常,修改全局或者靜態變量,讀取或者寫入文件操作等等.

  以下是一個我們要避免的例子,就是一個具有'declarations'和side effects的PHP文件。

<?php
// side effect: change ini settings
ini_set('error_reporting', E_ALL);

// side effect: loads a file
include "file.php";

// side effect: generates output
echo "<html>\n";

// declaration
function foo()
{
    // function body
}
以下是一個是正確的例子,只包含了'declaraion'沒有'side effects'.

<?php
// declaration
function foo()
{
    // function body
}

General - 約定

基本編碼標準
代碼必須遵循PSR-1中的所有規範

文件
所有PHP文件必須使用Unix LF(linefeed)作為行的結束符

所有PHP文件必須以一個空白行作為結束

只包含PHP代碼的文件結束?>標記必須被忽略


行的長度一定不能有硬性約束

行長度的軟限制必須在120字符內;自動樣式檢查必須警告但一定不能提示錯誤在軟限制上

行不應該超過80個字符;超過80個字符的長度的行應當拆分成多個不超過80個字符的子行

非空行後一定不能尾隨空格符

空行可以改善代碼閱讀,並且表明相關的代碼塊

每行一定不能存在多於一條語句

縮進
編碼必須使用4個空格,並且一定不能使用tab縮進

僅使用空格,並且不要混淆空格用tab,有助於避免比較差異,打補丁,重讀和註解問題。使用空格也使插入細粒度的子縮進為了跨線對齊變得容易

關鍵字:True,False,Null
PHP 關鍵字必須小寫

PHP常量true,false,null必須小寫

Namespace and Use Declarations - 命名空間和使用聲明
在目前,namespace聲明之後必須有一個空行

在目前,所有use聲明必須在namespace聲明之後

每個聲明必須有一個use關鍵字

use 塊之後必須有一個空行

<?php
namespace Vendor \ Package ;

use FooClass ;
use BarClass as Bar ;
use OtherVendor \ OtherPackage \ BazClass ;

// ... additional PHP code ...

Classes,Properties,and Methods - 類,屬性和方法
術語class指的是所有的class,interface,trait

繼承和實現
extends和implements關鍵字必須被聲明在作為類名的同一行

類的開花括號必須獨佔一行; 類的閉花括號必須在類體之後獨佔一行

implements的列表可以被分隔成多行,每個子行要縮進。當這樣做,列表中的第一個條目必須獨佔一行,並且必須是僅僅一個接口獨佔一行

<?php
namespace Vendor \ Package ;

use FooClass ;
use BarClass as Bar ;
use OtherVendor \ OtherPackage \ BazClass ;

class ClassName extends ParentClass implements
     \ ArrayAccess ,
    \ Countable ,
    \ Serializable
{ // constants, properties, methods }

控制結構(Control Structures)

控制結構的通用編碼風格規範:
控制結構的關鍵字之後應該有一個空格
左括號之後不應該有空格
右括號之前不應該有空格
右花括號和左花括號之間應該有一個空格
結構體應該縮印一次
右花括號應該在結構體的下一行
每一個結構體應該被花括號包圍;這樣子,結構看起來很標準,並且當加入新行的時候,gi 可以減少引入錯誤的可能性。

if, elseif, else
一個if結構看起來像下面那樣。注意圓括號的位置,空格和花括號;並且else和elseif與來自之前的結構體閉花括號在相同的行

<?php
if ($expr1) { // if body } elseif ($expr2) { // elseif body } else { // else body; }

關鍵字elseif應該被使用而不是else if以至於所有的控制關鍵字看起來像單個單詞

switch, case
一個switch結構看起來像下面那樣。注意圓括號的位置,空格和花括號。 case語句必須被縮進一次在switch中,並且break關鍵字(或者其它終止關鍵字)必須被縮進相同的級別在case體內。當故意落空一個非空case體時必須有一個註釋,例如:// no break
<?php
switch ($expr) { case 0 : echo 'First case, with a 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 ; }

留言

這個網誌中的熱門文章

《面試官別再問》PHP運用多執行緒(Multi-thread)實現非阻塞方法

詳細的請參考: 多程序還是多執行緒的選擇和區別 ,感覺這位牛人寫的特別清楚。下面我們再來看看php環境下使用多程序和多執行緒要注意的。 PHP是單進程同步模型,一個請求對應一個進程,I/O是同步阻塞的。通過nginx/apache/php-fpm等服務的擴展,才使得PHP提供高並發的服務,原理就是維護一個進程池,每個請求服務時單獨起一個新的進程,每個進程獨立存在。 PHP不支持多線程模式和回調處理,因此PHP內部腳本都是同步阻塞式的,如果你發起一個5s的請求,那麼程序就會I/O阻塞5s,直到請求返回結果,才會繼續執行代碼。因此做爬蟲之類的高並發請求需求很吃力。 常見互聯網分佈式架構如上,分為: ( 1 )客戶端層:典型調用方是瀏覽器 browser 或者手機應用 APP ( 2 )反向代理層:系統入口,反向代理 ( 3 )站點應用層:實現核心應用邏輯,返回 html 或者 json ( 4 )服務層:如果實現了服務化,就有這一層 ( 5 )數據 - 緩存層:緩存加速訪問存儲 ( 6 )數據 - 數據庫層:數據庫固化數據存儲 整個系統各層次的水平擴展,又分別是如何實施的呢? 反向代理層的水平擴展 反向代理層的水平擴展,是通過“ DNS 輪詢”實現的:dns-server 對於一個域名配置了多個解析ip ,每次DNS 解析請求來訪問dns-server ,會輪詢返回這些ip 。 當 nginx 成為瓶頸的時候,只要增加服務器數量,新增 nginx 服務的部署,增加一個外網 ip ,就能擴展反向代理層的性能,做到理論上的無限高並發。 php真的有多進程,多線程嗎? 剛接觸php的時候,就看到過php不支持多進程的,多線程,但是php可以利用其他的東西來實現偽多進程,多線程,例如:fsockopen實際是利用socket的多線程,popen,pcntl_fork ,proc_open利用httpd多進程功能的外衣。下面就一些實踐過程,以及這種多進程的效果,到底如何。 <?php   function  thread( $count =1) {     for ( $i =0; $i < $count ; ...

使用 Laravel、Redis 和 LINE Messaging API 建立客服系統

這個系統的目標是讓 LINE 的訊息可以透過網頁介面讓客服人員回覆。 好的,這是一個從 LINE 用戶發送訊息開始,到客服人員在網頁上回覆的完整步驟流程: 打造高併發 LINE 客服系統:設計與實踐 前言:以技術解決即時通訊挑戰 在高流量即時通訊場景下,系統的穩定性與響應速度是企業與用戶互動的核心挑戰。在這篇文章中,我將分享我設計並實作的一套 LINE 客服系統,展示如何透過 Laravel 生態系、Redis、WebSocket 與異步佇列,打造一個兼顧高併發處理、可擴展性與即時性的解決方案。這套系統不僅滿足了用戶對即時溝通的期待,也為客服團隊提供了流暢的操作體驗。 這篇文章將從架構設計、技術選型、核心實作到部署運維,全面剖析我的技術思維與實務能力,希望能為面試官或技術同儕提供有價值的參考。 系統架構:高效訊息流的設計理念 LINE 客服系統的核心目標,是確保從用戶發送訊息到客服回覆的整個流程,在高併發情境下仍能保持低延遲與高穩定性。以下是系統架構的 Mermaid 圖表,清晰呈現各組件間的訊息流動: graph TD subgraph LINE 用戶端 LINEUser[LINE 用戶] --> |發送訊息| LINEApp[LINE App] end subgraph LINE Platform LINEApp --> |Webhook HTTP POST| LINEPlatform(LINE Platform) LINEPlatform --> |HTTP POST /line/webhook| LaravelApp(Laravel 應用程式) end subgraph Laravel 應用程式 LaravelApp --> LineWebhookController(LineWebhookController) LineWebhookController --> |驗證簽名、解析事件| LINEPlatform LineWebhookController --> |快速回應 200 OK| LINEPlatform LineWebhookController -->...

Laravel9 + Redis 如何解決高併發交易及處理限量商品的庫存超賣問題?

在高併發交易場景下,使用 Laravel 9 搭配 Redis 在 AWS EC2 和 RDS 環境中,需要一套全面的策略來應對挑戰。這涉及到架構設計、程式碼優化、服務配置和監控。 高併發交易問題的核心挑戰 資料庫鎖 (Database Locks) :高併發寫入導致行鎖、表鎖競爭,降低吞吐量。 庫存超賣 (Overselling) :多個併發請求試圖購買同一商品時,因資料庫延遲或不一致,導致庫存扣減不準確。 交易延遲 (Transaction Latency) :大量請求導致應用伺服器、資料庫響應變慢,影響用戶體驗。 單點故障 (Single Point of Failure) :任何單一組件故障都可能導致整個交易流程中斷。 資源瓶頸 (Resource Bottlenecks) :CPU、記憶體、網絡 I/O、資料庫連接等資源耗盡。 Laravel + Redis + AWS EC2 + RDS 的解決方案 1. 架構優化 讀寫分離 (Read-Write Splitting) : RDS Master : 處理所有寫入( INSERT , UPDATE , DELETE )操作。 RDS Replicas : 處理所有讀取( SELECT )操作。 Laravel 配置 : 在 config/database.php 中配置讀寫分離。 PHP 'mysql' => [ 'driver' => 'mysql' , 'read' => [ 'host' => [env( 'DB_READ_HOST_1' ), env( 'DB_READ_HOST_2' )], ], 'write' => [ 'host' => [env( 'DB_WRITE_HOST' )], ], 'database' => env( 'DB_DATABASE' , 'forge' ), 'username...