- Web開發(fā)的平民英雄:PHP+MySQL
- 丁月華 王鈞玉 孫更新等編著
- 16810字
- 2018-12-27 18:50:28
1.4 PHP語(yǔ)言基礎(chǔ)
作為一種編程語(yǔ)言,PHP和大部分語(yǔ)言一樣,都有著相同的一些語(yǔ)法規(guī)則,但也有一些屬于PHP本身特有的語(yǔ)法。PHP的語(yǔ)法規(guī)定很多,可以用詳細(xì)的一章來(lái)介紹,在這里,我們只簡(jiǎn)要介紹如下。
1.4.1 PHP基本語(yǔ)法
1. 注釋
在PHP的程序中,加入注釋的方法很靈活??梢允褂肅語(yǔ)言、C++語(yǔ)言或者是UNIX的Shell語(yǔ)言的注釋方式,你可以使用塊注釋,單行注釋,你也可以使用多行注釋和文檔注釋,更方便的是,你也可以混合使用。
常用的注釋符號(hào)有單行注釋//用于注釋一行;塊注釋符號(hào)/*和*/注釋掉中間的多行語(yǔ)句。
2. 命名規(guī)則
在PHP命名中,遵循一定的命名規(guī)則,對(duì)于提高代碼的可讀性是非常重要的。
在給變量命名的時(shí)候,除了變量名外,所有實(shí)例,包括類,類常量,均采用大小寫混合的方式,第一個(gè)單詞的首字母小寫,其后單詞的首字母大寫。盡管在語(yǔ)法上使用下畫線或美元符號(hào)開頭命名是允許的,但是,我們?cè)趯?shí)際應(yīng)用中應(yīng)該盡量避免這種命名方法。
變量名應(yīng)簡(jiǎn)短且富于描述。變量名的選用應(yīng)該易于記憶,即能夠指出其用途。盡量避免單個(gè)字符的變量名,除非是一次性的臨時(shí)變量。
3. 數(shù)據(jù)類型
PHP數(shù)據(jù)類型是具有相同特性的一組數(shù)據(jù)的統(tǒng)稱。
PHP支持8種原始類型,其中標(biāo)量類型4種,符合類型兩種,特殊類型兩種。常見的數(shù)據(jù)類型包括字符串型、整型、浮點(diǎn)型和布爾型。
(1) 布爾型(Boolean)類型最初出現(xiàn)在PHP4中,布爾型類型是表示條件是真(非0)還是假(0)的數(shù)據(jù)類型。
PHP的數(shù)據(jù)類型屬于弱類型,PHP的變量在使用的時(shí)候可以根據(jù)具體情況自動(dòng)轉(zhuǎn)換成所需要的變量類型,布爾型的變量決定了條件語(yǔ)句的結(jié)果, 通常我們使用某些運(yùn)算符返回Boolean值,并將其傳遞給控制流程。
(2) 字符串是由一系列的字符序列組成的。無(wú)論哪種語(yǔ)言,字符串操作都是一個(gè)重要的基礎(chǔ),往往是最簡(jiǎn)單的,但是卻是最重要的。
(3) 整型是PHP中很常用的一個(gè)數(shù)據(jù)類型。它的取值范圍是這樣一個(gè)集合:Z={…-2,-1,0,1,2…},整型除作為必要的運(yùn)算數(shù)據(jù)外,整型值還經(jīng)常用于循環(huán)控制變量等處。
(4) 浮點(diǎn)型通常是指我們說(shuō)的實(shí)數(shù),它是用十進(jìn)制數(shù)字表示數(shù)字值,它的取值范圍取決于具體的機(jī)器,PHP浮點(diǎn)型與C編譯器的雙精度數(shù)據(jù)類型范圍相同,通常允許的取值范圍是1.7E-308和1.7E+308之間,精確到15位數(shù)字。
(5) 數(shù)組實(shí)際上是一個(gè)數(shù)據(jù)集合,相當(dāng)于是一個(gè)數(shù)據(jù)容器,很多數(shù)據(jù)存放在里面,我們可以按一定方法存進(jìn)去或取出來(lái),還可以對(duì)它里面的數(shù)據(jù)進(jìn)行排序等各種操作,還可以檢查里面有沒(méi)有我們想要的數(shù)據(jù)等。
4. 運(yùn)算符和關(guān)鍵字
運(yùn)算符是指可以通過(guò)給出的一個(gè)或多個(gè)值來(lái)產(chǎn)生另一個(gè)值的符號(hào)。
PHP提供三種類型的運(yùn)算符。
第一種是一元運(yùn)算符,只運(yùn)算一個(gè)值,例如 !(取反運(yùn)算符)或 ++(加一運(yùn)算符)。
第二種是有限二元運(yùn)算符,PHP支持的大多數(shù)運(yùn)算符都是這種。
第三種是三元運(yùn)算符:?:。它被用來(lái)根據(jù)一個(gè)表達(dá)式的不同取值而在另兩個(gè)表達(dá)式中選擇一個(gè)。
(1) 算術(shù)運(yùn)算符
算術(shù)運(yùn)算符如表1-3所示。
表1-3 PHP的算術(shù)運(yùn)算符

(2) 字符串運(yùn)算符
在PHP中,應(yīng)用與字符串的運(yùn)算符有兩個(gè):
第一個(gè)是連接運(yùn)算符(“.”),它返回其左右參數(shù)連接后的字符串。
第二個(gè)是連接賦值運(yùn)算符(“.=”),它將右邊參數(shù)附加到左邊的參數(shù)后。
(3) 賦值運(yùn)算符
PHP基本的賦值運(yùn)算符是“=”。它并不是“等于”的意思,而是把右邊表達(dá)式的值賦給左邊的變量。
(4) 比較運(yùn)算符
比較運(yùn)算符是用來(lái)比較兩個(gè)值的操作符,比較運(yùn)算符的表達(dá)式根據(jù)比較結(jié)果返回布爾型變量值:true或者false。比較運(yùn)算符如表1-4所示。
表1-4 PHP的比較運(yùn)算符

(5) 邏輯運(yùn)算符
邏輯運(yùn)算(logical operators)通常用來(lái)測(cè)試真值或假值的。邏輯運(yùn)算符如表1-5所示。
表1-5 PHP的邏輯運(yùn)算符

(6) 位運(yùn)算符
位運(yùn)算符可以將一個(gè)整型變量當(dāng)做一系列的位來(lái)處理,在PHP中,位運(yùn)算符可能并不經(jīng)常使用。位運(yùn)算符如表1-6所示。
表1-6 PHP的位運(yùn)算符

(7) 自增與自減運(yùn)算符
在PHP中自增與自減運(yùn)算符表示為:++和--。自增與自減運(yùn)算符如表1-7所示。
表1-7 PHP的自增與自減運(yùn)算符

(8) 關(guān)鍵字
關(guān)鍵字(keyword)是語(yǔ)言為其核心功能而保留的單詞。在對(duì)變量、函數(shù)、類和常量進(jìn)行命名時(shí),不能使用與關(guān)鍵字一樣的名字,關(guān)鍵字是區(qū)分大小寫的,如表1-8所示。
表1-8 PHP的保留關(guān)鍵字

5. 條件分支語(yǔ)句
條件語(yǔ)句是為能使應(yīng)用程序在運(yùn)行時(shí)根據(jù)不同的條件來(lái)執(zhí)行不同的程序塊而設(shè)置的,在PHP中,支持if和switch兩種條件語(yǔ)句。
(1) if語(yǔ)句
在PHP中,if語(yǔ)句是最常用的條件語(yǔ)句之一,同時(shí),if語(yǔ)句也是大多數(shù)程序開發(fā)語(yǔ)言中存在的條件語(yǔ)句。if條件語(yǔ)句的語(yǔ)法如下:
<?php if (表達(dá)式){ 語(yǔ)句塊 }elseif (表達(dá)式){ 語(yǔ)句塊 }elseif (表達(dá)式){ 語(yǔ)句塊 ... }else{ 語(yǔ)句塊 } ?>
if條件語(yǔ)句的表達(dá)式是一個(gè)返回值為布爾類型的表達(dá)式,如果表達(dá)式返回的值為true,那么在接下來(lái)的語(yǔ)句塊將被執(zhí)行,否則,程序?qū)⑻^(guò)下面的語(yǔ)句塊,繼續(xù)往下執(zhí)行。在上述的if條件語(yǔ)句的語(yǔ)法中,我們可以加入else語(yǔ)句,當(dāng)以前表達(dá)式的返回值都不為true時(shí),else語(yǔ)句塊中的語(yǔ)句將被執(zhí)行。
(2)switch語(yǔ)句
switch語(yǔ)句是PHP中另外一種條件判斷語(yǔ)句。Switch條件分支語(yǔ)句簡(jiǎn)化了使用if語(yǔ)句進(jìn)行的多重嵌套判斷。在編寫條件比較復(fù)雜的程序時(shí),如果使用較多的if語(yǔ)句,那么會(huì)使語(yǔ)句間的邏輯關(guān)系變得十分復(fù)雜,同時(shí)也會(huì)增加程序調(diào)試和維護(hù)的難度。switch語(yǔ)句提供了一個(gè)可讀性更好的多重if嵌套的解決方案。
switch條件分支語(yǔ)句也稱情況語(yǔ)句,其功能是從多個(gè)待選擇符的條件中選擇一個(gè)符合條件的語(yǔ)句,switch語(yǔ)句的基本語(yǔ)法如下:
<?php switch (條件表達(dá)式){ case 條件1: 語(yǔ)句塊 break; case條件2: 語(yǔ)句塊 ... break; default: 語(yǔ)句塊 } ?>
6. 循環(huán)
PHP中的循環(huán)有for循環(huán)、while循環(huán)、do…while循環(huán)、foreach循環(huán)四種。
(1) for循環(huán)
for循環(huán)是經(jīng)常能夠使用到的循環(huán)語(yǔ)句,for循環(huán)可以確定循環(huán)的次數(shù),在使用for循環(huán)的時(shí)候首先要為循環(huán)變量設(shè)置一個(gè)初始值和一個(gè)終值,循環(huán)變量可以是任意合法的表識(shí)符,循環(huán)變量的類型可以是整型、布爾型、字符類型等。
for循環(huán)的的基本語(yǔ)法如下:
<?php for(循環(huán)變量初始值;循環(huán)條件;計(jì)數(shù)器){ 循環(huán)體 } ?>
for循環(huán)的3個(gè)參數(shù)含義如下。
循環(huán)變量初始值:顧名思義,就是從for循環(huán)的哪個(gè)值開始循環(huán)。
循環(huán)條件:當(dāng)滿足什么條件時(shí)繼續(xù)循環(huán)。
計(jì)數(shù)器:就是沒(méi)執(zhí)行完一次循環(huán)以后,對(duì)循環(huán)變量按怎么樣的方式進(jìn)行記數(shù)。
在使用for循環(huán)的時(shí)候應(yīng)該注意以下幾點(diǎn)。
① 循環(huán)體中的語(yǔ)句可以是簡(jiǎn)單語(yǔ)句也可以是符合語(yǔ)句。
② 循環(huán)變量必須是有序數(shù)據(jù)類型的變量。
③ 不允許任何語(yǔ)句在循環(huán)體中改變循環(huán)變量的值。
為了理解for循環(huán)的循環(huán)流程,我們使用下圖來(lái)描述for循環(huán)的循環(huán)結(jié)構(gòu)。
根據(jù)計(jì)數(shù)器的不同計(jì)數(shù)方式,我們可以將for循環(huán)分為遞增循環(huán)和遞減循環(huán)。
(2)while循環(huán)
while循環(huán)語(yǔ)句又稱當(dāng)行循環(huán)語(yǔ)句,即“當(dāng)……是”循環(huán)執(zhí)行循環(huán)體。該語(yǔ)句的執(zhí)行過(guò)程是先判斷while后的布爾表達(dá)式,然后再執(zhí)行,while語(yǔ)句是當(dāng)條件語(yǔ)句的表達(dá)式的值為true時(shí),執(zhí)行其中的循環(huán)體,直到條件表達(dá)式的值為false時(shí)才退出循環(huán)。
while循環(huán)的基本語(yǔ)法如下:
while(條件表達(dá)式){ 循環(huán)體 }
while循環(huán)的流程圖如圖1-26所示。

