本文作者:陳進堅
博客地址:https://jian1098.github.io
CSDN博客:https://blog.csdn.net/c_jian
聯繫方式:[email protected]
版權聲明:文章僅在本人博客和CSDN博客中發佈,所有文章未經授權禁止轉載!
一、摘要
這是一份旨在增強團隊的開發協作,提高代碼質量和打造開發基石的編碼風格規範。當一個團隊開始指定並實行編碼規範的話,錯誤就會變得更加顯而易見。如果一段特定的代碼不符合規範的話,它有可能只是代碼風格錯誤,而也有可能會是 bug,更可能出現安全問題。早期指定規範就使得代碼審覈得以更好的開展,並且可以更精確的地定位到錯誤。只要開發者們能夠保證源代碼源文件都嚴格遵循規範,那接下來的維護工作就可以變得輕鬆簡單。
總之,我們的目標就是遵循同一套編碼規範,不管有多少人共同參與同一項目,都可以確保每一行代碼都像是同一個人編寫的,每一個功能都是安全的。
二、PHP相關命名規範
2.1 方法命名
方法,指的是在類中定義的函數,方法的命名使用駝峯法,並且首字母小寫或者使用下劃線“_”,例如 getUserName( ),_parseType( ),通常下劃線開頭的方法屬於私有方法;
2.2 函數命名
函數是指不在類中定義的函數,例如在公共文件中的函數。函數的命名使用小寫字母和下劃線的方式,例如 get_client_ip( );
2.3 變量(屬性)命名
變量,也叫屬性。屬性的命名使用駝峯法,並且首字母小寫或者使用下劃線“_”,例如 tableName、_instance,通常下劃線開頭的屬性屬於私有屬性;
2.4 常量命名
常量以大寫字母和下劃線命名,例如 HAS_ONE和 MANY_TO_MANY;
2.5 配置參數命名
配置參數以大寫字母和下劃線命名,例如 HTML_CACHE_ON = 1;
三、數據庫相關命名規範
3.1 數據庫命名
數據庫的命名一般採用小寫字母命名,如 testdb;
3.2 數據表命名
數據表命名格式爲 表前綴+下劃線(_)+表名 組合方式命名。同一數據庫表前綴相同,且使用小寫字母命名,表名使用小寫字母和下劃線命名。例如 wll_setting_record,其中wll爲前綴,setting_record爲表名。
3.3 字段命名
字段的命名採用小寫字母和下劃線命名,如 coin_type。
四、禁止使用的命名方式
4.1 無意義的命名
例如:$abcd、qqqqqqq()、test1111111等,命名應該使用對應的英文翻譯;
4.2 拼音命名
例如添加用戶(tjyh)或中英混合的(tjUser),如果使用這種方式,其他開發人員會很難看得懂,加大維護難度。
4.3 單字母命名
ThinkPHP中封裝了很多名稱爲單字母的快捷方法,例如A( )、C( )、M( )。如果再定義可能會發生衝突。
五、註釋規範
5.1 方法和函數
在方法和函數的上一行必須用雙斜線註釋註明該方法或函數的功能,在難以理解的代碼語句後面適當添加註釋說明,例如:
// 短信寶短信 http://www.smsbao.com/
public function smsbao($username, $password, $moble, $content)
{
$url = 'http://api.smsbao.com/sms?u=' . $username . '&p=' . $password . '&m=' . $moble . '&c=' . $content;
if (function_exists('file_get_contents')) {
$file_contents = file_get_contents($url);
} else {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$file_contents = curl_exec($ch);
curl_close($ch);
}
if ($file_contents > 0) {
return [$file_contents]; // 失敗
} else {
return [$file_contents, 1]; //成功
}
}
5.2 配置參數
在配置文件中的參數設置必須註明變量含義,例如:
'DB_TYPE' => 'mysql', // 數據庫類型
'DB_HOST' => 'localhost', // 服務器地址
'DB_NAME' => 'wlldb', // 數據庫名
'DB_USER' => 'root', // 用戶名
'DB_PWD' => 'root', // 密碼
六、編碼風格規範
6.1 禁止出現多行空格
如果不是特殊需要,在代碼文件中禁止出現多行空格,例如下面這種是不允許的:
//公共方法
public function common(){
$name='tom'; //定義姓名
$this->assign('name',$name);
$this->display();
}
6.2 縮進
代碼中需要適當的縮進,否則會加大維護難度。
6.3 目錄結構
一般框架都是有默認的目錄結構,非特殊情況不允許修改目錄結構,例如thinkphp默認的是MVC架構的目錄結構,避免由於更改目錄結構帶來的維護困難。Controller文件放在Controller目錄 中,Model文件放在Model目錄中,View文件放在View目錄中,不要隨意更改目錄的位置和目錄名稱。
七、安全
7.1.1 輸入框
所有的輸入框請設置最大長度,必填項請做必填的限制。例如帳號CHN00000001,只能輸入11位,那麼最大輸入長度只能爲11,並且添加required="required"屬性。
7.1.2 文本編輯器
前臺頁面儘量不要使用富文本編輯器,因爲富文本編輯器可以輸入代碼,有很大的安全隱患。如果要使用,必須對提交內容進行過濾,例如使用htmlspecialchars()進行過濾。
7.2 後臺接收參數
PHP從表單獲取url中獲取參數必須進行字段類型判斷。例如接收數字的參數不能含有其他字符,只能是數字,建議編寫公共的檢查接收post和get參數的函數,對每一個參數值進行驗證,防止注入惡意代碼。
接收長篇內容的變量,例如留言內容等變量時,必須進行特殊字符的過濾操作。比如strip_tags()、htmlspecialchars()、htmlentities()等函數可以起作用,防止用戶注入惡意代碼進行跨站腳本攻擊。
7.3 數據庫查詢
數據庫查詢語句禁止直接使用sql語句和傳遞的參數直接執行,例如下面這種的寫法是禁止使用的:
$id = 1;
$User = M("User"); // 實例化User對象
$User->where('id='.$id)->select(); //錯誤寫法1
$User->where("id=$id")->select(); //錯誤寫法2
如果傳遞過來的參數含有SQL注入代碼,這兩種寫法都是非常危險的。正確的寫法有以下兩種:
(1)數組條件,例如:
$where['id'] = 1;
$User = M("User"); // 實例化User對象
$User->where($where)->select();
或者
$User = M("User"); // 實例化User對象
$User->where(['id'=>1])->select();
(2)預處理機制,例如:
$User = M("User"); // 實例化User對象
$User->where("id=%d",$id)->select();
7.4 權限控制
凡是需要登錄之後纔可以訪問的頁面加載頁面之前必須做好登錄檢測,登錄超時的必須重新登錄。需要權限訪問的頁面和功能必須做好權限控制和檢測。
7.5 越權訪問
比如郵件列表的頁面 http://119.28.56.83/user/xq/id/5 ,只需要修改最後面的郵件id就可以直接訪問的,必須加入當前用戶判斷,只能查看自己的郵件,禁止越權訪問。
7.6 數據導出
數據的導出和下載必須做好登錄狀態驗證和權限的控制,沒有權限或沒有登錄的禁止下載導出。
7.7 防暴力破解
暴力破解是指使用數據字典等枚舉方式逐個帳號進行密碼的嘗試破解,爲了防止這種破解,在登錄、註冊、找回密碼等頁面必須設置好圖形驗證碼或者其他驗證,最好是做好錯誤次數的限制,例如密碼輸錯5次,一個小時內禁止登錄等。
7.8 短信郵件安全
用到發送短信和發送郵件的頁面,必須設置圖形驗證碼,點擊發送之前,驗證圖形驗證碼正確後再發送。最好限制每個手機號每天的發送數量。
7.9 密碼明文傳輸
一般在前端頁面表單提交的時候,用戶輸入密碼是明文的。在服務器沒有配置SLL證書(https)的情況下,必須先進行加密操作再提交,參數傳遞到後臺接收後再進行解密操作。服務器配置SLL證書(https)可以自動進行加密傳輸,安全性更高。
7.10 使用外部文件
在前端頁面中,禁止引入其他網站的靜態文件(javascript、css、網絡圖片等),如果需要用到,必須下載到本地,使用相對地址引入文件。使用本地靜態文件的優點:加載更快,安全,確保不失效。
7.11 密碼安全
禁止將明文密碼存儲在數據庫中,所有密碼必須加密處理,防止用戶數據被導出造成密碼泄露。禁止在日誌、調試信息文件、cookies中記錄密碼口令、銀行賬號、通信內容等敏感數據。爲了保障帳號的安全,所有密碼的長度強制限制在6位以上。
八、併發和大流量處理
8.1 重複提交
爲了防止用戶在提交表單時重複提交,表單必須設置提交驗證。例如商城提交訂單時,必須防止用戶重複提交。Thinkphp框架中提供表單令牌的功能可以防止重複提交,原生php也可以在打開頁面前生成token,並保存在session,然後將token傳遞到頁面表單字段,在表單提交時將token一起提交,在後臺接收時驗證token,驗證後銷燬session的保存的token。
8.2 session
一次性驗證的session使用後必須銷燬,例如短信驗證,表單驗證等,防止一次性session被重複利用,例如在用戶在註冊時如果不銷燬短信驗證碼session,用戶可以用同一個短信驗證碼註冊多個賬號。
8.3 併發
併發處理會經常碰到,例如商城秒殺功能,如果不做好併發處理,那麼同一件商品江湖被多個用戶購買。併發的處理方案可以考慮以下方案:
(1)鎖表操作,缺點是併發數比較大的時候回造成系統卡頓。
(2)隊列
(3)負載均衡
(4)數據庫讀寫分離
(5) 使用Nginx作爲http服務器
8.4 緩存
對於經常需要訪問的數據庫數據,可以使用緩存來提高訪問速度,讀取緩存文件數據幣數據庫查詢要快得多,主要緩存技術有:
(1)Thinkphp自帶的S()方法
(2)文件讀寫,這個方法主意數據的加密確保安全性
(3)Memcached