




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、PHPCMS中的PHP編碼規(guī)范注:這是從PHPCMS開發(fā)文檔里看到編碼規(guī)范,雖名為PHPCMS的開發(fā)規(guī)范,但我覺得所有的PHP編程都該如此。寫了那么多PHP,很多編碼對(duì)照這規(guī)范都感覺欠缺很多,今后一定要對(duì)照糾正。Phpcms 編碼規(guī)范1. 引言. 22. 適用范圍. 23. 標(biāo)準(zhǔn)化的重要性和好處. 34. PHP編碼規(guī)范與原則. 34.1. 代碼標(biāo)記 34.2. 注釋 34.3. 書寫規(guī)則 44.3.1. 縮進(jìn) 44.3.2. 大括號(hào)、if和switch. 44.3.3. 運(yùn)算符、小括號(hào)、空格、關(guān)鍵詞和函數(shù) 54.3.4. 函數(shù)定義 64.3.5. 引號(hào) 64.3.6. 多語言問題 74.4.
2、 命名原則 84.4.1. 變量、對(duì)象、函數(shù)名 84.4.2. 常量 84.5. 變量的初始化與邏輯檢查 84.6. 安全性 94.7. 兼容性 94.8. 代碼重用 104.9. 其他細(xì)節(jié)問題 104.9.1. 包含調(diào)用 104.9.2. 錯(cuò)誤報(bào)告級(jí)別 115. 數(shù)據(jù)庫設(shè)計(jì). 115.1. 字段 115.1.1. 表和字段命名 115.1.2. 字段結(jié)構(gòu) 115.2. SQL語句 125.3. 性能與效率 135.3.1. 定長(zhǎng)與變長(zhǎng)表 135.3.2. 運(yùn)算與檢索 135.3.3. 結(jié)構(gòu)優(yōu)化與索引優(yōu)化 145.3.4. 查詢優(yōu)化 145.3.5. 兼容性問題 166. 模板設(shè)計(jì). 166.
3、1. 代碼標(biāo)記 166.2. 書寫規(guī)則 166.2.1. HTML. 166.2.2. 變量 166.2.3. 語言元素 176.2.4. 縮進(jìn) 177. 文件與目錄. 177.1. 文件命名 177.2. 目錄命名 187.3. 空目錄索引 181. 引言本規(guī)范由編程原則組成,融合并提煉了開發(fā)人員長(zhǎng)時(shí)間積累下來的成熟經(jīng)驗(yàn),意在幫助形成良好一致的編程風(fēng)格。以達(dá)到事半功倍的效果,如果有需要本文檔會(huì)不定期更新。版權(quán): 陜西玖肆陸陸網(wǎng)絡(luò)科技有限公司,保留所有權(quán)利最后更新日期:年11月20日 20062. 適用范圍如無特殊說明,以下規(guī)則要求完全適用于phpcms項(xiàng)目,同時(shí)也可大部分適用于公司其他PHP
4、項(xiàng)目。3. 標(biāo)準(zhǔn)化的重要性和好處當(dāng)一個(gè)軟件項(xiàng)目嘗試著遵守公共一致的標(biāo)準(zhǔn)時(shí),可以使參與項(xiàng)目的開發(fā)人員更容易了解項(xiàng)目中的代碼、弄清程序的狀況。使新的參與者可以很快的適應(yīng)環(huán)境,防止部分參與者出于節(jié)省時(shí)間的需要,自創(chuàng)一套風(fēng)格并養(yǎng)成終生的習(xí)慣,導(dǎo)致其它人在閱讀時(shí)浪費(fèi)過多的時(shí)間和精力。而且在一致的環(huán)境下,也可以減少編碼出錯(cuò)的機(jī)會(huì)。缺陷是由于每個(gè)人的標(biāo)準(zhǔn)不同,所以需要一段時(shí)間來適應(yīng)和改變自己的編碼風(fēng)格,暫時(shí)性的降底了工作效率。從使項(xiàng)目長(zhǎng)遠(yuǎn)健康的發(fā)展以及后期更高的團(tuán)隊(duì)工作效率來考慮暫時(shí)的工作效率降低是值得的,也是必須要經(jīng)過的一個(gè)過程。標(biāo)準(zhǔn)不是項(xiàng)目成功的關(guān)鍵,但可以幫助我們?cè)趫F(tuán)隊(duì)協(xié)作中有更高的效率并且更加順利的
5、完成既定的任務(wù)。1. 程序員可以了解任何代碼,弄清程序的狀況2. 新人可以很快的適應(yīng)環(huán)境3. 防止新接觸PHP的人出于節(jié)省時(shí)間的需要,自創(chuàng)一套風(fēng)格并養(yǎng)成終生的習(xí)慣4. 防止新接觸PHP的人一次次的犯同樣的錯(cuò)誤5. 在一致的環(huán)境下,人們可以減少犯錯(cuò)的機(jī)會(huì)6. 程序員們有了一致的敵人4. PHP編碼規(guī)范與原則4.1.代碼標(biāo)記PHP程序可以使用或來界定 PHP 代碼,在HTML頁面中嵌入純變量時(shí),可以使用這樣的形式。近年來PHP開發(fā)組一直倡導(dǎo)代碼規(guī)范化和標(biāo)準(zhǔn)化,未來版本PHP可能會(huì)開始不建議使用甚至取消和這種速記形式,因此為了加強(qiáng)程序兼容性,在發(fā)布之前我們將統(tǒng)一把 4.2.注釋注釋是對(duì)于那些容易忘記
6、作用的代碼添加簡(jiǎn)短的介紹性內(nèi)容。請(qǐng)使用 C 樣式的注釋“/* */”和標(biāo)準(zhǔn) C+ 注釋“/”。程序開發(fā)中難免留下一些臨時(shí)代碼和調(diào)試代碼,此類代碼必須添加注釋,以免日后遺忘。所有臨時(shí)性、調(diào)試性、試驗(yàn)性的代碼,必須添加統(tǒng)一的注釋標(biāo)記“/debug”并后跟完整的注釋信息,這樣可以方便在程序發(fā)布和最終調(diào)試前批量檢查程序中是否還存在有疑問的代碼。例如:$num = 1;$flag = TRUE; /debug 這里不能確定是否需要對(duì)$flag進(jìn)行賦值if(empty($flag) /Statements 4.3.書寫規(guī)則4.3.1. 縮進(jìn)每個(gè)縮進(jìn)的單位約定是一個(gè)TAB(8個(gè)空白字符寬度),需每個(gè)參與項(xiàng)目
7、的開發(fā)人員在編輯器(UltraEdit、EditPlus、Zend Studio等)中進(jìn)行強(qiáng)制設(shè)定,以防在編寫代碼時(shí)遺忘而造成格式上的不規(guī)范。本縮進(jìn)規(guī)范適用于PHP、JavaScript中的函數(shù)、類、邏輯結(jié)構(gòu)、循環(huán)等。4.3.2. 大括號(hào)、if和switch首括號(hào)與關(guān)鍵詞同行,尾括號(hào)與關(guān)鍵字同列;if結(jié)構(gòu)中,if和elseif與前后兩個(gè)圓括號(hào)同行,左右各一個(gè)空格,所有大括號(hào)都單獨(dú)另起一行。另外,即便if后只有一行語句,仍然需要加入大括號(hào),以保證結(jié)構(gòu)清晰;switch結(jié)構(gòu)中,通常當(dāng)一個(gè)case塊處理后,將跳過之后的case塊處理,因此大多數(shù)情況下需要添加break。break的位置視程序邏輯,與
8、case同在一行,或新起一行均可,但同一switch體中,break的位置格式應(yīng)當(dāng)保持一致。以下是符合上述規(guī)范的例子:If ($condition)switch ($var)case 1: echo var is 1; break;case 2: echo var is 2; break;default: echo var is neither 1 or 2; break;elseswitch ($str)case abc:$result = abc;break;default:$result = unknown;break; 4.3.3. 運(yùn)算符、小括號(hào)、空格、關(guān)鍵詞和函數(shù)每個(gè)運(yùn)算符與兩邊參
9、與運(yùn)算的值或表達(dá)式中間要有一個(gè)空格,唯一的特例是字符連接運(yùn)算符號(hào)兩邊不加空格;左括號(hào)“(” 應(yīng)和函數(shù)關(guān)鍵詞緊貼在一起,除此以外應(yīng)當(dāng)使用空格將“(”同前面內(nèi)容分開;右括號(hào)“)”除后面是“)”或者“.”以外,其他一律用空格隔開它們;除字符串中特意需要,一般情況下,在程序以及HTML中不出現(xiàn)兩個(gè)連續(xù)的空格;任何情況下,PHP程序中不能出現(xiàn)空白的帶有TAB或空格的行,即:這類空白行應(yīng)當(dāng)不包含任何TAB或空格。同時(shí),任何程序行尾也不能出現(xiàn)多余的TAB或空格。多數(shù)編輯器具有自動(dòng)去除行尾空格的功能,如果習(xí)慣養(yǎng)成不好,可臨時(shí)使用它,避免多余空格產(chǎn)生;每段較大的程序體,上、下應(yīng)當(dāng)加入空白行,兩個(gè)程序塊之間只使用
10、1個(gè)空行,禁止使用多行。程序塊劃分盡量合理,過大或者過小的分割都會(huì)影響他人對(duì)代碼的閱讀和理解。一般可以以較大函數(shù)定義、邏輯結(jié)構(gòu)、功能結(jié)構(gòu)來進(jìn)行劃分。少于15行的程序塊,可不加上下空白行;說明或顯示部分中,內(nèi)容如含有中文、數(shù)字、英文單詞混雜,應(yīng)當(dāng)在數(shù)字或者英文單詞的前后加入空格。根據(jù)上述原則,以下舉例說明正確的書寫格式:$result = ($a + 1) * 3 / 2 + $num).Test;$condition ? func1($var) : func2($var);$condition ? $long_statement: $another_long_statement;if ($fl
11、ag)/Statements/More than 15 linesShowmessage(請(qǐng)使用 restore.php 工具恢復(fù)數(shù)據(jù)。); 4.3.4. 函數(shù)定義l 參數(shù)的名字和變量的命名規(guī)范一致;l 函數(shù)定義中的左小括號(hào),與函數(shù)名緊挨,中間無需空格;l 開始的左大括號(hào)另起一行;l 具有默認(rèn)值的參數(shù)應(yīng)該位于參數(shù)列表的后面;l 函數(shù)調(diào)用與定義的時(shí)候參數(shù)與參數(shù)之間加入一個(gè)空格;l 必須仔細(xì)檢查并切實(shí)杜絕函數(shù)起始縮進(jìn)位置與結(jié)束縮進(jìn)位置不同的現(xiàn)象。例如,符合標(biāo)準(zhǔn)的定義:function authcode($string, $operation, $key = '')if($flag)
12、/Statement/函數(shù)體 不符合標(biāo)準(zhǔn)的定義:function authcode($string,$operation,$key = '') /函數(shù)體 4.3.5. 引號(hào)PHP中單引號(hào)和雙引號(hào)具有不同的含義,最大的幾項(xiàng)區(qū)別如下:?jiǎn)我?hào)中,任何變量($var)、特殊轉(zhuǎn)義字符(如“t r n”等)不會(huì)被解析,因此PHP的解析速度更快,轉(zhuǎn)義字符僅僅支持“”和“”這樣對(duì)單引號(hào)和反斜杠本身的轉(zhuǎn)義;雙引號(hào)中,變量($var)值會(huì)代入字符串中,特殊轉(zhuǎn)義字符也會(huì)被解析成特定的單個(gè)字符,還有一些專門針對(duì)上述兩項(xiàng)特性的特殊功能性轉(zhuǎn)義,例如“$”和“$arraykey。這樣雖然程序編寫更加方便,但
13、同時(shí)PHP的解析也很慢;數(shù)組中,如果下標(biāo)不是整型,而是字符串類型,請(qǐng)務(wù)必用單引號(hào)將下標(biāo)括起,正確的寫法為$arraykey,而不是$arraykey,因?yàn)椴徽_的寫法會(huì)使PHP解析器認(rèn)為key是一個(gè)常量,進(jìn)而先判斷常量是否存在,不存在時(shí)才以“key”作為下標(biāo)帶入表達(dá)式中,同時(shí)出發(fā)錯(cuò)誤事件,產(chǎn)生一條Notice級(jí)錯(cuò)誤。因此,在絕大多數(shù)可以使用單引號(hào)的場(chǎng)合,禁止使用雙引號(hào)。依據(jù)上述分析,可以或必須使用單引號(hào)的情況包括但不限于下述:l 字符串為固定值,不包含“t”等特殊轉(zhuǎn)義字符;l 數(shù)組的固定下標(biāo),例如$arraykey;l 表達(dá)式中不需要帶入變量,例如$string = test;,而非$stri
14、ng = “test$var”;例外的,在正則表達(dá)式(用于preg_系列函數(shù)和ereg系列函數(shù))中,phpcms全部使用雙引號(hào),這是為了人工分析和編寫的方便,并保持正則表達(dá)式的統(tǒng)一,減少不必要的分析混淆。數(shù)據(jù)庫SQL語句中,所有數(shù)據(jù)都不得加單引號(hào),但是在進(jìn)行sql查詢之前都必須經(jīng)過intval函數(shù)處理;所有字符串都必須加單引號(hào),以避免可能的注入漏洞和SQL錯(cuò)誤。正確的寫法為:$catid = intval($catid);SELECT * FROM phpcms_member WHERE username=$_username AND catid=$catid; 所有數(shù)據(jù)在插入數(shù)據(jù)庫之前,均需
15、要進(jìn)行addslashes()處理,以免特殊字符未經(jīng)轉(zhuǎn)義在插入數(shù)據(jù)庫的時(shí)候出現(xiàn)錯(cuò)誤。phpcms中如果已經(jīng)引入了文件 common.inc.php,則所有通過 GET, POST, FILE,取得的變量默認(rèn)情況下已經(jīng)使用了addslashes()進(jìn)行了轉(zhuǎn)義,不必重復(fù)進(jìn)行。如果數(shù)據(jù)處理必要(例如用于直接顯示),可以使用 stripslashes() 恢復(fù),但數(shù)據(jù)在插入數(shù)據(jù)庫之前必須再次進(jìn)行轉(zhuǎn)義。緩存文件中,一般對(duì)緩存數(shù)據(jù)的值采用 addcslashes($string, ''')進(jìn)行轉(zhuǎn)義。4.3.6. 4.4.命名原則命名是程序規(guī)劃的核心。古人相信只要知道一個(gè)人真正的名字
16、就會(huì)獲得凌駕于那個(gè)人之上的不可思議的力量。只要你給事物想到正確的名字,就會(huì)給你以及后來的人帶來比代碼更強(qiáng)的力量。名字就是事物在它所處的生態(tài)環(huán)境中一個(gè)長(zhǎng)久而深遠(yuǎn)的結(jié)果??偟膩碚f,只有了解系統(tǒng)的程序員才能為系統(tǒng)取出最合適的名字。如果所有的命名都與其自然相適合,則關(guān)系清晰,含義可以推導(dǎo)得出,一般人的推想也能在意料之中。就一般約定而言,類、函數(shù)和變量的名字應(yīng)該總是能夠描述讓代碼閱讀者能夠容易的知道這些代碼的作用。形式越簡(jiǎn)單、越有規(guī)則,就越容易讓人感知和理解。應(yīng)該避免使用模棱兩可,晦澀不標(biāo)準(zhǔn)的命名。4.4.1. 變量、對(duì)象、函數(shù)名變量、對(duì)象、函數(shù)名一律為小寫格式,除非必要,單詞之間一般不使用下劃線“_”
17、進(jìn)行分割;以標(biāo)準(zhǔn)計(jì)算機(jī)英文為藍(lán)本,杜絕一切拼音、或拼音英文混雜的命名方式;變量命名只能使用項(xiàng)目中有據(jù)可查的英文縮寫方式,例如可以使用$data而不可使用$data1、$data2這樣容易產(chǎn)生混淆的形式,應(yīng)當(dāng)使用$articledata、$userdata這樣一目了然容易理解的形式;可以合理的對(duì)過長(zhǎng)的命名進(jìn)行縮寫,例如$bio($biography),$tpp($threadsPerPage),前提是英文中有這樣既有的縮寫形式,或字母符合英文縮寫規(guī)范;必須清楚所使用英文單詞的詞性,在權(quán)限相關(guān)的范圍內(nèi),大多使用$enable*、$is* 、的形式,前者后面接動(dòng)詞,后者后面接形容詞。4.4.2. 常
18、量常量應(yīng)該總是全部使用大寫字母命名,少數(shù)特別必要的情況下,可使用劃線來分隔單詞;PHP 的內(nèi)建值 TRUE、FALSE 和NULL必須全部采用大寫字母書寫。4.5.變量的初始化與邏輯檢查任何變量在進(jìn)行累加、直接顯示或存儲(chǔ)前必需進(jìn)行初使化,例如:$number = 0; /數(shù)值型初始化$string = ; /字符串初始化$array = array(); /數(shù)組初始化 判斷一個(gè)無法確定(不知道是否已被賦值)的變量時(shí),可用empty()或isset(),而不要直接使用if($switch)的形式,除非你確切的知道此變量一定已經(jīng)被初始化并賦值。empty()和isset()的區(qū)別為:l bool
19、empty(mixed var)n 如果 var 是非空或非零的值,則 empty() 返回 FALSE。換句話說,""、0、"0"、NULL、FALSE、array()、var $var; 以及沒有任何屬性的對(duì)象都將被認(rèn)為是空的,如果 var 為空,則返回 TRUE。l bool isset(mixed var, mixed var, .)n 如果 var 存在則返回 TRUE,否則返回 FALSE。n 如果已經(jīng)使用 unset() 釋放了一個(gè)變量之后,它將不再是 isset()。若使用 isset() 測(cè)試一個(gè)被設(shè)置成 NULL 的變量,將返回 FA
20、LSE。同時(shí)要注意的是一個(gè) NULL 字節(jié)("0")并不等同于 PHP 的 NULL 常數(shù)。判斷一個(gè)變量是否為數(shù)組,請(qǐng)使用is_array(),這種判斷尤其適用于對(duì)數(shù)組進(jìn)行遍歷的操作,例如foreach(),因?yàn)槿绻皇孪扰袛?,foreach()會(huì)對(duì)非數(shù)組類型的變量報(bào)錯(cuò);判斷一個(gè)數(shù)組元素是否存在,可使用isset($arraykey),也可使用empty(),兩者異同見上。4.6.安全性PHP中的變量不并不像C語言那樣需要事先聲明,解釋器會(huì)在第一次使用時(shí)自動(dòng)創(chuàng)建他們,同樣類型也不需要指定,解釋器會(huì)根據(jù)上下文環(huán)境自動(dòng)確定。從開發(fā)人員的角度來看,這無疑是一種極其方便的處理方法。
21、一個(gè)變量被創(chuàng)建了,就可以在程序中的任何地方使用。這導(dǎo)致的結(jié)果就是開發(fā)人員工經(jīng)常不注意初始化變量。因此,為了提高程序的安全性,我們不能相信任何沒有明確定義的變量。所有的變量在定義使用前要初使化以防止惡意構(gòu)造提交的變量覆蓋程序中使用的變量。細(xì)節(jié)可以閱讀()這篇文檔,該文檔里羅列了PHP常見的安全問題,閱讀該文檔是非常有必要的!4.7.兼容性代碼設(shè)計(jì)應(yīng)當(dāng)兼顧PHP 高低版本的特性,當(dāng)前,應(yīng)仍然以PHP 4.3.0作為最低通過平臺(tái),盡量不使用高版本PHP 新增的函數(shù)、常數(shù)或者常量。如果使用只在高版本才具備的函數(shù),必須對(duì)其進(jìn)行二次封裝,自動(dòng)判斷當(dāng)前PHP版本,并自行編寫低版本下的兼容代碼;對(duì)于個(gè)別函數(shù),
22、參數(shù)要求或者代碼要求應(yīng)當(dāng)以較為嚴(yán)格的PHP版本為準(zhǔn);除非必要,不要使用PHP擴(kuò)展模塊中的函數(shù)。使用時(shí)應(yīng)當(dāng)加入必要的判斷,當(dāng)服務(wù)器環(huán)境不支持此函數(shù)的時(shí)候,進(jìn)行必要的處理。文檔和程序中的功能說明中,也應(yīng)加上兼容性說明。4.8.代碼重用代碼的有效重用可以減少效率的損失與資源的浪費(fèi)。在開發(fā)軟件項(xiàng)目時(shí)為了避免重復(fù)勞動(dòng)和浪費(fèi)時(shí)間。開發(fā)人員應(yīng)盡量提高現(xiàn)有代碼的重用率,同時(shí)將更多的精力用在新技術(shù)的應(yīng)用和新功能的創(chuàng)新開發(fā)上面。l 在需要多次使用代碼,并且對(duì)于您希望實(shí)現(xiàn)的任務(wù)沒有可用的內(nèi)置 PHP 函數(shù)時(shí),不吝嗇定義函數(shù)或類。開發(fā)者須根據(jù)功能、調(diào)用情況,將函數(shù)放置于include目錄并以.func.php作為函數(shù)
23、文件后綴,將類放置于include/class目錄。超過3行,實(shí)現(xiàn)相同功能的程序切勿在不同程序中多次出現(xiàn),這是無法容忍和回避的問題;l 在任何時(shí)候都不要出現(xiàn)同一個(gè)程序中出現(xiàn)兩段或更多的相似代碼或相同代碼,即便在不同程序中,也應(yīng)盡力避免。開發(fā)者應(yīng)當(dāng)總是有能力找到避免代碼大段(超過10行)重復(fù)或類似的情況。需要強(qiáng)調(diào)的是,本部分雖然篇幅較短,但卻是十分需要經(jīng)驗(yàn),并將花費(fèi)開發(fā)者大量時(shí)間和精力去進(jìn)行優(yōu)化的部分,任何產(chǎn)品開發(fā)者必須時(shí)刻清楚和理解代碼重用的重要性和必要性,切實(shí)在增強(qiáng)產(chǎn)品效率、邏輯性和可讀性上下功夫,這是一名優(yōu)秀軟件開發(fā)者所必須具備的基本素質(zhì)。4.9.其他細(xì)節(jié)問題4.9.1. 包含調(diào)用包含調(diào)用
24、程序文件,請(qǐng)全部使用require_once,以避免可能的重復(fù)包含問題;包含調(diào)用緩存文件,由于緩存文件無法保證100%正確打開,請(qǐng)使用include_once或include。在必要時(shí),可以使用include_once或include的方式,以忽略錯(cuò)誤提示;包含和調(diào)用代碼中,須以PHPCMS_ROOT./開頭,應(yīng)避免直接寫程序文件名(例如:require_once x.php;)的做法;所有被包含和調(diào)用的程序文件,包括但不限于程序、緩存或模板,通常其不能被直接URL請(qǐng)求。phpcms通過在./include/common.inc.php中定義一個(gè)標(biāo)記性常量IN_PHPCMS,來判斷程序是否被合
25、法調(diào)用。因此,在除了./include/common.inc.php以外的任何一個(gè)被包含和調(diào)用的程序文件中,需要包含以下內(nèi)容,以使得訪問者無法直接通過URL請(qǐng)求該文件:defined('IN_PHPCMS') or exit('Access Denied'); 4.9.2. 錯(cuò)誤報(bào)告級(jí)別在軟件開發(fā)和調(diào)試階段,請(qǐng)使用error_reporting(E_ALL);作為默認(rèn)的錯(cuò)誤報(bào)告級(jí)別,此級(jí)別最為嚴(yán)格,能夠報(bào)告程序中所有的錯(cuò)誤、警告和提示信息,以幫助開發(fā)者檢查和核對(duì)代碼,避免大多數(shù)安全性問題和邏輯錯(cuò)誤、拼寫錯(cuò)誤。error_reporting()可以在./inclu
26、de/common.inc.php的頭幾行進(jìn)行設(shè)置。在軟件發(fā)布時(shí),請(qǐng)使用error_reporting(E_ERROR | E_WARNING | E_PARSE);作為默認(rèn)的錯(cuò)誤報(bào)告級(jí)別,以利于用戶使用并將無謂錯(cuò)誤提示信息降至最低。5. 數(shù)據(jù)庫設(shè)計(jì)5.1.字段5.1.1. 表和字段命名表和字段的命名以前面4.4命名原則的約定為基本準(zhǔn)則。所有數(shù)據(jù)表名稱,只要其名稱是可數(shù)名詞,則必須以復(fù)數(shù)方式命名,例如:phpcms_member(用戶表);存儲(chǔ)多項(xiàng)內(nèi)容的字段,或代表數(shù)量的字段,也應(yīng)當(dāng)以復(fù)數(shù)方式命名,例如:hits(查看次數(shù))、items(內(nèi)容數(shù)量)。當(dāng)幾個(gè)表間的字段有關(guān)連時(shí),要注意表與表之間關(guān)
27、聯(lián)字段命名的統(tǒng)一,如phpcms_article_1表中的articleid與phpcms_article_data_1表中的articleid。代表id自增量的字段,通常用以下幾種形式:l 一般情況下,使用全稱的形式,例如userid、articleid;l 沒有功能性作用,只為管理和維護(hù)方便而設(shè)的id,可以使用全稱的形式,也可只將其命名為id。篇幅所限,無法一一贅述,但所有與表、字段相關(guān)的命名,請(qǐng)務(wù)必大量參考phpcms現(xiàn)有字段的命名方式,以保證命名的系統(tǒng)性和統(tǒng)一性。5.1.2. 字段結(jié)構(gòu)允許NULL值的字段,數(shù)據(jù)庫在進(jìn)行比較操作時(shí),會(huì)先判斷其是否為NULL,非NULL時(shí)才進(jìn)行值的必對(duì)。因
28、此基于效率的考慮,所有字段均不能為空,即全部NOT NULL;預(yù)計(jì)不會(huì)存儲(chǔ)非負(fù)數(shù)的字段,例如各項(xiàng)id、發(fā)帖數(shù)等,必須設(shè)置為UNSIGNED類型。UNSIGNED類型比非UNSIGNED類型所能存儲(chǔ)的正整數(shù)范圍大一倍,因此能獲得更大的數(shù)值存儲(chǔ)空間;存儲(chǔ)開關(guān)、選項(xiàng)數(shù)據(jù)的字段,通常使用tinyint(1)非UNSIGNED類型,少數(shù)情況也可能使用enum()結(jié)果集的方式。tinyint作為開關(guān)字段時(shí),通常1為打開;0為關(guān)閉;-1為特殊數(shù)據(jù),例如N/A(不可用);高于1的為特殊結(jié)果或開關(guān)二進(jìn)制數(shù)組合(詳見phpcms中相關(guān)代碼);MEMORY/HEAP類型的表中,要尤其注意規(guī)劃節(jié)約使用存儲(chǔ)空間,這將節(jié)
29、約更多內(nèi)存。例如cdb_sessions表中,就將IP地址的存儲(chǔ)拆分為4個(gè)tinyint(3) UNSIGNED類型的字段,而沒有采用char(15)的方式;任何類型的數(shù)據(jù)表,字段空間應(yīng)當(dāng)本著足夠用,不浪費(fèi)的原則,數(shù)值類型的字段取值范圍見下表:字段類型 存儲(chǔ)空間(b) UNSIGNED 取值范圍tinyint 1 否 -128127是 0255smallint 2 否 -3276832767是 065535mediumint 3 否 -83886088388607是 016777215int 4 否 -21474836482147483647是 04294967295bigint 8 否 -9
30、223372892233727是 0184467445 5.2.SQL語句所有SQL語句中,除了表名、字段名稱以外,全部語句和函數(shù)均需大寫,應(yīng)當(dāng)杜絕小寫方式或大小寫混雜的寫法。例如select * from phpcms_member;是不符合規(guī)范的寫法。很長(zhǎng)的SQL語句應(yīng)當(dāng)有適當(dāng)?shù)臄嘈?,依?jù)JOIN、FROM、ORDER BY等關(guān)鍵字進(jìn)行界定。通常情況下,在對(duì)多表進(jìn)行操作時(shí),要根據(jù)不同表名稱,對(duì)每個(gè)表指定一個(gè)12個(gè)字母的縮寫,以利于語句簡(jiǎn)潔和可讀性。如下的語句范例,是符合規(guī)范的:$result = $db->query(”SELECT m.*, i.*FROM “.TABLE_MEMB
31、ER.” m, “.TABLE_MEMBERINFO.” iWHERE m.userid=i.userid AND m.userid=$_userid); 5.3.性能與效率5.3.1. 定長(zhǎng)與變長(zhǎng)表包含任何varchar、text等變長(zhǎng)字段的數(shù)據(jù)表,即為變長(zhǎng)表,反之則為定長(zhǎng)表。l 對(duì)于變長(zhǎng)表,由于記錄大小不同,在其上進(jìn)行許多刪除和更改將會(huì)使表中的碎片更多。需要定期運(yùn)行OPTIMIZE TABLE以保持性能。而定長(zhǎng)表就沒有這個(gè)問題;l 如果表中有可變長(zhǎng)的字段,將它們轉(zhuǎn)換為定長(zhǎng)字段能夠改進(jìn)性能,因?yàn)槎ㄩL(zhǎng)記錄易于處理。但在試圖這樣做之前,應(yīng)該考慮下列問題:l 使用定長(zhǎng)列涉及某種折衷。它們更快,但占
32、用的空間更多。char(n) 類型列的每個(gè)值總要占用n 個(gè)字節(jié)(即使空串也是如此),因?yàn)樵诒碇写鎯?chǔ)時(shí),值的長(zhǎng)度不夠?qū)⒃谟疫呇a(bǔ)空格;l 而varchar(n)類型的列所占空間較少,因?yàn)橹唤o它們分配存儲(chǔ)每個(gè)值所需要的空間,每個(gè)值再加一個(gè)字節(jié)用于記錄其長(zhǎng)度。因此,如果在char和varchar類型之間進(jìn)行選擇,需要對(duì)時(shí)間與空間作出折衷;l 變長(zhǎng)表到定長(zhǎng)表的轉(zhuǎn)換,不能只轉(zhuǎn)換一個(gè)可變長(zhǎng)字段,必須對(duì)它們?nèi)窟M(jìn)行轉(zhuǎn)換。而且必須使用一個(gè)ALTER TABLE語句同時(shí)全部轉(zhuǎn)換,否則轉(zhuǎn)換將不起作用;l 有時(shí)不能使用定長(zhǎng)類型,即使想這樣做也不行。例如對(duì)于比255字符更長(zhǎng)的串,沒有定長(zhǎng)類型;l 在設(shè)計(jì)表結(jié)構(gòu)時(shí)如果能夠
33、使用定長(zhǎng)數(shù)據(jù)類型盡量用定長(zhǎng)的,因?yàn)槎ㄩL(zhǎng)表的查詢、檢索、更新速度都很快。必要時(shí)可以把部分關(guān)鍵的、承擔(dān)頻繁訪問的表拆分,例如定長(zhǎng)數(shù)據(jù)一個(gè)表,非定長(zhǎng)數(shù)據(jù)一個(gè)表。例如phpcms的phpcms_member表等。因此規(guī)劃數(shù)據(jù)結(jié)構(gòu)時(shí)需要進(jìn)行全局考慮;進(jìn)行表結(jié)構(gòu)設(shè)計(jì)時(shí),應(yīng)當(dāng)做到恰到好處,反復(fù)推敲,從而實(shí)現(xiàn)最優(yōu)的數(shù)據(jù)存儲(chǔ)體系。5.3.2. 運(yùn)算與檢索數(shù)值運(yùn)算一般比字符串運(yùn)算更快。例如比較運(yùn)算,可在單一運(yùn)算中對(duì)數(shù)進(jìn)行比較。而串運(yùn)算涉及幾個(gè)逐字節(jié)的比較,如果串更長(zhǎng)的話,這種比較還要多。如果串列的值數(shù)目有限,應(yīng)該利用普通整型或emum類型來獲得數(shù)值運(yùn)算的優(yōu)越性。更小的字段類型永遠(yuǎn)比更大的字段類型處理要快得多。對(duì)于
34、字符串,其處理時(shí)間與串長(zhǎng)度直接相關(guān)。一般情況下,較小的表處理更快。對(duì)于定長(zhǎng)表,應(yīng)該選擇最小的類型,只要能存儲(chǔ)所需范圍的值即可。例如,如果mediumint夠用,就不要選擇bigint。對(duì)于可變長(zhǎng)類型,也仍然能夠節(jié)省空間。一個(gè)TEXT 類型的值用2 字節(jié)記錄值的長(zhǎng)度,而一個(gè)LONGTEXT 則用4字節(jié)記錄其值的長(zhǎng)度。如果存儲(chǔ)的值長(zhǎng)度永遠(yuǎn)不會(huì)超過64KB,使用TEXT 將使每個(gè)值節(jié)省2字節(jié)。5.3.3. 結(jié)構(gòu)優(yōu)化與索引優(yōu)化索引能加快查詢速度,而索引優(yōu)化和查詢優(yōu)化是相輔相成的,既可以依據(jù)查詢對(duì)索引進(jìn)行優(yōu)化,也可以依據(jù)現(xiàn)有索引對(duì)查詢進(jìn)行優(yōu)化,這取決于修改查詢或索引,哪個(gè)對(duì)現(xiàn)有產(chǎn)品架構(gòu)和效率的影響最小。
35、索引優(yōu)化與查詢優(yōu)化是多年經(jīng)驗(yàn)積累的結(jié)晶,在此無法詳述,但仍然給出幾條最基本的準(zhǔn)則。首先,根據(jù)產(chǎn)品的實(shí)際運(yùn)行和被訪問情況,找出哪些SQL語句是最常被執(zhí)行的。最常被執(zhí)行和最常出現(xiàn)在程序中是完全不同的概念。最常被執(zhí)行的SQL語句,又可被劃分為對(duì)大表(數(shù)據(jù)條目多的)和對(duì)小表(數(shù)據(jù)條目少的)的操作。無論大表或小表,有可分為讀(SELECT)多、寫(UPDATE/INSERT)多或讀寫都多的操作。對(duì)常被執(zhí)行的SQL語句而言,對(duì)大表操作需要尤其注意:l 寫操作多的,通??墒褂脤懭刖彺娴姆椒ǎ葘⑿枰獙懟蛐枰碌臄?shù)據(jù)緩存至文件或其他表,定期對(duì)大表進(jìn)行批量寫操作。同時(shí),應(yīng)盡量使得常被讀寫的大表為定長(zhǎng)類型,即便
36、原本的結(jié)構(gòu)中大表并非定長(zhǎng)。大表定長(zhǎng)化,可以通過改變數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)和數(shù)據(jù)讀取方式,將一個(gè)大表拆成一個(gè)讀寫多的定長(zhǎng)表,和一個(gè)讀多寫少的變長(zhǎng)表來實(shí)現(xiàn);l 讀操作多的,需要依據(jù)SQL查詢頻率設(shè)置專門針對(duì)高頻SQL語句的索引和聯(lián)合索引。而小表就相對(duì)簡(jiǎn)單,加入符合查詢要求的特定索引,通常效果比較明顯。同時(shí),定長(zhǎng)化小表也有益于效率和負(fù)載能力的提高。字段比較少的小定長(zhǎng)表,甚至可以不需要索引。其次,看SQL語句的條件和排序字段是否動(dòng)態(tài)性很高(即根據(jù)不同功能開關(guān)或?qū)傩?,SQL查詢條件和排序字段的變化很大的情況),動(dòng)態(tài)性過高的SQL語句是無法通過索引進(jìn)行優(yōu)化的。惟一的辦法只有將數(shù)據(jù)緩存起來,定期更新,適用于結(jié)果對(duì)實(shí)效
37、性要求不高的場(chǎng)合。MySQL索引,常用的有PRIMARY KEY、INDEX、UNIQUE幾種,詳情請(qǐng)查閱MySQL文檔。通常,在單表數(shù)據(jù)值不重復(fù)的情況下,PRIMARY KEY和UNIQUE索引比INDEX更快,請(qǐng)酌情使用。事實(shí)上,索引是將條件查詢、排序的讀操作資源消耗,分布到了寫操作中,索引越多,耗費(fèi)磁盤空間越大,寫操作越慢。因此,索引決不能盲目添加。對(duì)字段索引與否,最根本的出發(fā)點(diǎn),依次仍然是SQL語句執(zhí)行的概率、表的大小和寫操作的頻繁程度。5.3.4. 查詢優(yōu)化MySQL中并沒有提供針對(duì)查詢條件的優(yōu)化功能,因此需要開發(fā)者在程序中對(duì)查詢條件的先后順序人工進(jìn)行優(yōu)化。例如如下的SQL語句:SE
38、LECT * FROM table WHERE a>0 AND b<1 ORDER BY c LIMIT 10; 事實(shí)上無論a>0還是b<1哪個(gè)條件在前,得到的結(jié)果都是一樣的,但查詢速度就大不相同,尤其在對(duì)大表進(jìn)行操作時(shí)。開發(fā)者需要牢記這個(gè)原則:最先出現(xiàn)的條件,一定是過濾和排除掉更多結(jié)果的條件;第二出現(xiàn)的次之;以此類推。因而,表中不同字段的值的分布,對(duì)查詢速度有著很大影響。而ORDER BY中的條件,只與索引有關(guān),與條件順序無關(guān)。除了條件順序優(yōu)化以外,針對(duì)固定或相對(duì)固定的SQL查詢語句,還可以通過對(duì)索引結(jié)構(gòu)進(jìn)行優(yōu)化,進(jìn)而實(shí)現(xiàn)相當(dāng)高的查詢速度。原則是:在大多數(shù)情況下,根據(jù)
39、WHERE條件的先后順序和ORDER BY的排序字段的先后順序而建立的聯(lián)合索引,就是與這條SQL語句匹配的最優(yōu)索引結(jié)構(gòu)。盡管,事實(shí)的產(chǎn)品中不能只考慮一條SQL語句,也不能不考慮空間占用而建立太多的索引。同樣以上面的SQL語句為例,最優(yōu)的當(dāng)table表的記錄達(dá)到百萬甚至千萬級(jí)后,可以明顯的看到索引優(yōu)化帶來的速度提升。依據(jù)上面條件優(yōu)化和索引優(yōu)化的兩個(gè)原則,當(dāng)table表的值為如下方案時(shí),可以得出最優(yōu)的條件順序方案:字段a 字段b 字段c1 7 112 8 103 9 13-1 0 12最優(yōu)條件:b<1 AND a>0最優(yōu)索引:INDEX abc (b, a, c)原因:b<1作為
40、第一條件可以先過濾掉75%的結(jié)果。如果以a>0作為第一條件,則只能先過濾掉25%的結(jié)果注意1:字段c由于未出現(xiàn)于條件中,故條件順序優(yōu)化與其無關(guān)注意2:最優(yōu)索引由最優(yōu)條件順序得來,而非由例子中的SQL語句得來注意3:索引并非修改數(shù)據(jù)存儲(chǔ)的物理順序,而是通過對(duì)應(yīng)特定偏移量的物理數(shù)據(jù)而實(shí)現(xiàn)的虛擬指針 EXPLAIN語句是檢測(cè)索引和查詢能否良好匹配的簡(jiǎn)便方法。在phpMyAdmin或其他MySQL客戶端中運(yùn)行EXPLAIN+查詢語句,例如EXPLAIN select * FROM table WHERE a>0 AND b<1 ORDER BY c;這種形式,即使得開發(fā)者無需模擬上百
41、萬條數(shù)據(jù),也可以驗(yàn)證索引是否合理,相關(guān)細(xì)節(jié)請(qǐng)參考MySQL說明。值得提出的是,Using 是最不應(yīng)當(dāng)出現(xiàn)的情況,如果EXPLAIN得出此結(jié)果,說明數(shù)據(jù)庫為這個(gè)查詢專門建立了一個(gè)用以緩存結(jié)果的臨時(shí)表文件,并在查詢結(jié)束后刪除。眾所周知,硬盤I/O速度始終是計(jì)算機(jī)存儲(chǔ)的瓶頸,因此,查詢中應(yīng)當(dāng)盡全力避免高執(zhí)行頻率的SQL語句使用。盡管,開發(fā)者永遠(yuǎn)都不可能保證產(chǎn)品中的全部SQL語句都不會(huì)使用。限于篇幅,本文檔遠(yuǎn)遠(yuǎn)沒有涵蓋數(shù)據(jù)庫優(yōu)化的方方面面,例如:聯(lián)合索引與普通索引的可重用性、JOIN連接的索引設(shè)計(jì)、MEMORY/HEAP表等。數(shù)據(jù)庫優(yōu)化實(shí)際上就是在很多因素和利弊間不斷權(quán)衡、修改,惟有在成功與失敗經(jīng)驗(yàn)中
42、反復(fù)推敲才能得出的經(jīng)驗(yàn),這種經(jīng)驗(yàn)往往就是最難能可貴和價(jià)值連城的。5.3.5. 兼容性問題由于MySQL 3.23至5.0的變化很大,因此程序中盡量不使用特殊的SQL語句,以免帶來兼容性問題,并給數(shù)據(jù)庫移植造成困難。通常在MySQL 4.1以上版本,phpcms應(yīng)使用相當(dāng)?shù)淖址瘉泶鎯?chǔ),例如GBK/BIG5/UTF-8。傳統(tǒng)的latin1編碼雖然有一定的兼容性,但仍然不是推薦的選擇。使用相應(yīng)非默認(rèn)字符集時(shí),程序每次運(yùn)行時(shí)需要使用SET NAMES character_set;來規(guī)定連接、傳輸和結(jié)果的字符集。Mysql 5.0以上新增了數(shù)種SQL_MODE,默認(rèn)的SQL_MODE依服務(wù)器安裝設(shè)置不
43、同而不同,因此程序每次運(yùn)行時(shí)需要使用SET SQL_MODE=;來規(guī)定當(dāng)前的SQL模式。6. 模板設(shè)計(jì)6.1.代碼標(biāo)記HTML代碼標(biāo)記一律采用小寫字母形式,杜絕任何使用大寫字母的方式模板中所有的邏輯體,如if、loop等,必須前后使用HTML注釋(<!- ->),即類似<!-if expr->的形式。事實(shí)上,phpcms模板編譯器是支持不加HTML注釋的邏輯體寫法的,但加入注釋可以使得模板可讀性更好,同時(shí)方便用戶使用DreamWeaver或FrontPage等對(duì)模板進(jìn)行修改。6.2.書寫規(guī)則6.2.1. HTML所有HTML標(biāo)記參數(shù)賦值需使用雙引號(hào)包含,例如,應(yīng)當(dāng)使用
44、<input type=”text” name=”test” value=”ok”>而絕對(duì)不能使用 <input type=text name=test value=ok>。在任何情況下,產(chǎn)品中的模板文件必須采用手寫HTML代碼的方式,而絕對(duì)不能使用DreamWeaver、FrontPage等自動(dòng)網(wǎng)頁制作工具進(jìn)行撰寫或修改。6.2.2. 變量模板中使用的變量,依據(jù)作用和出現(xiàn)位置不同,分為幾種方式:l 邏輯體中,即被包圍起來的部分,例如這種形式,其中的變量書寫規(guī)范與PHP程序中完全一致;開發(fā)者需要使用將變量括起來,以免出現(xiàn)模板編譯錯(cuò)誤,可能的情況如下:l 變量前后含有中括號(hào)的或其他敏感字符的(包括但不限于“$”、
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 服務(wù)合同:自費(fèi)出國留學(xué)中介服務(wù)委托合同6篇
- 2025年福建貨運(yùn)從業(yè)資格證科目一模擬考試題庫
- 2025年唐山貨運(yùn)從業(yè)資格證網(wǎng)上考試答案
- 2025年資陽貨運(yùn)員初級(jí)考試題庫
- 建筑勞務(wù)施工合同
- 勞務(wù)外包安全管理協(xié)議
- 涂料助劑:流平劑產(chǎn)業(yè)分析報(bào)告
- 廠房施工標(biāo)準(zhǔn)合同范例
- 臺(tái)面加工承攬合同范本
- 債權(quán)收益權(quán)轉(zhuǎn)讓合同范本
- 2023年山東藥品食品職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)考試筆試題庫及答案解析
- 《工程化學(xué)》全套教學(xué)課件
- 4.1比的意義 導(dǎo)學(xué)案 2022-2023學(xué)年六年級(jí)數(shù)學(xué)上冊(cè)-人教版(含答案)
- 美容手術(shù)的麻醉精品課件
- 蔬菜生產(chǎn)技術(shù)實(shí)踐教學(xué)大綱
- 施耐德APC1-20K不間斷電源內(nèi)部培訓(xùn)(ppt可編輯修改)課件
- 看圖寫話我是乖孩子
- 油管、套管等規(guī)格對(duì)照表
- IEST-RP-CC0053
- 模糊邏輯與模糊推理
- 玉米收割機(jī)的設(shè)計(jì)(機(jī)械CAD圖紙)
評(píng)論
0/150
提交評(píng)論