圖1-25 for循環(huán)流程圖

圖1-26 while循環(huán)流程圖
程序從條件表達(dá)式進(jìn)入循環(huán)體語(yǔ)句,如果條件表達(dá)式的值為true,那么繼續(xù)循環(huán),直到條件表達(dá)式的值為false時(shí)退出循環(huán)。
(3)do…while循環(huán)
do…while循環(huán)也是PHP中經(jīng)常用到的循環(huán)語(yǔ)句,該語(yǔ)句不同于while循環(huán),while循環(huán)在執(zhí)行循環(huán)體之前,先判斷循環(huán)條件是不是成立,如果成立,則執(zhí)行循環(huán)體,并且進(jìn)行計(jì)數(shù),如果循環(huán)條件不成立,則跳出循環(huán),不執(zhí)行循環(huán)體;而do…while循環(huán)語(yǔ)句則不同,do…while循環(huán)至少執(zhí)行一次循環(huán)體,然后再判斷循環(huán)條件是否成立,若循環(huán)條件成立,則返回繼續(xù)執(zhí)行循環(huán)體,否則,跳出循環(huán)。do…while循環(huán)語(yǔ)句的基本語(yǔ)法如下:
<?php do{ 循環(huán)體 }while(條件語(yǔ)句) ?>
它的循環(huán)結(jié)構(gòu)我們可以用圖1-27來(lái)表示。

