規(guī)范1
發(fā)表時間:2024-02-22 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]PHP程序編碼規(guī)范標準最后修改日期: 2000-11-16PHP編程標準是經(jīng)由Todd Hoff許可,基于《C++ 編程標準》為PHP而重寫的,作者為Fredrik Kristiansen,使用本標準,如果您想拷貝一份留做自用的話,那是完全免費的,這也是我們制作它的原因。假如您發(fā)現(xiàn)了任何的錯誤又或...
PHP程序編碼規(guī)范標準
最后修改日期: 2000-11-16
PHP編程標準是經(jīng)由Todd Hoff許可,基于《C++ 編程標準》為PHP而重寫的,
作者為Fredrik Kristiansen,
使用本標準,如果您想拷貝一份留做自用的話,那是完全免費的,這也是我們制作它的原因。假如您發(fā)現(xiàn)了任何的錯誤又或者是有任何的改進,請您給筆者發(fā)一個email,以便筆者將它們合并到最新更新中去。
目錄
介紹
標準化的重要性
解釋
認同觀點
項目的四個階段
命名規(guī)則
合適的命名
縮寫詞不要全部使用大寫字母
類命名
類庫命名
方法命名
類屬性命名
方法中參數(shù)命名
變量命名
引用變量和函數(shù)返回引用
全局變量
定義命名 / 全局常量
靜態(tài)變量
函數(shù)命名
php文件擴展名
文檔規(guī)則
評價注釋
Comments Should Tell a Story
Document Decisions
使用標頭說明
Make Gotchas Explicit
Interface and Implementation Documentation
目錄文檔
復(fù)雜性管理規(guī)則
Layering
Open/Closed Principle
Design by Contract
類規(guī)則
Different Accessor Styles
別在對象架構(gòu)期做實際的工作
Thin vs. Fat Class Interfaces
短方法
進程規(guī)則
Use a Design Notation and Process
Using Use Cases
Code Reviews
Create a Source Code Control System Early and Not Often
Create a Bug Tracking System Early and Not Often
RCS關(guān)鍵詞、更改記錄和歷史記錄規(guī)則
Honor Responsibilities
格式化
大括號 {} 規(guī)則
縮進/制表符/空格 規(guī)則
小括號、關(guān)鍵詞和函數(shù) 規(guī)則
If Then Else 格式
switch 格式
continue,break 和 ? 的使用
每行一個語句
聲明塊的定位
流行神話
Promise of OO
雜項
不要不可思議的數(shù)字
錯誤返回檢測規(guī)則
不要采用缺省值測試非零值
布爾邏輯類型
通常避免嵌入式的賦值
重用您和其他人的艱苦工作
使用if (0)來注釋外部代碼塊
其他雜項
--------------------------------------------------------------------------------
介紹
標準化的重要性
標準化問題在某些方面上讓每個人頭痛,讓人人都覺得大家處于同樣的境地。這有助于讓這些建
議在許多的項目中不斷演進,許多公司花費了許多星期逐子字逐句的進行爭論。標準化不是特殊
的個人風格,它對本地改良是完全開放的。
優(yōu)點
當一個項目嘗試著遵守公用的標準時,會有以下好處:
程序員可以了解任何代碼,弄清程序的狀況
新人可以很快的適應(yīng)環(huán)境
防止新接觸php的人出于節(jié)省時間的需要,自創(chuàng)一套風格并養(yǎng)成終生的習慣
防止新接觸php的人一次次的犯同樣的錯誤
在一致的環(huán)境下,人們可以減少犯錯的機會
程序員們有了一致的敵人 :-)
缺點
現(xiàn)在輪到壞處了:
因為標準由一些不懂得php的人所制定,所以標準通常看上去很傻
因為標準跟我做的不一樣,所以標準通?瓷先ズ苌
標準降低了創(chuàng)造力
標準在長期互相合作的人群中是沒有必要的
標準強迫太多的格式
總之人們忽視標準
討論
許多項目的經(jīng)驗?zāi)艿贸鲞@樣的結(jié)論:采用編程標準可以使項目更加順利地完成。標準是成功的關(guān)
鍵么?當然不。但它們可以幫助我們,而且我們需要我們能得到的所有的幫助!老實說,對一個
細節(jié)標準的大部分爭論主要是源自自負思想。對一個合理的標準的很少決定能被說為是缺乏技術(shù)
性的話,那只是口味的原因罷了。所以,要靈活的控制自負思想,記住,任何項目都取決于團隊
合作的努力。
解釋
慣例
在本文檔中使用“要”字所指的是使用本規(guī)范的所有項目需要遵守規(guī)定的標準。
使用“應(yīng)該”一詞的作用是指導項目定制項目細節(jié)規(guī)范。因為項目必須適當?shù)陌?(include),
排除(exclude)或定制(tailor)需求。
使用“可以”一詞的作用與“應(yīng)該”類似,因為它指明了可選的需求。
標準實施
首先應(yīng)該在開發(fā)小組的內(nèi)部找出所有的最重要的元素,也許標準對你的狀況還不夠恰當。它可能已經(jīng)概
括了 重要的問題,也可能還有人對其中的某些問題表示強烈的反對。
無論在什么情況下,只要最后順利的話,人們將成熟的明白到這個標準是合理的,然后其他的程序員們
也會發(fā)現(xiàn)它的合理性,并覺得帶著一些保留去遵循這一標準是值得的。
如果沒有自愿的合作,可以制定需求:標準一定要經(jīng)過代碼的檢驗。
如果沒有檢驗的話,這個解決方案僅僅是一個建立在不精確的基礎(chǔ)上的一大群可笑的人。
認同觀點
這行不通;
也許可行吧,但是它既不實用又無聊;
這是真的,而且我也告訴過你。
這個是我先想到的;
本來就應(yīng)該這樣。
如果您帶著否定的成見而來看待事物的話,請您保持開放的思想。你仍可以做出它是廢話的結(jié)論,但是做
出結(jié)論的方法就是你必須要能夠接受不同的思想。請您給自己一點時間去做到它。
項目的四個階段
數(shù)據(jù)庫結(jié)構(gòu)
設(shè)計
數(shù)據(jù)層
HTML層
--------------------------------------------------------------------------------
命名規(guī)則
合適的命名
命名是程序規(guī)劃的核心。古人相信只要知道一個人真正的名字就會獲得凌駕于那個人之上的不可思議的力
量。只要你給事物想到正確的名字,就會給你以及后來的人帶來比代碼更強的力量。別笑!
名字就是事物在它所處的生態(tài)環(huán)境中一個長久而深遠的結(jié)果?偟膩碚f,只有了解系統(tǒng)的程序員才能為系
統(tǒng)取出最合適的名字。如果所有的命名都與其自然相適合,則關(guān)系清晰,含義可以推導得出,一般人的推
想也能在意料之中。
如果你發(fā)覺你的命名只有少量能和其對應(yīng)事物相匹配的話, 最好還是重新好好再看看你的設(shè)計吧。
類命名
在為類(class )命名前首先要知道它是什么。如果通過類名的提供的線索,你還是想不起這個類是
什么 的話,那么你的設(shè)計就還做的不夠好。
超過三個詞組成的混合名是容易造成系統(tǒng)各個實體間的混淆,再看看你的設(shè)計,嘗試使用(CRC Se-
ssion card)看看該命名所對應(yīng)的實體是否有著那么多的功用。
對于派生類的命名應(yīng)該避免帶其父類名的誘惑,一個類的名字只與它自身有關(guān),和它的父類叫什么無
關(guān)。
有時后綴名是有用的,例如:如果你的系統(tǒng)使用了代理(agent ),那么就把某個部件命名為“下
載代理”(DownloadAgent)用以真正的傳送信息。
方法和函數(shù)命名
通常每個方法和函數(shù)都是執(zhí)行一個動作的,所以對它們的命名應(yīng)該清楚的說明它們是做什么的:用
CheckForErrors()代替ErrorCheck(),用DumpDataToFile()代替DataFile()。這么做也可以使功能和
數(shù)據(jù)成為更可區(qū)分的物體。
有時后綴名是有用的:
Max - 含義為某實體所能賦予的最大值。
Cnt - 一個運行中的計數(shù)變量的當前值。
Key - 鍵值。
例如:RetryMax 表示最多重試次數(shù),RetryCnt 表示當前重試次數(shù)。
有時前綴名是有用的:
Is - 含義為問一個關(guān)于某樣事物的問題。無論何時,當人們看到Is就會知道這是一個問題。
Get - 含義為取得一個數(shù)值。
Set - 含義為設(shè)定一個數(shù)值
例如:IsHitRetryLimit。
縮寫詞不要全部使用大寫字母
無論如何,當遇到以下情況,你可以用首字母大寫其余字母小寫來代替全部使用大寫字母的方法來表
示縮寫詞。
使用: GetHtmlStatistic.
不使用: GetHTMLStatistic.
理由
當命名含有縮略詞時,人們似乎有著非常不同的直覺。統(tǒng)一規(guī)定是最好,這樣一來,命名的含義就完
全可以預(yù)知了。
舉個NetworkABCKey的例子,注意C是應(yīng)該是ABC里面的C還是key里面的C,這個是很令人費解的。有些
人不在意這些,其他人卻很討厭這樣。所以你會在不同的代碼里看到不同的規(guī)則,使得你不知道怎么
去叫它。
例如
class FluidOz // 不要寫成 FluidOZ
class GetHtmlStatistic // 不要寫成 GetHTMLStatistic
--------------------------------------------------------------------------------
類命名
使用大寫字母作為詞的分隔,其他的字母均使用小寫
名字的首字母使用大寫
不要使用下劃線('_')
理由
根據(jù)很多的命名方式,大部分人認為這樣是最好的方式。
例如
class NameOneTwo
class Name
--------------------------------------------------------------------------------
類庫命名
目前命名空間正在越來越廣泛的被采用,以避免不同廠商和團體類庫間的類名沖突。
當尚未采用命名空間的時候,為了避免類名沖突,一般的做法是在類名前加上獨特的前綴,兩個字符就
可以了,當然多用一些會更好。
例如
John Johnson的數(shù)據(jù)結(jié)構(gòu)類庫可以用Jj做為前綴,如下:
class JjLinkList
{
}
--------------------------------------------------------------------------------
方法命名
采用與類命名一致的規(guī)則
理由
使用所有不同規(guī)則的大部分人發(fā)現(xiàn)這是最好的折衷辦法。
例如
class NameOneTwo
{
function DoIt() {};
function HandleError() {};
}
--------------------------------------------------------------------------------
類屬性命名
屬性命名應(yīng)該以字符‘m’為前綴。
前綴‘m’后采用于類命名一致的規(guī)則。
‘m’總是在名字的開頭起修飾作用,就像以‘r’開頭表示引用一樣。
理由
前綴'm'防止類屬性和方法名發(fā)生任何沖突。你的方法名和屬性名經(jīng)常會很類似,特別是存取元素。
例如
class NameOneTwo
{
function VarAbc() {};
function ErrorNumber() {};
var mVarAbc;
var mErrorNumber;
var mrName;
}
--------------------------------------------------------------------------------
方法中參數(shù)命名
第一個字符使用小寫字母。
在首字符后的所有字都按照類命名規(guī)則首字符大寫。
理由
你可以隨時知道那個變量對應(yīng)那個變量。
你可以使用與類名相似的名稱而不至于產(chǎn)生重名沖突。
例如
class NameOneTwo
{
function StartYourEngines(
&$rSomeEngine,
&$rAnotherEngine);
}
--------------------------------------------------------------------------------
變量命名
所有字母都使用小寫
使用'_'作為每個詞的分界。
理由
通過這一途徑,代碼中變量的作用域是清晰的。
所有的變量在代碼中都看起來不同,容易辨認。
例如
function HandleError($errorNumber)
{
$error = OsErr();
$time_of_error = OsErr->getTimeOfError;
$error_processor = OsErr->getErrorProcessor;
}
--------------------------------------------------------------------------------
引用變量和函數(shù)返回引用
引用必須帶‘r’前綴
理由
使得類型不同的變量容易辨認
它可以確定哪個方法返回可更改對象,哪個方法返回不可更改對象。
例如
class Test
{
var mrStatus;
function DoSomething(&$rStatus) {};
function &rStatus() {};
}
--------------------------------------------------------------------------------
全局變量
全局變量應(yīng)該帶前綴‘g’。
理由
知道一個變量的作用域是非常重要的。
例如
global $gLog;
global &$grLog;
--------------------------------------------------------------------------------
定義命名 / 全局常量
全局常量用'_'分隔每個單詞。
理由
這是命名全局常量的傳統(tǒng)。你要注意不要與其它的定義相沖突。
例如
define("A_GLOBAL_CONSTANT", "Hello world!");
--------------------------------------------------------------------------------
靜態(tài)變量
靜態(tài)變量應(yīng)該帶前綴‘s’。
理由
知道一個變量的作用域是非常重要的。
例如
function test(){static $msStatus = 0;
}
--------------------------------------------------------------------------------
函數(shù)命名
函數(shù)名字采用C GNU的慣例,所有的字母使用小寫字母,使用'_'分割單詞。
理由
這樣可以更易于區(qū)分相關(guān)聯(lián)的類名。
例如
function some_bloody_function()
{
}
--------------------------------------------------------------------------------
錯誤返回檢測規(guī)則
檢查所有的系統(tǒng)調(diào)用的錯誤信息,除非你要忽略錯誤。
為每條系統(tǒng)錯誤消息定義好系統(tǒng)錯誤文本以便include。
--------------------------------------------------------------------------------
大括號 {} 規(guī)則
在三種主要的大括號放置規(guī)則中,有兩種是可以接受的,如下的第一種是最好的:
將大括號放置在關(guān)鍵詞下方的同列處:
if ($condition) while ($condition)
{ {
... ...
} }
傳統(tǒng)的UNIX的括號規(guī)則是,首括號與關(guān)鍵詞同行,尾括號與關(guān)鍵字同列:
if ($condition) { while ($condition) {
... ...
} }
理由
引起劇烈爭論的非原則的問題可通過折衷的辦法解決,兩種方法任意一種都是可以接受的,然而對于大
多數(shù)人來說更喜歡第一種。原因就是心理研究學習范疇的東西了。
對于更喜歡第一種還有著更多的原因。如果您使用的字符編輯器支持括號匹配功能的話(例如vi),最
重要的就是有一個好的樣式。為什么?我們說當你有一大塊的程序而且想知道這一大塊程序是在哪兒結(jié)
束的話。你先移到開始的括號,按下按鈕編輯器就會找到與之對應(yīng)的結(jié)束括號,例如:
if ($very_long_condition && $second_very_long_condition)
{
...
}
else if (...)
{
...
}
從一個程序塊移動到另一個程序塊只需要用光標和你的括號匹配鍵就可以了,不需要來回的移動到行末去
找匹配的括號。
--------------------------------------------------------------------------------
縮進/制表符/空格 規(guī)則
使用制表符縮進。
使用三到四個空格為每層次縮進。
不再使用只要一有需要就縮排的方法。對與最大縮進層數(shù),并沒有一個固定的規(guī)矩,假如縮進層數(shù)大于四或
者五層的時候,你可以考慮著將代碼因數(shù)分解(factoring out code)。
理由
許多編程者支持制表符。
Tabs was invented for a rason
當人們使用差異太大的制表符標準的話,會使閱讀代碼變得很費力。
如此多的人愿意限定最大的縮進層數(shù),它通常從未被看作是一件工作。我們相信程序員們會明智的選擇嵌套
的深度。
例如
function func()
{
if (something bad)
{
if (another thing bad)
{
while (more input)
{
}
}
}
}
--------------------------------------------------------------------------------
小括號、關(guān)鍵詞和函數(shù) 規(guī)則
不要把小括號和關(guān)鍵詞緊貼在一起,要用空格隔開它們。
不要把小括號和函數(shù)名緊貼在一起。
除非必要,不要在Return返回語句中使用小括號。
理由
關(guān)鍵字不是函數(shù)。如果小括號緊貼著函數(shù)名和關(guān)鍵字,二者很容易被看成是一體的。
例如
if (condition)
{
}
while (condition)
{
}
strcmp($s, $s1);
return 1;
--------------------------------------------------------------------------------
RCS關(guān)鍵詞、更改記錄和歷史記錄規(guī)則
直接使用RCS關(guān)鍵詞的規(guī)則必須改變,其中包括使用CVS等類似的支持RCS風格關(guān)鍵詞的源代碼控制系統(tǒng):
別在文件以內(nèi)使用 RCS 關(guān)鍵詞。
別在文件中保存歷史修改記錄。
別在文件中保存作者信息記錄。
理由
The reasoning is your source control system already keeps all this information. There is no reason to clutter up source files with duplicate information that:
makes the files larger
makes doing diffs difficult as non source code lines change
makes the entry into the file dozens of lines lower in the file which makes a search or jump necessary for each file
is easily available from the source code control system and does not need embedding in the file
When files must be sent to other organizations the comments may contain internal details that should not be exposed to outsiders.
--------------------------------------------------------------------------------
別在對象架構(gòu)期做實際的工作
別在對象架構(gòu)期做真實的工作,在架構(gòu)期初始化變量和/或做任何不會有失誤的事情。
當完成對象架構(gòu)時,為該對象建立一個Open()方法,Open()方法應(yīng)該以對象實體命名。
理由
構(gòu)造不能返回錯誤 。
例如
class Device
{
function Device(){ /* initialize and other stuff */ }
function Open(){ return FAIL; }
};
$dev = new Device;
if (FAIL == $dev->Open()) exit(1);
--------------------------------------------------------------------------------