圖1-27 do…while循環(huán)結(jié)構(gòu)
從do…while的循環(huán)結(jié)構(gòu)可以看出,其循環(huán)條件放在循環(huán)體的后面來(lái)判斷,也就是說(shuō), do…while循環(huán)先執(zhí)行一次循環(huán)體,然后再判斷循環(huán)條件是否成立來(lái)決定是否繼續(xù)執(zhí)行循環(huán)體。
(4)foreach循環(huán)
foreach循環(huán)結(jié)構(gòu)是在PHP4中引入的,并且foreach循環(huán)只能用于循環(huán)訪問(wèn)數(shù)組的元素,自PHP5開始,foreach循環(huán)還可以遍歷對(duì)象,本節(jié)只介紹它在數(shù)組循環(huán)中的使用方法。
在使用foreach循環(huán)遍歷數(shù)組之前,必須先對(duì)要遍歷的數(shù)組進(jìn)行初始化,否則,PHP會(huì)產(chǎn)生錯(cuò)誤。
foreach循環(huán)的的語(yǔ)法可以分為兩種情況來(lái)寫,第一種情況語(yǔ)法如下:
<?php foreach (array_expression as $value){ 循環(huán)體 } ?>
這種格式的語(yǔ)法將遍歷給定的array_expression數(shù)組。在每次循環(huán)中,當(dāng)前單元的值被賦給$value,并且數(shù)組內(nèi)部的指針向前移一步,以便于在下次循環(huán)中能夠取到下一個(gè)單元的數(shù)值。
foreach循環(huán)的第二種語(yǔ)法如下:
<?php foreach (array_expression as $key => $value){ 循環(huán)體 } ?>
這種語(yǔ)法與第一種相比,它將一個(gè)數(shù)組元素分解為$key和$value兩個(gè)部分,$key是數(shù)組的索引,$value是這個(gè)索引的值,它們的名字可以隨意。
(5)continue與break在循環(huán)中的應(yīng)用
continue在循環(huán)結(jié)構(gòu)中用來(lái)跳過(guò)本次循環(huán)中剩余的代碼,并在判斷條件值為真時(shí)開始執(zhí)行下一次循環(huán)。 continue接受一個(gè)可選的數(shù)字參數(shù)來(lái)決定跳過(guò)幾重循環(huán)到循環(huán)結(jié)尾,而break則直接跳出本循環(huán),繼續(xù)執(zhí)行循環(huán)以外的程序。
1.4.2 字符串和正則表達(dá)式
1. 字符串
一個(gè)字母、一個(gè)數(shù)字、一個(gè)標(biāo)點(diǎn),這些組成豐富語(yǔ)言的基本元素,我們稱之為一個(gè)“字符”,在以二進(jìn)制模式工作的計(jì)算機(jī)中,每一個(gè)字符都用一個(gè)代碼來(lái)表示,這種代碼叫做ASCII碼,如ASCII碼65就代表大寫字母A,美國(guó)國(guó)家標(biāo)準(zhǔn)學(xué)會(huì)(American National Standard Institute, ANSI)制定了可見和不可見(如:Enter、退格等控制字符)的共127字符。
零個(gè)或者多個(gè)字符組成的有限序列,也就是n(n≧0)個(gè)字符的集合,就叫做字符串。一個(gè)字符串,可以是我們看起來(lái)有意義的一個(gè)單詞、一句話、一篇文章,也有可能是毫無(wú)意義的字符堆積。字符串最常用的功能是人機(jī)對(duì)話,告訴用戶發(fā)生了什么,以及下一步需要做什么。
在書寫上,字符串一般都寫在成對(duì)的單引號(hào)或者雙引號(hào)中。
一般來(lái)說(shuō),對(duì)字符串的操作有連接、分割成子串、求字符串長(zhǎng)度、兩個(gè)字符串比較、查找子串、替換字符串中間的部分子串等。
下面我們簡(jiǎn)要介紹一些常用的字符串操作函數(shù)。
函數(shù)語(yǔ)法:string chop ( string $str [, string $charlist] )。
函數(shù)作用:去除字符串尾部的空格等特殊字符,如果指定了第二個(gè)參數(shù),則去除字符串尾部的第二個(gè)參數(shù)指定的字符。
函數(shù)語(yǔ)法:string ltrim ( string $str [, string $charlist] )。
函數(shù)作用:去除字符串頭部的空格等特殊字符,如果指定了第二個(gè)參數(shù),則去除字符串頭部的第二個(gè)參數(shù)指定的字符。
函數(shù)語(yǔ)法:string trim ( string $str [, string $charlist] )。
函數(shù)作用:去除字符串頭部和尾部的空格等特殊字符,如果指定了第二個(gè)參數(shù),則去除字符串頭部和尾部的第二個(gè)參數(shù)指定的字符。
函數(shù)語(yǔ)法:string addslashes ( string str )
函數(shù)作用:使用反斜線引用字符串。
stripslashes()函數(shù)和addslashes()相反,是把被addslashes()函數(shù)加上的轉(zhuǎn)義符取消。
函數(shù)語(yǔ)法:string stripslashes ( string )
函數(shù)語(yǔ)法:string strtoupper ( string $string )
函數(shù)說(shuō)明:將字符串string的字母全部以大寫字母的形式返回。
函數(shù)語(yǔ)法:string strtolower ( string $string )
函數(shù)說(shuō)明:將字符串string的字母全部以小寫字母的形式返回。
函數(shù)語(yǔ)法:array explode ( string $separator, string $string [, int $limit] )
函數(shù)作用:將字符串$string用$separator來(lái)分割,每出現(xiàn)一次$separator,就多出一個(gè)兩個(gè)$separator之間的字符組成的字符串元素,函數(shù)最后返回值是一個(gè)數(shù)組。如果使用了第三個(gè)參數(shù)$limit,則函數(shù)返回的數(shù)組最多包含$limit個(gè)元素,剩余未被分割的字符串作為最后一個(gè)元素。函數(shù)實(shí)際使用時(shí),最常見的$separator是空格或者“||”、“,”。
函數(shù)語(yǔ)法:string implode ( string $glue, array $pieces )
函數(shù)作用:把數(shù)組的各元素合成成一個(gè)用$glue連接起來(lái)的字符串。
函數(shù)語(yǔ)法:string strtok ( string $str, string $token )
函數(shù)作用:字符串 $str用字符串 $token的值切開成小段小段的字符串,返回$token第一次出現(xiàn)前的部分子字符串,如果重復(fù)執(zhí)行該函數(shù),則不再需要$str參數(shù),將依次返回后續(xù)的下一個(gè)$token出現(xiàn)前的部分子字符串。
函數(shù)語(yǔ)法:string substr ( string $string, int $start [, int $length] )
函數(shù)作用:取得字符串$string從$start開始的$length長(zhǎng)度的子字符串,如果沒(méi)有$length參數(shù),則取到$string的最后一個(gè)字符。
$string字符串的各字符位置($start參數(shù))從0開始;如果$start參數(shù)為負(fù)數(shù),則從$string字符串倒數(shù)第$start個(gè)字符開始取得$length長(zhǎng)度的子字符串。
如果$length參數(shù)為負(fù)數(shù),則截取到$string字符串倒數(shù)第$length個(gè)字符為止。
函數(shù)語(yǔ)法:int strlen ( string $string )
函數(shù)說(shuō)明:返回字符串string的長(zhǎng)度。
函數(shù)語(yǔ)法:string strstr ( string $haystack, string $needle, bool $before_needle )
函數(shù)說(shuō)明:在字符串haystack中查找子字符串needle第一次出現(xiàn)的位置,并返回字符串haystack中從字符串needle開始到母字符串結(jié)束的部分。如果參數(shù)before_needle為true,則返回字符串haystack中從開始到字符串needle第一次出現(xiàn)位置之間的字符串。
如果字符串haystack中查找不到字符串needle,則返回false。
函數(shù)語(yǔ)法:string stristr ( string $haystack, string $needle, bool $before_needle )
函數(shù)說(shuō)明:同strstr(),不同之處為本函數(shù)不區(qū)分大小寫。
函數(shù)語(yǔ)法:string strrchr ( string $haystack, string $needle )
函數(shù)說(shuō)明:本函數(shù)用來(lái)尋找字符串haystack中的字符needle最后一次出現(xiàn)的位置,并返回此位置起至字符串haystack結(jié)束之間的字符串。若沒(méi)有找到needle則返回false。
函數(shù)語(yǔ)法:int strpos ( string $haystack, mixed $needle [, int $offset] )
函數(shù)說(shuō)明:尋找字符串haystack中的字符needle最先出現(xiàn)的位置。值得注意的是needle只能是一個(gè)字符,中文字等就不適合了。若找不到指定的字符,則返回false值。參數(shù)offset可省略,用來(lái)表示從offset位置處開始找。
函數(shù)語(yǔ)法:int strrpos ( string $haystack, string $needle [, int $offset] )
函數(shù)說(shuō)明:略同strpos(),不同之處是查找并返回needle最后一次出現(xiàn)的位置。
函數(shù)語(yǔ)法:mixed str_replace ( mixed $search, mixed $replace, mixed $subject [, int&$count] )
函數(shù)說(shuō)明:將字符串replace代入subject字符串中,將所有的search置換成replace。
函數(shù)語(yǔ)法:string md5 ( string $str [, bool $raw_output] )
函數(shù)說(shuō)明:返回字符串str的MD5散列值。
函數(shù)語(yǔ)法:string urlencode ( string $str )
函數(shù)說(shuō)明:將字符串str按照URL方式編碼,除了 -_. 之外的所有非字母數(shù)字字符都將被替換成百分號(hào)(%)后跟兩位十六進(jìn)制數(shù),空格則編碼為加號(hào)(+)。
函數(shù)語(yǔ)法:string urldecode ( string $str )
函數(shù)說(shuō)明:解碼給出的已編碼字符串中的任何 %##。返回解碼后的字符串。
函數(shù)語(yǔ)法:string base64_encode ( string $data )
函數(shù)說(shuō)明:返回使用base64對(duì)data進(jìn)行編碼。設(shè)計(jì)此種編碼是為了使二進(jìn)制數(shù)據(jù)可以通過(guò)非純8-bit的傳輸層傳輸,例如電子郵件的主體。Base64-encoded數(shù)據(jù)要比原始數(shù)據(jù)多占用33%左右的空間。
函數(shù)語(yǔ)法:string base64_decode ( string $encoded_data )
函數(shù)說(shuō)明:將encoded_data進(jìn)行解碼,返回原始數(shù)據(jù),失敗則返回FALSE。
2. 正則表達(dá)式
正則表達(dá)式是一種可以用于模式匹配和替換的強(qiáng)有力的工具。正則表達(dá)式可以讓用戶通過(guò)使用一系列的特殊字符構(gòu)建匹配模式,然后把匹配模式與數(shù)據(jù)文件、程序輸入以及Web頁(yè)面的表單輸入等目標(biāo)對(duì)象進(jìn)行比較,根據(jù)比較對(duì)象中是否包含匹配模式,執(zhí)行相應(yīng)的程序。
正則表達(dá)式的“祖先”可以一直上溯至對(duì)人類神經(jīng)系統(tǒng)如何工作的早期研究。Warren McCulloch和Walter Pitts這兩位神經(jīng)生理學(xué)家研究出一種數(shù)學(xué)方式來(lái)描述這些神經(jīng)網(wǎng)絡(luò)。
1956年,一位叫Stephen Kleene的數(shù)學(xué)家在McCulloch和Pitts早期工作的基礎(chǔ)上,發(fā)表了一篇標(biāo)題為“神經(jīng)網(wǎng)事件的表示法”的論文,引入了正則表達(dá)式的概念。正則表達(dá)式就是用來(lái)描述他稱為“正則集的代數(shù)”的表達(dá)式,因此采用“正則表達(dá)式”這個(gè)術(shù)語(yǔ)。
隨后,發(fā)現(xiàn)可以將這一工作應(yīng)用于使用Ken Thompson的計(jì)算搜索算法的一些早期研究,Ken Thompson是UNIX的主要發(fā)明人。正則表達(dá)式的第一個(gè)實(shí)用應(yīng)用程序就是UNIX中的qed編輯器。
目前,正則表達(dá)式已經(jīng)在很多軟件中得到廣泛的應(yīng)用,包括*nix(Linux,UNIX等),HP等操作系統(tǒng),PHP,C#,Java等開發(fā)環(huán)境,以及很多的應(yīng)用軟件中,都可以看到正則表達(dá)式的影子。
正則表達(dá)式的使用,可以通過(guò)簡(jiǎn)單的辦法來(lái)實(shí)現(xiàn)強(qiáng)大的功能。為了簡(jiǎn)單有效而又不失強(qiáng)大,造成了正則表達(dá)式代碼的難度較大,學(xué)習(xí)起來(lái)也不是很容易,所以需要付出一些努力才行。
在字符串處理領(lǐng)域,正則表達(dá)式的強(qiáng)大功能令人嘆為觀止,它可以按照一定的規(guī)則匹配一組不確定的字符串,而上節(jié)我們介紹的幾個(gè)函數(shù)只能比較兩個(gè)確定的字符串。那么什么是正則表達(dá)式呢?
通俗地講,正則表達(dá)式(regular expression)就是用一個(gè)“字符串”來(lái)描述一個(gè)特征,然后去驗(yàn)證另一個(gè)“字符串”是否符合這個(gè)特征。比如表達(dá)式“ab+”描述的特征是“一個(gè) 'a'和任意個(gè) 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合這個(gè)特征。
正則表達(dá)式的用途非常廣泛,如:① 驗(yàn)證字符串是否符合指定特征,比如驗(yàn)證是否是合法的郵件地址。② 用來(lái)查找字符串,從一個(gè)長(zhǎng)的文本中查找符合指定特征的字符串,比查找固定字符串更加靈活方便。③ 用來(lái)替換,比普通的替換更強(qiáng)大。
列目錄時(shí), dir *.txt或ls *.txt中的*.txt就不是一個(gè)正則表達(dá)式,因?yàn)檫@里*與正則式的*的含義是不同的。
正則表達(dá)式是由普通字符(例如字符a到z)以及特殊字符(稱為元字符)組成的文字模式。正則表達(dá)式作為一個(gè)模板,將某個(gè)字符模式與所搜索的字符串進(jìn)行匹配。
構(gòu)造正則表達(dá)式的方法和創(chuàng)建數(shù)學(xué)表達(dá)式的方法一樣。也就是用多種元字符與操作符將小的表達(dá)式結(jié)合在一起來(lái)創(chuàng)建更大的表達(dá)式。正則表達(dá)式的組件可以是單個(gè)的字符、字符集合、字符范圍、字符間的選擇或者所有這些組件的任意組合。
限定符用來(lái)指定正則表達(dá)式的一個(gè)給定組件必須要出現(xiàn)多少次才能滿足匹配條件。有*、+、?、{n}、{n,}、{n,m}共6種。
用來(lái)描述字符串或單詞的邊界,共有^、$、\b、\B等4個(gè)。
正則表達(dá)式的選擇是用圓括號(hào)將所有選擇項(xiàng)括起來(lái),相鄰的選擇項(xiàng)之間用|分隔。
正則表達(dá)式的引用是對(duì)一個(gè)正則表達(dá)式模式或部分模式兩邊添加圓括號(hào)將導(dǎo)致相關(guān)匹配存儲(chǔ)到一個(gè)臨時(shí)緩沖區(qū)中,所捕獲的每個(gè)子匹配都按照在正則表達(dá)式模式中從左至右所遇到的內(nèi)容存儲(chǔ)。存儲(chǔ)子匹配的緩沖區(qū)編號(hào)從1開始,連續(xù)編號(hào)直至最大99個(gè)子表達(dá)式。每個(gè)緩沖區(qū)都可以使用'\n'訪問(wèn),其中n為一個(gè)標(biāo)識(shí)特定緩沖區(qū)的一位或兩位十進(jìn)制數(shù)。
下面是幾個(gè)正則表達(dá)式的例子。
(1) 表達(dá)式 "('|")(.*?)(\1)" 在匹配 " 'Hello', "World" " 時(shí)成功,匹配到的內(nèi)容是" 'Hello' "。再次匹配時(shí)可以匹配到" "World" "。
(2) 表達(dá)式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 時(shí)成功;匹配到的內(nèi)容是 "ccccc"。再次匹配時(shí),將得到999999999。這個(gè)表達(dá)式要求 "\w" 范圍的字符至少重復(fù)5次,注意與 "\w{5,}" 之間的區(qū)別。
(3) 表達(dá)式 "<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?</\1>" 在匹配 "<td id='td1' style="bgcolor:white"> </td>" 時(shí)成功。如果 "<td>" 與 "</td>" 不配對(duì),則會(huì)匹配失??;如果改成其他配對(duì),也可以匹配成功。
(4) "^The":表示所有以"The"開始的字符串("There","The cat"等)。
(5) "of despair$":表示所以以"of despair"結(jié)尾的字符串。
(6) "^abc$":表示開始和結(jié)尾都是"abc"的字符串。
(7) "notice":表示任何包含"notice"的字符串。
(8) '*','+'和'?'這三個(gè)符號(hào),表示一個(gè)或一序列字符重復(fù)出現(xiàn)的次數(shù)。它們分別表示“沒(méi)有或更多”,“一次或更多”還有“沒(méi)有或一次”。
"ab*":表示一個(gè)字符串有一個(gè)a后面跟著零個(gè)或若干個(gè)b。("a", "ab", "abbb",……)。
"ab+":表示一個(gè)字符串有一個(gè)a后面跟著至少一個(gè)b或者更多。
"ab?":表示一個(gè)字符串有一個(gè)a后面跟著零個(gè)或者一個(gè)b。
"a?b+$":表示在字符串的末尾有零個(gè)或一個(gè)a跟著一個(gè)或幾個(gè)b。
(9) 用大括號(hào)表示重復(fù)次數(shù)的范圍。
"ab{2}":表示一個(gè)字符串有一個(gè)a跟著兩個(gè)b("abb")。
"ab{2,}":表示一個(gè)字符串有一個(gè)a跟著至少兩個(gè)b。
"ab{3,5}":表示一個(gè)字符串有一個(gè)a跟著3到5個(gè)b。
需要注意的是必須指定范圍的下限,如:"{0,2}"而不是"{,2}", '*','+'和'?'相當(dāng)于"{0,}","{1,}"和"{0,1}"。
(10) '|'表示“或”操作。
"hi|hello":表示一個(gè)字符串里有"hi"或者"hello"。
"(b|cd)ef":表示"bef"或"cdef";
"(a|b)*c":表示一串"a""b"混合的字符串后面跟一個(gè)"c"。
(11) '.'可以替代任何字符。
"a.[0-9]":表示一個(gè)字符串有一個(gè)"a"后面跟著一個(gè)任意字符和一個(gè)數(shù)字;
"^.{3}$":表示有任意三個(gè)字符的字符串(長(zhǎng)度為3個(gè)字符);
(12) 方括號(hào)表示某些字符允許在一個(gè)字符串中的某一特定位置出現(xiàn)。
"[ab]":表示一個(gè)字符串有一個(gè)"a"或"b"(相當(dāng)于"a|b")。
"[a-d]":表示一個(gè)字符串包含小寫的'a'到'd'中的一個(gè)(相當(dāng)于"a|b|c|d"或者"[abcd]");
"^[a-zA-Z]":表示一個(gè)以字母開頭的字符串。
"[0-9]%":表示一個(gè)百分號(hào)前有一位的數(shù)字。
",[a-zA-Z0-9]$":表示一個(gè)字符串以一個(gè)逗號(hào)后面跟著一個(gè)字母或數(shù)字結(jié)束。
'^'在方括號(hào)里的第一位時(shí)表示不希望出現(xiàn)的字符。(如:"%[^a-zA-Z]%"表示兩個(gè)百分號(hào)中不應(yīng)該出現(xiàn)字母)。
下面是幾個(gè)常用的正則表達(dá)式。
(1) 非負(fù)整數(shù):^\d+$
(2) 正整數(shù):^[0-9]*[1-9][0-9]*$
(3) 非正整數(shù):^((-\d+)|(0+))$
(4) 負(fù)整數(shù):^-[0-9]*[1-9][0-9]*$
(5) 整數(shù):^-?\d+$
(6) 非負(fù)浮點(diǎn)數(shù):^\d+(\.\d+)?$
(7) 正浮點(diǎn)數(shù):^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9] [0-9]*))$
(8) 非正浮點(diǎn)數(shù):^((-\d+\.\d+)?)|(0+(\.0+)?))$
(9) 負(fù)浮點(diǎn)數(shù):^(-((正浮點(diǎn)數(shù)正則式)))$
(10) 英文字符串:^[A-Za-z]+$
(11) 英文大寫串:^[A-Z]+$
(12) 英文小寫串:^[a-z]+”
(13) 英文字符數(shù)字串:^[A-Za-z0-9]+$
(14) 英數(shù)字加下畫線串:^\w+$
(15) E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
(16) URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
3. 常用的正則表達(dá)式函數(shù)
函數(shù)語(yǔ)法:array preg_grep ( string $pattern, array $input [, int $flags] )
函數(shù)說(shuō)明:返回一個(gè)包括了input數(shù)組中與給定的pattern模式相匹配單元的新數(shù)組。如果參數(shù)flags為PREG_GREP_INVERT,則返回的是由不匹配pattern單元所組成的新數(shù)組。
函數(shù)語(yǔ)法:int preg_match_all ( string $pattern, string $subject, array $matches [, int $flags] )
函數(shù)說(shuō)明:在subject中搜索所有與pattern給出的正則表達(dá)式匹配的內(nèi)容并將結(jié)果以flags指定的順序放到數(shù)組matches中。搜索到第一個(gè)匹配項(xiàng)之后,接下來(lái)的搜索從上一個(gè)匹配項(xiàng)末尾開始。
函數(shù)語(yǔ)法:int preg_match ( string $pattern, string $subject [, array $matches [, int $flags]] )
函數(shù)說(shuō)明:在subject字符串中搜索與pattern給出的正則表達(dá)式相匹配的內(nèi)容。如果提供了matches,則其會(huì)被搜索的結(jié)果所填充。$matches[0] 將包含與整個(gè)模式匹配的文本,$matches[1] 將包含與第一個(gè)捕獲的括號(hào)中的子模式所匹配的文本,以此類推。返回pattern所匹配的次數(shù)。要么是0次(沒(méi)有匹配)或1次,因?yàn)閜reg_match()在第一次匹配之后將停止搜索,如果出錯(cuò)返回FALSE。和preg_match_all()函數(shù)的區(qū)別在于本函數(shù)只匹配一次,而后者全文匹配。
函數(shù)語(yǔ)法:string preg_quote ( string $str [, string $delimiter] )
函數(shù)說(shuō)明:以str為參數(shù)并給其中每個(gè)屬于正則表達(dá)式語(yǔ)法的字符前面加上一個(gè)反斜線。如果你需要以動(dòng)態(tài)生成的字符串作為模式去匹配則可以用此函數(shù)轉(zhuǎn)義其中可能包含的特殊字符。如果提供了可選參數(shù)delimiter,該字符也將被轉(zhuǎn)義。可以用來(lái)轉(zhuǎn)義PCRE函數(shù)所需要的定界符,最常用的定界符是斜線 /。正則表達(dá)式的特殊字符包括:. \ + * ? [ ^ ] $ ( ) { }= ! < > | :。
函數(shù)語(yǔ)法:mixed preg_replace ( mixed $pattern, mixed $replacement, mixed $subject [, int$limit] )
函數(shù)說(shuō)明:在subject中搜索pattern模式的匹配項(xiàng)并替換為replacement。如果指定了limit,則僅替換limit個(gè)匹配,如果省略limit或者其值為-1,則所有的匹配項(xiàng)都會(huì)被替換。
replacement可以包含\\n形式或$n形式的逆向引用,首選使用后者。每個(gè)此種引用將被替換為與第n個(gè)被捕獲的括號(hào)內(nèi)的子模式所匹配的文本。n可以從0到99,其中 \\0或$0指的是被整個(gè)模式所匹配的文本。對(duì)左圓括號(hào)從左到右計(jì)數(shù)(從1開始)以取得子模式的數(shù)目。
對(duì)替換模式在一個(gè)逆向引用后面緊接著一個(gè)數(shù)字時(shí)(即:緊接在一個(gè)匹配的模式后面的數(shù)字),不能使用熟悉的\\1符號(hào)來(lái)表示逆向引用。舉例說(shuō) \\11,將會(huì)使preg_replace() 搞不清楚是想要一個(gè)\\1的逆向引用后面跟著一個(gè)數(shù)字1還是一個(gè)\\11的逆向引用。本例中的解決方法是使用\${1}1。這會(huì)形成一個(gè)隔離的$1逆向引用,而使另一個(gè)1只是單純的文字。
preg_replace() 的每個(gè)參數(shù)(除了limit)都可以是一個(gè)數(shù)組。如果pattern和replacement都是數(shù)組,將以其鍵名在數(shù)組中出現(xiàn)的順序來(lái)進(jìn)行處理。
函數(shù)語(yǔ)法:mixed preg_replace_callback ( mixed $pattern, callback $callback, mixed $subject [, int $limit] )
函數(shù)說(shuō)明:本函數(shù)的行為幾乎和preg_replace() 一樣,除了不是提供一個(gè)replacement參數(shù),而是指定一個(gè)callback函數(shù)。該函數(shù)將以目標(biāo)字符串中的匹配數(shù)組作為輸入?yún)?shù),并返回用于替換的字符串。
函數(shù)語(yǔ)法:array preg_split ( string $pattern, string $subject [, int $limit [, int $flags]] )
函數(shù)說(shuō)明:返回一個(gè)數(shù)組,包含subject中沿著與pattern匹配的邊界所分割的子串。如果指定了limit,則最多返回limit個(gè)子串,如果limit是-1,則意味著沒(méi)有限制,可以用來(lái)繼續(xù)指定可選參數(shù)flags。
flags可以是下列標(biāo)記的任意組合(用按位或運(yùn)算符 | 組合)。
PREG_SPLIT_NO_EMPTY:如果設(shè)定了本標(biāo)記,則preg_split() 只返回非空的成分。
PREG_SPLIT_DELIM_CAPTURE:如果設(shè)定了本標(biāo)記,定界符模式中的括號(hào)表達(dá)式也會(huì)被捕獲并返回。本標(biāo)記添加于PHP 4.0.5。
PREG_SPLIT_OFFSET_CAPTURE:如果設(shè)定了本標(biāo)記,如果設(shè)定本標(biāo)記,對(duì)每個(gè)出現(xiàn)的匹配結(jié)果也同時(shí)返回其附屬的字符串偏移量。注意這改變了返回的數(shù)組的值,使其中的每個(gè)單元也是一個(gè)數(shù)組,其中第一項(xiàng)為匹配字符串,第二項(xiàng)為其在subject中的偏移量。
4. 正則表達(dá)式中的元字符行
表1-9為正則表達(dá)式的元字符行。
表1-9 正則表達(dá)式的元字符行

1.4.3 PHP面向?qū)ο蟮木幊?/h3>
(1) 類和對(duì)象的概念
面向?qū)ο蟮某绦蛟O(shè)計(jì)(OOP),是近年來(lái)日趨流行的編程架構(gòu),常常被用來(lái)作為設(shè)計(jì)大型軟件項(xiàng)目的解決方案,尤其是多人合作的項(xiàng)目。OOP達(dá)到了軟件工程的三個(gè)目標(biāo):重用性、靈活性和擴(kuò)展性,它的基本原則是計(jì)算機(jī)程序是由單個(gè)能夠起到子程序作用的單元或?qū)ο蠼M合而成。有人說(shuō)PHP不是一個(gè)真正的面向?qū)ο蟮恼Z(yǔ)言,這話不假,PHP是一個(gè)混合型語(yǔ)言,你可以使用OOP,也可以使用傳統(tǒng)的過(guò)程化編程。
類(Class)是變量和作用于這些變量的函數(shù)的集合,我們可以把類理解成為是對(duì)萬(wàn)事萬(wàn)物的高度概括、歸納出來(lái)的抽象概念。
當(dāng)給一個(gè)類的屬性賦予具體的值,就生成了基于這個(gè)類的一個(gè)實(shí)例,這個(gè)實(shí)例就叫做“對(duì)象(Object)”。對(duì)象是系統(tǒng)中用來(lái)描述客觀事物的一個(gè)實(shí)體,它是構(gòu)成系統(tǒng)的一個(gè)基本單位。對(duì)象是類的實(shí)例,所以,類中定義的屬性和方法均可被對(duì)象沿用。
面向?qū)ο笃鋵?shí)是現(xiàn)實(shí)世界模型的自然延伸,現(xiàn)實(shí)世界中任何實(shí)體都可以看做是對(duì)象,客觀世界就是由對(duì)象和對(duì)象之間的聯(lián)系組成的。面向?qū)ο蟮木幊趟枷雱t力圖使對(duì)計(jì)算機(jī)語(yǔ)言中對(duì)事物的描述與現(xiàn)實(shí)世界中該事物的本來(lái)面目盡可能的一致,對(duì)象之間通過(guò)消息相互作用。
在PHP5中,類的創(chuàng)建通過(guò)關(guān)鍵字class來(lái)定義。語(yǔ)法如下:
<?php class classname { 變量聲明;//屬性定義 函數(shù)聲明;//方法定義 } ?>
所有的屬性和方法定義都被封閉在class所引導(dǎo)的花括號(hào)中,在聲明變量時(shí),須使用三個(gè)限定詞(public、private、protected)其中的一個(gè)進(jìn)行修飾,以定義變量的訪問(wèn)權(quán)限,如:
<?php class form { public $name = "form"; //定義對(duì)象默認(rèn)名稱為”form” public $width = 200; //定義為200 private $value1;//一個(gè)私有屬性 } ?>
類的方法都是以函數(shù)的形式存在的,因此和普通函數(shù)一樣,通過(guò)function關(guān)鍵字來(lái)定義。
function sum($val1,$val2) { return $val1+$val2; }
當(dāng)聲明一個(gè)方法時(shí),我們所做的和在類外部定義一個(gè)函數(shù)是一樣的。類的方法和屬性都有與類外部函數(shù)不同的各自的命名空間,這意味著我們可以建立一個(gè)與類外部函數(shù)或者其他類同名的方法,兩者不會(huì)沖突。
要想使用類提供的功能,則需要把類實(shí)例成對(duì)象的,定義好一個(gè)類之后,就可以使用關(guān)鍵字new來(lái)創(chuàng)建一個(gè)基于該類的一個(gè)對(duì)象實(shí)例了,new需要類的名稱,并返回一個(gè)類的實(shí)例,該實(shí)例也是一個(gè)變量,需要在對(duì)象名稱前加$。如:
<?php $objectname = new classname; ?>
一個(gè)類可以實(shí)例出多個(gè)對(duì)象,每個(gè)對(duì)象都是獨(dú)立的,每個(gè)對(duì)象之間是沒(méi)有聯(lián)系的,只能說(shuō)明他們這個(gè)類的實(shí)例對(duì)象,每個(gè)對(duì)象都有自己各自的屬性值。
只要是類里面體現(xiàn)出來(lái)的成員屬性和成員方法,實(shí)例化出來(lái)的對(duì)象里面就包含了這些屬性和方法,當(dāng)需要訪問(wèn)這些屬性變量時(shí)用->運(yùn)算符來(lái)引用他們,而不能像普通變量那樣用$來(lái)直接引導(dǎo),如$objectname->attribute。當(dāng)調(diào)用這個(gè)對(duì)象的方法時(shí),同樣如此:$objectname->functionname()。
當(dāng)我們需要在對(duì)象外部調(diào)用它的某些屬性值或者調(diào)用它的方法時(shí),是使用“對(duì)象變量名->”來(lái)調(diào)用其屬性或方法的,那么,當(dāng)只有一個(gè)類的定義還沒(méi)有被實(shí)例化的時(shí)候,或者在這個(gè)類定義其某個(gè)方法時(shí)就需要調(diào)用其他屬性和方法,此時(shí)還沒(méi)有對(duì)象變量的名稱,該如何引用呢?
為解決變量的命名沖突和不確定性問(wèn)題,引入偽變量“$this”代表其當(dāng)前所在對(duì)象。我們可以使用$this來(lái)訪問(wèn)自身的方法函數(shù)和變量,$this變量可以理解為“我自己的”或者“當(dāng)前對(duì)象”。因而 $this->name可以理解為“我自己的$name屬性”或者“當(dāng)前對(duì)象的$name屬性”。
在類內(nèi)部調(diào)用該類所定義的屬性和其他方法,必須使用$this->取值,而方法內(nèi)定義的局部變量,作用范圍僅限于該方法內(nèi)部,而不屬于對(duì)象,因此是不能用$this關(guān)鍵字取值的。
(2) 構(gòu)造方法
構(gòu)造函數(shù)又叫做構(gòu)造方法,是對(duì)象被通過(guò)使用new關(guān)鍵字創(chuàng)建時(shí)自動(dòng)調(diào)用的方法,通常用于完成類初始化的工作。如果我們?cè)谝粋€(gè)類中聲明一個(gè)命名為__construct()的函數(shù)(__是兩個(gè)下畫線),那么這個(gè)函數(shù)將被當(dāng)成是一個(gè)構(gòu)造函數(shù)并在生成對(duì)象實(shí)例時(shí)被執(zhí)行。
就像其他任何函數(shù)一樣,構(gòu)造函數(shù)也可以有參數(shù)或者默認(rèn)值。
構(gòu)造函數(shù)可以調(diào)用本類的屬性,也可以調(diào)用本類的其他方法,還可以被其他方法顯式調(diào)用。
(3) 析構(gòu)函數(shù)
和構(gòu)造函數(shù)__construct()相對(duì)應(yīng),如果我們?cè)谝粋€(gè)類中聲明一個(gè)名為__destruct()的函數(shù), PHP將在對(duì)象被銷毀前調(diào)用它,這個(gè)函數(shù)我們就叫做析構(gòu)函數(shù)。
當(dāng)PHP判斷程序腳本中某個(gè)對(duì)象不再使用時(shí),就會(huì)調(diào)用析構(gòu)函數(shù)來(lái)將其從內(nèi)存中銷毀, PHP默認(rèn)僅僅釋放對(duì)象屬性所占用的內(nèi)存并銷毀該對(duì)象相關(guān)的資源,析構(gòu)函數(shù)則允許在使用一個(gè)對(duì)象之后執(zhí)行任意代碼來(lái)清除內(nèi)存。
和其他方法不同,析構(gòu)函數(shù)比較特殊,析構(gòu)函數(shù)不能帶有參數(shù),也不要在程序中調(diào)用一個(gè)對(duì)象的析構(gòu)函數(shù)。
(4) 兩個(gè)對(duì)象的全等于比較
當(dāng)使用全等符(===)時(shí),當(dāng)且僅當(dāng)兩個(gè)對(duì)象指向相同類(在某一特定的命名空間中)的同一個(gè)對(duì)象時(shí)才相等,這是更嚴(yán)格意義上的相等,內(nèi)容相等,對(duì)象必須是同一個(gè)(相同的內(nèi)存地址)。
(5) 對(duì)象的克隆
當(dāng)用“=”克隆一個(gè)已有對(duì)象變量時(shí),實(shí)際上只是引用了這個(gè)對(duì)象地址,改動(dòng)新變量引用的屬性值,原變量也會(huì)隨之改動(dòng),而有的時(shí)候我們需要在一個(gè)項(xiàng)目里面,使用兩個(gè)或多個(gè)一樣的對(duì)象,如果使用“new”關(guān)鍵字重新創(chuàng)建對(duì)象的話,再賦值上相同的屬性,這樣做比較煩瑣而且也容易出錯(cuò),所以要根據(jù)一個(gè)對(duì)象完全克隆出一個(gè)一模一樣的對(duì)象,是非常有必要的,關(guān)鍵是克隆以后,兩個(gè)對(duì)象互不干擾,其中的一個(gè)對(duì)象的改變不會(huì)影響到另一個(gè)。為此,PHP提供了clone關(guān)鍵字來(lái)克隆一個(gè)與原對(duì)象擁有相同屬性和方法的對(duì)象,并定義了一個(gè)在對(duì)象克隆時(shí)自動(dòng)調(diào)用的特殊方法:__clone(),像__construct()和__destruct()一樣,前面有兩個(gè)下畫線,如果想在克隆時(shí)改變默認(rèn)的內(nèi)容,就要在__clone中覆寫屬性或方法。
值得注意的是,__clone()方法不能被直接調(diào)用,否則程序就會(huì)報(bào)錯(cuò)。
(6) 類的繼承
當(dāng)我們已經(jīng)創(chuàng)建了一些類后,就會(huì)發(fā)現(xiàn)在同一個(gè)范疇內(nèi)如果再建立一些新的類,將會(huì)出現(xiàn)大量的雷同,新類和已有類大部分的屬性和方法都相同,此時(shí),有一種方法可以讓我們很方便的以這些已有類為基礎(chǔ),快速便捷地生成新的類,不需要重復(fù)定義那些相同的屬性和方法,大大減少書寫代碼的時(shí)間,提高代碼的可重用率,這個(gè)方法就是繼承。繼承是面向?qū)ο笕笾匾匦灾?,有著極其重要的作用,它是指建立一個(gè)新的派生類,從一個(gè)或多個(gè)先前已經(jīng)定義的類中繼承屬性和方法,并可以重新定義或者加以改進(jìn)這些屬性和方法,從而建立了類的層級(jí),在類與類之間建立了關(guān)系。
在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,我們管已有的基礎(chǔ)類叫做父類、基類,新的類叫做子類、派生類。子類默認(rèn)從已有父類遺傳有完全相同的屬性和方法,只是簡(jiǎn)單的做一些父類中沒(méi)有的擴(kuò)展就可以了。需要值得注意的是,子類從父類繼承了全部的屬性和方法(父類的私有屬性和私有方法除外,私有屬性和私有方法的內(nèi)容下文講述),這些屬性和方法是不能被注銷的,不能減少,但是可以用新的值來(lái)覆蓋他們。子類被創(chuàng)建后,又可以作為父類派生出更多的子類。
繼承的重要優(yōu)點(diǎn)是經(jīng)濟(jì),您可以選擇定義一個(gè)新類也可以在現(xiàn)有的類上建立子類。這兩種方法得到結(jié)果是相同的。但是定義一個(gè)新類PHP會(huì)重新解析并占用一定的系統(tǒng)資源而使用繼承的方法可以繼承父類而且代碼也會(huì)顯得簡(jiǎn)潔。
除了上面的優(yōu)點(diǎn)之外,繼承有助于程序的維護(hù),節(jié)省工作時(shí)間。如我們?cè)谝呀?jīng)定義好的父類中增加定義幾個(gè)屬性或者方法,則它的所有子類都不用增加一句代碼就全部自動(dòng)擴(kuò)展了這些屬性和方法。
一個(gè)子類可以從一個(gè)父類中繼承屬性和方法,這叫做單繼承;也可以從多個(gè)父類中同時(shí)繼承其屬性和方法,這叫做多繼承。
PHP5中,一個(gè)子類只能從一個(gè)父類中繼承數(shù)據(jù),是單繼承,PHP5不支持多繼承。創(chuàng)建一個(gè)子類時(shí)使用extends關(guān)鍵字來(lái)繼承一個(gè)父類:
class childrenclassname extends fatherclassname { }
通常父類中的所有屬性和方法都被子類全部繼承,這并不是絕對(duì)的,在類的定義時(shí),被三個(gè)限定詞public、private、protected之一的private限定的屬性和方法是不能被繼承的,由這樣的子類生成的實(shí)例對(duì)象就沒(méi)有了這些屬性和方法。
(7) 訪問(wèn)控制
如果類的一個(gè)成員被設(shè)置成了private私有訪問(wèn)方式,那么它將只對(duì)類或者對(duì)象實(shí)例本身的內(nèi)部成員開放,不做訪問(wèn)限制,此對(duì)象內(nèi)部的方法可以訪問(wèn)到所有屬性和其他方法,不管這些成員被設(shè)置成了什么訪問(wèn)方式。
Private成員對(duì)外部程序是被屏蔽而不可見的,不能被它們?cè)L問(wèn)到,當(dāng)前對(duì)象以外的任何類、對(duì)象、程序都不能讀取其私有屬性的值,更不能改變它們,也不能調(diào)用其私有方法,即使是派生出的子類都不能訪問(wèn)到其父類的私有屬性和方法。
Public(公共)成員可以被毫無(wú)限制地訪問(wèn),不管是在類或者對(duì)象的內(nèi)部還是外部,任何程序代碼都可以讀寫public屬性的值,都可以調(diào)用public方法。
和Private成員類似,Protected(保護(hù)) 成員也不能被外部程序訪問(wèn),但區(qū)別之處在于受保護(hù)的成員可以被繼承出的子類訪問(wèn)到,而私有成員不可以。Public有違封裝的精神,因?yàn)樗鼈冊(cè)试S子類依賴于一個(gè)特定的屬性來(lái)書寫,protected方法就不會(huì)帶來(lái)這方面的擔(dān)憂.一個(gè)使用protected方法的子類需要很清楚它的父類的結(jié)構(gòu)才可以。
(8) parent關(guān)鍵字
PHP在同一個(gè)頁(yè)面和被包含的頁(yè)面中不能定義相同名稱的方法,在同一個(gè)類中也不能定義相同名稱的方法。但是在父子關(guān)系的兩個(gè)類中,我們可以在子類中定義和父類同名的方法,這樣就把父類中繼承過(guò)來(lái)的方法覆蓋掉了。當(dāng)要突出表達(dá)子類與眾不同的特點(diǎn)的方法時(shí),就必須要改寫父類方法。
一種是使用父類的“類名::”來(lái)調(diào)用父類中被覆蓋的方法;另一種是使用“parent::”的方式來(lái)調(diào)用父類中被覆蓋的方法。
“::”是范圍解析操作符,用于在沒(méi)有聲明任何實(shí)例的情況下訪問(wèn)類中的函數(shù)或者基類中的函數(shù)和變量。
parent只在子類中使用,特指它的父類,不管父類的名字是什么。
(9) 類的接口
類的接口是一種特殊的抽象類,抽象類又是一種特殊的類,介紹類的接口前,我們需要先知道什么是抽象類。
在面向?qū)ο蟮木幊陶Z(yǔ)言中,一個(gè)類可以有一個(gè)或多個(gè)子類,抽象方法就是為了方便繼承而引入的。所謂抽象方法就是我們?cè)陬惱锒x的沒(méi)有方法體的方法,和正常的方法定義不同,沒(méi)有方法體的意思是指在方法聲明的時(shí)候沒(méi)有{}以及其中的內(nèi)容,而是直接在聲明時(shí)在方法名后加上“;”結(jié)束,另外在聲明抽象方法時(shí)還要加一個(gè)關(guān)鍵字“abstract”來(lái)修飾。
如果一個(gè)類里面有一個(gè)方法是抽象方法,那么這個(gè)類就必須要定義為抽象類,抽象類也要使用“abstract”關(guān)鍵字來(lái)修飾;在抽象類里面可以有不是抽象的方法和成員屬性,但只要有一個(gè)方法是抽象的方法,這個(gè)類就必須聲明為抽象類。
定義抽象類就相當(dāng)于定義了一種規(guī)范,這種規(guī)范要求子類去遵守,子類繼承抽象類之后,把抽象類里面的抽象方法按照子類的需要實(shí)現(xiàn)。子類必須把父類中的抽象方法全部都實(shí)現(xiàn),換句話說(shuō),就是父類的抽象方法在子類中必須被重寫,只要子類中還存在抽象方法,那么子類還是抽象類,還是不能實(shí)例化成對(duì)象。
聲明一個(gè)類的時(shí)候我們使用的關(guān)鍵字是“class”,類的定義:class類名{ … },而接口是一種特殊的類,使用的關(guān)鍵字是“interface”,接口的聲明:interface接口名{ … }
<?php interface interfacename { public function fun1(); public function fun2(); } ?>
我們使用extends來(lái)定義一個(gè)子類或一個(gè)抽象子類,而當(dāng)從一個(gè)接口生成普通類的時(shí),就要使用implements來(lái)實(shí)現(xiàn)這個(gè)接口,并需要實(shí)現(xiàn)接口中的全部抽象方法。
class 類名 implements 接口名 { 屬性聲明; 方法聲明; }
PHP是單繼承的,一個(gè)類只能有一父類,但是一個(gè)類卻可以實(shí)現(xiàn)多個(gè)接口,只要使用“,”將多個(gè)接口名連在一起就可以了,就相當(dāng)于一個(gè)類要遵守多個(gè)規(guī)范。PHP5中不僅一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,也可以在繼承一個(gè)類的同時(shí)還實(shí)現(xiàn)多個(gè)接口,但一定要先繼承類再去實(shí)現(xiàn)接口。
(10) 多態(tài)性
當(dāng)我們?cè)谧宇愔懈膶懥烁割惖姆椒?,或者用多個(gè)類來(lái)實(shí)現(xiàn)同一個(gè)接口時(shí),都會(huì)導(dǎo)致在有層次關(guān)系的類里出現(xiàn)方法同名卻不同行為的情況發(fā)生,我們管這種情況叫做面向?qū)ο蟮亩鄳B(tài)性。
1.4.4 PHP程序調(diào)試與異常
盡管我們寫出了整潔、設(shè)計(jì)良好的代碼, 但在程序運(yùn)行中仍可能有各種各樣的意外出現(xiàn),當(dāng)一個(gè)程序在運(yùn)行過(guò)程中出現(xiàn)意外時(shí),如除0溢出、數(shù)組越界、文件找不到等的異常事件,將阻止程序的正常運(yùn)行,因此我們?cè)诔绦蛟O(shè)計(jì)時(shí),要充分考慮容錯(cuò)性,估計(jì)到可能會(huì)發(fā)生的各種異常情況并做出相應(yīng)的處理,以便程序可以健康的運(yùn)行。
在面向?qū)ο缶幊讨幸话阋膊捎妹嫦驅(qū)ο蟮漠惓L幚矸椒?,通過(guò)throw來(lái)拋出異常, try-catch捕獲異常,PHP 5.0內(nèi)核采用了面向?qū)ο缶幊痰姆椒?,也引入了這種異常處理的方法。
PHP 5.0開始引入了異常處理類,我們可以通過(guò)實(shí)例化Exception類或者它的子類來(lái)創(chuàng)建一個(gè)異常實(shí)例,有了這個(gè)異常實(shí)例,就可以通過(guò)Exception類中定義好的getCode()、getFile()、getLine()等方法,來(lái)獲得相應(yīng)的屬性值。
異常類Exception中屬性和方法的定義如下:
<?php class Exception { protected $message; //存儲(chǔ)異常信息的變量 private $string; //格式化以后的異常信息 protected $code; //通過(guò)構(gòu)造函數(shù)傳遞的異常代碼 protected $file; //產(chǎn)生異常的php文件的文件名 protected $line; //引起異常的代碼在php文件中的行數(shù) private $trace; //引起異常后,包含相關(guān)信息的一個(gè)數(shù)組 final private function __clone() { } function __construct($message = NULL, $code = 0) { //構(gòu)造函數(shù),需要一個(gè)出錯(cuò)信息和一個(gè)可選的整型錯(cuò)誤標(biāo)記作參數(shù) if (func_num_args()) { $this->message = $message; } $this->code = $code; //默認(rèn)錯(cuò)誤代碼為0 $this->file = __FILE__; //文件名 $this->line = __LINE__; //行號(hào) $this->trace = debug_backtrace(); $this->string = StringFormat($this); } //取得出錯(cuò)信息 final public function getMessage() { return $this->message; } // 出錯(cuò)的代碼 final public function getCode() { return $this->code; } //異常發(fā)生的文件 final public function getFile() { return $this->file; } //異常發(fā)生的行數(shù) final public function getLine() { return $this->line; } //跟蹤異常每一步傳遞的路線,存入數(shù)組,返回該數(shù)組 final public function getTrace() { return $this->trace; } // 和getTrace()功能一樣,但可以將數(shù)組中的元素轉(zhuǎn)成字符串并按一定格式輸出 final public function getTraceAsString() { } // public function __toString() { return $this->string; } } ?>
在面向?qū)ο蟮木幊讨校绻骋粋€(gè)方法在運(yùn)行過(guò)程中發(fā)生了異常,此方法將生成代表該異常的一個(gè)對(duì)象,并把它交給運(yùn)行時(shí)系統(tǒng),運(yùn)行時(shí)系統(tǒng)尋找相應(yīng)的代碼來(lái)處理這一異常。我們把生成異常對(duì)象并把它提交給運(yùn)行時(shí)系統(tǒng)的這個(gè)過(guò)程稱為拋出(throw)一個(gè)異常。運(yùn)行時(shí)系統(tǒng)在方法的調(diào)用棧中查找,從生成異常的方法開始進(jìn)行回朔,直到找到包含相應(yīng)異常處理的方法為止,這一個(gè)過(guò)程稱為捕獲(catch)一個(gè)異常。
Throw的用法是:
throw new Exception( "Exception Message", 2 );
我們通常使用try-catch語(yǔ)句(包括一個(gè)try語(yǔ)句和至少一個(gè)catch語(yǔ)句)來(lái)捕獲程序代碼通過(guò)throw拋出的異常并處理,try語(yǔ)句用花括號(hào){}指定了一段代碼,該段代碼可能會(huì)拋棄一個(gè)或多個(gè)異常。任何調(diào)用可能會(huì)拋出異常的程序代碼都應(yīng)該使用try語(yǔ)句。一旦throw拋出異常,程序會(huì)在throw語(yǔ)句后立即終止,它后面的語(yǔ)句不再執(zhí)行,而是在包含它的所有try塊中(可能在上層調(diào)用函數(shù)中)從里向外尋找含有與其匹配的catch子句的try塊。
Catch語(yǔ)句則用來(lái)處理可能拋出的異常。catch語(yǔ)句的參數(shù)類似于方法的聲明,包括一個(gè)異常類型和一個(gè)異常對(duì)象。異常類型必須為Exception類的子類,它指明了catch語(yǔ)句所處理的異常類型,異常對(duì)象則由運(yùn)行時(shí)系統(tǒng)在try所指定的代碼塊中生成并被捕獲,花括號(hào)中包含對(duì)象的處理,其中可以調(diào)用對(duì)象的方法。
Try-catch語(yǔ)句的語(yǔ)法是:
Try { //可能發(fā)生異常的語(yǔ)句 } Catch(異常類型 異常實(shí)例) { //異常處理語(yǔ)句 }
如果try塊未產(chǎn)生任何異常,try塊將正常運(yùn)行完畢,catch塊內(nèi)容不會(huì)被執(zhí)行。
Try塊如果拋出了異常,會(huì)立刻在catch中尋找可以捕獲此異常的catch塊,并運(yùn)行相應(yīng)的catch塊代碼,然后跳出try catch塊繼續(xù)運(yùn)行。 而try塊中拋出異常后面的代碼將被跳過(guò)。
如果try塊中的異常不能被catch塊捕獲,將拋向系統(tǒng)引發(fā)系統(tǒng)致命錯(cuò)誤,代碼終止運(yùn)行。
在catch中,異常類型后面跟的是一個(gè)變量,這個(gè)變量將指向內(nèi)存中被捕獲的異常實(shí)例。
如果try塊中的程序語(yǔ)句可能拋出兩種以上的異常,我們可以在使用throw new Exception($message,$code)時(shí),通過(guò)第二個(gè)參數(shù)$code來(lái)指定異常代碼,然后在catch塊中判斷不同的異常代碼分別做異常處理。
Catch語(yǔ)句可以有多個(gè),分別處理不同類的異常,有多個(gè)擴(kuò)展的異常處理類時(shí)就常用多個(gè)catch語(yǔ)句來(lái)對(duì)應(yīng)匹配,運(yùn)行時(shí)系統(tǒng)從上到下分別對(duì)每個(gè)catch語(yǔ)句處理的例外類型進(jìn)行檢測(cè),直到找到類型相匹配的catch語(yǔ)句為止。每個(gè)catch語(yǔ)句的參數(shù)就像是一個(gè)匹配測(cè)試一樣,第一個(gè)發(fā)生匹配的catch語(yǔ)句將會(huì)執(zhí)行,而不執(zhí)行其他的catch語(yǔ)句。這里,類型匹配指catch所處理的異常類型與生成的例外對(duì)象的類型完全一致或者是它的父類,因此,catch語(yǔ)句的排列順序應(yīng)該是從特殊到一般,將針對(duì)特定異常的catch語(yǔ)句寫在前面,而將針對(duì)一般性的異常的catch語(yǔ)句寫在后面。
也可以用一個(gè)catch語(yǔ)句處理多個(gè)異常類型,這時(shí)它的異常類型參數(shù)應(yīng)該是這多個(gè)異常類型的父類,如Exception,程序設(shè)計(jì)中要根據(jù)具體的情況來(lái)選擇catch語(yǔ)句的異常處理類型。
那么我們已經(jīng)出發(fā)了一些在發(fā)生時(shí)調(diào)用程序無(wú)法馬上處理的異常怎么辦呢?類似,將處理這個(gè)異常的責(zé)任交還給調(diào)用當(dāng)前方法的上一級(jí)代碼,也就是在catch語(yǔ)句中再次拋出了異常,又叫重?cái)S異常,這就使得異常沿著方法的調(diào)用層鏈逐級(jí)向上傳遞了。
異常是PHP5中的一個(gè)新的重要特性,異常機(jī)制提供了幾個(gè)非常關(guān)鍵的好處:
(1) 通過(guò)將錯(cuò)誤處理集中于catch語(yǔ)句中,我們可以將錯(cuò)誤處理從應(yīng)用流程中獨(dú)立出來(lái)。這也使代碼的可讀性提高,看起來(lái)令人愉快。通過(guò)采取非常嚴(yán)格的策略來(lái)捕捉所有異常并中止腳本執(zhí)行,這樣可以獲得所需的附加的彈性,同時(shí)實(shí)現(xiàn)安全易用的異常管理。
(2) 重?cái)S異常,可以在catch中傳播錯(cuò)誤信息,將異常數(shù)據(jù)流從低層傳遞至高層,就是說(shuō)異常被傳回最適合決定如何處理異常的地方。這看起來(lái)會(huì)顯得有點(diǎn)奇怪,但實(shí)際情況中很經(jīng)常我們?cè)诋惓0l(fā)生的時(shí)候無(wú)法立刻決定如何處理它。
(3) 異常機(jī)制提供的Throw/catch避免了直接返回錯(cuò)誤標(biāo)識(shí),方法的返回值是可以由類來(lái)決定。其他程序員使用我們的代碼時(shí),可以指定返回一個(gè)他希望的形式,而不需要令人疲倦的不停地測(cè)試,方便程序定位錯(cuò)誤和維護(hù)。
有這樣一種“美妙的”想法:用一個(gè)catch語(yǔ)句捕獲所有的異常,最常見的情形就是使用catch(Exception $e)語(yǔ)句。但實(shí)際上,在絕大多數(shù)情況下,這種做法不值得提倡。為什么呢?
要理解其原因,我們必須回顧一下catch語(yǔ)句的用途。catch語(yǔ)句表示我們預(yù)期會(huì)出現(xiàn)某種異常,而且希望能夠處理該異常。異常類的作用就是告訴PHP我們想要處理的是哪一種異常。由于絕大多數(shù)異常都直接或間接從Exception繼承,catch(Exception ex)就相當(dāng)于說(shuō)我們想要處理所有的異常,可是在同一個(gè)catch塊中處理幾種截然不同的異常是不合適的,catch語(yǔ)句應(yīng)當(dāng)盡量指定具體的異常類型,而不應(yīng)該指定涵蓋范圍太廣的Exception類。必要時(shí)使用多個(gè)catch,不要試圖處理所有可能出現(xiàn)的異常。
還有要盡量避免把大量的代碼放入單個(gè)try塊,這不是好習(xí)慣。這種現(xiàn)象是因?yàn)槌绦騿T圖省事,不愿花時(shí)間分析一大塊代碼中哪幾行代碼會(huì)拋出異常、異常的具體類型是什么。把大量的語(yǔ)句裝入單個(gè)巨大的try塊就像是出門旅游時(shí)把所有日常用品塞入一個(gè)大箱子,雖然東西是帶上了,但要找出來(lái)可不容易。把大量的代碼放入單個(gè)try塊,然后再在catch語(yǔ)句中聲明Exception,而不是分離各個(gè)可能出現(xiàn)異常的段落并分別捕獲其異常。這種做法為分析程序拋出異常的原因帶來(lái)了困難,因?yàn)橐淮蠖未a中有太多的地方可能拋出Exception。
1.4.5 PHP與MySQL數(shù)據(jù)庫(kù)
MySQL作為PHP最密切的數(shù)據(jù)庫(kù),PHP提供了非常多的函數(shù)來(lái)提供對(duì)MySQL數(shù)據(jù)庫(kù)的操作,就連MySQL應(yīng)用最廣的管理軟件phpMyadm都是用PHP來(lái)編寫的。
PHP提供的MySQL數(shù)據(jù)庫(kù)操作函數(shù)有:
mysql_affected_rows——取得前一次MySQL操作所影響的記錄行數(shù)
mysql_change_user——改變活動(dòng)連接中登錄的用戶
mysql_client_encoding——返回字符集的名稱
mysql_close——關(guān)閉MySQL 連接
mysql_connect——打開一個(gè)到MySQL服務(wù)器的連接
mysql_create_db——新建一個(gè)MySQL數(shù)據(jù)庫(kù)
mysql_data_seek——移動(dòng)內(nèi)部結(jié)果的指針
mysql_db_name——取得結(jié)果數(shù)據(jù)
mysql_db_query——發(fā)送一條MySQL查詢
mysql_drop_db——丟棄(刪除)一個(gè)MySQL數(shù)據(jù)庫(kù)
mysql_errno——返回上一個(gè)MySQL操作中的錯(cuò)誤信息的數(shù)字編碼
mysql_error——返回上一個(gè)MySQL操作產(chǎn)生的文本錯(cuò)誤信息
mysql_escape_string——轉(zhuǎn)義一個(gè)字符串用于mysql_query
mysql_fetch_array——從結(jié)果集中取得一行作為關(guān)聯(lián)數(shù)組,或數(shù)字?jǐn)?shù)組,或二者兼有
mysql_fetch_assoc——從結(jié)果集中取得一行作為關(guān)聯(lián)數(shù)組
mysql_fetch_field——從結(jié)果集中取得列信息并作為對(duì)象返回
mysql_fetch_lengths——取得結(jié)果集中每個(gè)輸出的長(zhǎng)度
mysql_fetch_object——從結(jié)果集中取得一行作為對(duì)象
mysql_fetch_row——從結(jié)果集中取得一行作為枚舉數(shù)組
mysql_field_flags——從結(jié)果中取得和指定字段關(guān)聯(lián)的標(biāo)志
mysql_field_len——返回指定字段的長(zhǎng)度
mysql_field_name——取得結(jié)果中指定字段的字段名
mysql_field_seek——將結(jié)果集中的指針設(shè)定為制定的字段偏移量
mysql_field_table——取得指定字段所在的表名
mysql_field_type——取得結(jié)果集中指定字段的類型
mysql_free_result——釋放結(jié)果內(nèi)存
mysql_get_client_info——取得MySQL 客戶端信息
mysql_get_host_info——取得MySQL 主機(jī)信息
mysql_get_proto_info——取得MySQL 協(xié)議信息
mysql_get_server_info——取得MySQL服務(wù)器信息
mysql_info——取得最近一條查詢的信息
mysql_insert_id——取得上一步INSERT操作產(chǎn)生的ID
mysql_list_dbs——列出MySQL服務(wù)器中所有的數(shù)據(jù)庫(kù)
mysql_list_fields——列出MySQL結(jié)果中的字段
mysql_list_processes——列出MySQL進(jìn)程
mysql_list_tables——列出MySQL數(shù)據(jù)庫(kù)中的表
mysql_num_fields——取得結(jié)果集中字段的數(shù)目
mysql_num_rows——取得結(jié)果集中行的數(shù)目
mysql_pconnect——打開一個(gè)到MySQL服務(wù)器的持久連接
mysql_ping——Ping 一個(gè)服務(wù)器連接,如果沒(méi)有連接則重新連接
mysql_query——發(fā)送一條MySQL查詢
mysql_real_escape_string——轉(zhuǎn)義SQL語(yǔ)句中使用的字符串中的特殊字符,并考慮到連接的當(dāng)前字符集
mysql_result——取得結(jié)果數(shù)據(jù)
mysql_select_db——選擇MySQL數(shù)據(jù)庫(kù)
mysql_set_charset——Sets the client character set
mysql_stat——取得當(dāng)前系統(tǒng)狀態(tài)
mysql_tablename——取得表名
mysql_thread_id——返回當(dāng)前線程的ID
mysql_unbuffered_query——向MySQL 發(fā)送一條SQL查詢,并不獲取和緩存結(jié)果的行
1.4.6 構(gòu)建PHP動(dòng)態(tài)網(wǎng)頁(yè)
掌握了PHP的語(yǔ)法和面向?qū)ο蟮木幊讨R(shí)后,我們就可以綜合運(yùn)用來(lái)編寫PHP動(dòng)態(tài)網(wǎng)頁(yè)了。
如下面我們給出一個(gè)連接MySQL數(shù)據(jù)庫(kù)查詢其中數(shù)據(jù)顯示出來(lái)的的PHP腳本演示。
<?php //MySQL服務(wù)器地址 $host = "localhost:3306"; //MySQL用戶名 $user = "root"; //MySQL密碼 $pass = ""; //要使用的數(shù)據(jù)庫(kù) $dbname = "phpbook"; //建立和數(shù)據(jù)庫(kù)的連接 $id = mysql_connect($host, $user, $pass); //使用GBK編碼 mysql_query("set names gbk"); //選擇數(shù)據(jù)庫(kù) mysql_select_db($dbname); //執(zhí)行SQL查詢,讀出用戶表 $sql = "select * from users where user_id > 0 order by user_id"; $result = mysql_query($sql); echo "<table><tr><td>用戶代碼</td><td>用戶名</td><td>電子郵件</td><td>頭像 地址</td><td>手機(jī)號(hào)碼</td></tr>"; while($row = mysql_fetch_array($result)) { echo "<tr><td>" . $row['user_id'] . "</td><td>" . $row['user_name'] . "</td><td>" . $row['email'] . "</td><td>" . $row['img'] . "</td><td>" . $row['mobile_phone'] . "</td></tr>"; } echo "</table>"; ?>
我們將此代碼存儲(chǔ)為demo1.php,在瀏覽器中訪問(wèn)該地址如圖1-28所示。

圖1-28 PHP代碼運(yùn)行實(shí)例
- 觸·心:DT時(shí)代的大數(shù)據(jù)精準(zhǔn)營(yíng)銷
- PHP基礎(chǔ)案例教程
- Mastering Kotlin
- Java技術(shù)手冊(cè)(原書第7版)
- Implementing Cisco Networking Solutions
- MATLAB實(shí)用教程
- 單片機(jī)應(yīng)用技術(shù)
- Android程序設(shè)計(jì)基礎(chǔ)
- C語(yǔ)言程序設(shè)計(jì)
- Mastering Backbone.js
- Internet of Things with ESP8266
- Maker基地嘉年華:玩轉(zhuǎn)樂(lè)動(dòng)魔盒學(xué)Scratch
- Python函數(shù)式編程(第2版)
- STM8實(shí)戰(zhàn)
- Ext JS 4 Plugin and Extension Development