《PHP程序設(shè)計(jì)》 第三章 PHP中的數(shù)據(jù)處理
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
第三章 PHP中的數(shù)據(jù)處理
本章著重講述PHP程序的內(nèi)部數(shù)據(jù),包括數(shù)字,變量和常量。程序中的數(shù)據(jù)由操作符來(lái)控制的,操作符告訴PHP對(duì)內(nèi)部數(shù)據(jù)進(jìn)行什么操作(如加、減等等)。PHP程序的外部數(shù)據(jù)包括文本文件和數(shù)據(jù)庫(kù),對(duì)外部數(shù)據(jù)的詳細(xì)介紹請(qǐng)參考第六章“數(shù)據(jù)庫(kù)和SQL” 當(dāng)程序運(yùn)行時(shí)數(shù)值不會(huì)改變,這是因?yàn)檫@些數(shù)值在源代碼中已經(jīng)準(zhǔn)確表示了它們?cè)撌鞘裁粗怠6蠖鄶?shù)時(shí)候,在程序運(yùn)行時(shí)卻需要改變某些數(shù)值,為此,必須留出一部分計(jì)算機(jī)的存儲(chǔ)空間來(lái)保存可變化的數(shù)值。而且必須隨時(shí)留意這些小存儲(chǔ)單元的位置,以便程序能在需要時(shí)能找到它們。像所有計(jì)算機(jī)語(yǔ)言一樣,PHP使用變量來(lái)監(jiān)視計(jì)算機(jī)存儲(chǔ)器的使用情況,每當(dāng)需要存儲(chǔ)一條新的消息時(shí),就可以將它置成一個(gè)變量。常量指的是賦予一個(gè)名稱的數(shù)值,最典型的一個(gè)常量例子就是數(shù)學(xué)值:π(pi)。 本章講述了在PHP中如何使用數(shù)值、變量和常量。首先,我們先來(lái)討論數(shù)值。 3.1 數(shù)值 數(shù)值常表示為“等于”或?qū)嶋H代碼的形式,比如,在源代碼程序中看到像12.5這樣的數(shù)值時(shí),它指的是十二點(diǎn)五,而不是指“1”,“2”,“.”,“5”這四個(gè)字符。可以用同樣方式來(lái)表示文本,比如,“Rolf D"Barno”(注意雙引號(hào))表示由十二個(gè)字符組成的字符串。因?yàn)檫@十二個(gè)字符用雙引號(hào)括了起來(lái),因此,它們只能是一個(gè)字符串?dāng)?shù)值。 PHP使用兩種類(lèi)型的數(shù)值: .數(shù)字 -- 最基本的數(shù)據(jù)類(lèi)型。 .文本 -- 作為一個(gè)單元進(jìn)行處理的一串字符。 3.1.1 數(shù)字 在PHP中最常使用的是數(shù)字,它通常代表為了完成某項(xiàng)任務(wù)而需要執(zhí)行的程序所要用到的一個(gè)數(shù)值。我們最常使用的是十進(jìn)制數(shù),但在PHP中也可以使用八進(jìn)制和十六進(jìn)制。 在遇到很大的或很小的數(shù)字的時(shí)候,就會(huì)發(fā)現(xiàn)科學(xué)表達(dá)式是十分有用的了。在高中時(shí)我所學(xué)的數(shù)學(xué)知識(shí)差不多都快忘光了,只有對(duì)科學(xué)表達(dá)式牢記不忘,這大概是因?yàn)槲冶容^喜歡移動(dòng)小數(shù)點(diǎn)的緣故。科學(xué)表達(dá)式10.23E+4,等于102,300。也可以在科學(xué)表達(dá)式中用減號(hào)表示比較小的數(shù),比如,10.23E-4等于.001023。簡(jiǎn)單地說(shuō),如果指數(shù)為正數(shù)的話,就將小數(shù)點(diǎn)向右移動(dòng),如果指數(shù)為負(fù)數(shù),則將小數(shù)點(diǎn)向左移動(dòng)。 注意:對(duì)于那些對(duì)非十進(jìn)制不熟悉的人來(lái)說(shuō),這里有一個(gè)簡(jiǎn)單的解釋。 十進(jìn)制的基數(shù)為十。當(dāng)看到值15時(shí),它表示(1*10)+5或1510。下方的值代表基數(shù)。 八進(jìn)制的基數(shù)為八。當(dāng)看到值15時(shí),它表示(1*8)+5或1310。 十六進(jìn)制的基數(shù)為十六。當(dāng)看到值15時(shí),它表示(1*16)+5或2110。當(dāng)基數(shù)為十六時(shí),除了0到9外,還需要6個(gè)字符,以便能占滿十六個(gè)值的每一個(gè)位置。字母A-F常用來(lái)表示11-16。因此,值BD16等于(B16*16)+D16或(1110*16)+1310,即17610。 讓我們來(lái)看一看在程序中會(huì)用到的幾種不同類(lèi)型的數(shù)字。首先先來(lái)看整數(shù)。 * 123--十進(jìn)制整數(shù)。 * 043--八進(jìn)制整數(shù),數(shù)字前綴0表示八進(jìn)制數(shù)。 * 0x23--十六進(jìn)制整數(shù),數(shù)字前綴“0x”表示十六進(jìn)制數(shù)。 有小數(shù)部分的數(shù)叫做浮點(diǎn)數(shù)。簡(jiǎn)略地講,經(jīng)常見(jiàn)到的那些數(shù)值指的都是浮點(diǎn)數(shù)。 * 100.5--有一位小數(shù)的一個(gè)浮點(diǎn)數(shù),也可以稱為一百又十分之五。 * 54.534--有三位小數(shù)的一個(gè)浮點(diǎn)數(shù),也可以稱為五十四又一千分之五百三十四。 * .000034--非常小的一個(gè)浮點(diǎn)數(shù),也可以用科學(xué)表達(dá)式3.4E-5表示。 整數(shù)沒(méi)有小數(shù)部分,浮點(diǎn)數(shù)有小數(shù)部分。 3.1.2 文本 文本是一組由引號(hào)括起來(lái)的字符,因而能被當(dāng)為單個(gè)數(shù)據(jù)來(lái)使用。實(shí)際上,PHP對(duì)引號(hào)的要求并不嚴(yán)格,沒(méi)有用引號(hào)括起來(lái)的單個(gè)詞也可以用來(lái)表示字符串,但是為了避免混淆,請(qǐng)不要這樣做。由于文本值包含有一系列字符,所以文本值通常稱為字符串。它們?cè)诔绦蛑谐S糜诒硎敬_定文件名、顯示消息、輸入提示等。PHP嚴(yán)格區(qū)分單引號(hào)(')、雙引號(hào)(")和反引號(hào)(`)的作用。 文本也常稱為字符串。 單引號(hào)字符串: 單引號(hào)字符串相當(dāng)容易理解,只需要用單引號(hào)把想使用的文本括起來(lái)即可。例如: 'Men at Arms by Terry Pratchett' '<p>This is an HTML paragraph.</p>' 單引號(hào)字符串是用單括號(hào)(')括起來(lái)的文本。 注意:讀過(guò)本章后面的內(nèi)容“變量替換”之后,單引號(hào)的真正作用才能表現(xiàn)出來(lái)。 如果需要在單引號(hào)內(nèi)部再次使用單引號(hào),事情就會(huì)變得有些麻煩。例如,下面的語(yǔ)句不能正常工作,這是由于第二個(gè)引號(hào)已經(jīng)結(jié)束了所表示字符串。 'Terry's book is highly enjoyable.' 這個(gè)典型的錯(cuò)誤即是語(yǔ)法(或分析)錯(cuò)誤,PHP編譯器不知道如何處理第二個(gè)單引號(hào)以后的文本。以下是正確的表示方式: 'Terry\'s book is highly enjoyable.' 反斜杠(\)字符串表示單引號(hào)的功能--結(jié)束文本值--將會(huì)被忽略。 提示:反斜杠字符也被稱為轉(zhuǎn)義字符,這也許是由于它使它后面的字符從常用含義中脫離出來(lái)的緣故。 有關(guān)單引號(hào)字符串的另一個(gè)更重要的要點(diǎn)是--如果需要在單引號(hào)字符串中換行,只要簡(jiǎn)單地在源代碼中鍵入換行鍵即可。清單3.1顯示了如何這樣做。 清單3.1 line_breaks.php3--在輸入行中加入換行即可開(kāi)始新行 <?php echo '<pre>First Paragraph: Corporal Carrot, Ankh-Morpork City Guard (Night Watch), sat down in his nightshirt took up his pencil, sucked the end for a moment, and then wrote:</pre>'; ?> 如果讀者不熟悉HTML語(yǔ)言的話,請(qǐng)閱讀一到兩本HTML教學(xué)指南。在本書(shū)以后的章節(jié)中必須熟悉HTML語(yǔ)言。 Page 35, 圖 3。1 圖 3.1 可以通過(guò) Web瀏覽器看到在代碼中加入的換行 在圖3.1中可以看到用單引號(hào)括起來(lái)的,甚至在代碼中包含換行的字符串的一部分。 雙引號(hào)字符串: 雙引號(hào)字符串類(lèi)似于單引號(hào)字符串,但是雙引號(hào)字符串更復(fù)雜一點(diǎn)。在雙引號(hào)字符串中可以使用反斜杠在字符串中加入轉(zhuǎn)義序列和轉(zhuǎn)換字符。也可以使用變量替換,但是現(xiàn)在還不打算過(guò)早涉及有關(guān)變量替換方面的問(wèn)題,這個(gè)主題留到以后再仔細(xì)討論。 雙引號(hào)字符串是由雙引號(hào)(")括起來(lái)的字符串。 基本的雙引號(hào)字符串是一系列由雙引號(hào)(")括起來(lái)的字符,如果需要在字符串中使用雙引號(hào),可以使用反斜杠字符。例如: "Men at Arms by Terry Pratchett" "<p>This is an HTML paragraph.</p>" "Terry's book is highly enjoyable. " "John said,\"Gifts are great.\"" 注意在最后一行中的反斜杠用來(lái)使雙引號(hào)的功能改變,如果不使用反斜杠字符,也可以使用單引號(hào)。雙引號(hào)字符串和單引號(hào)字符串的一個(gè)較大的不同之處是,雙引號(hào)字符串可以在字符串中加入特殊的轉(zhuǎn)義序列。表3.1顯示了PHP可以理解的轉(zhuǎn)義序列。 表3.1 轉(zhuǎn)義序列 轉(zhuǎn)義序列 描述 \n 換行 \r 回車(chē) \t 制表符 \$ 美圓符號(hào) \0nnn 任一個(gè)八進(jìn)制數(shù) \xnn 任一個(gè)十六進(jìn)制數(shù) \\ 反斜杠字符 提示:在下一節(jié)“變量”中,就可以知道在使用$字符時(shí),為什么需要使用反斜杠。 你也許對(duì)\0nnn和\xnn比較陌生,請(qǐng)看下面的例子: "Peter was \067 years old yesterday." "Peter was \0x39 years old yesterday. " 以上的文本都表示彼得 9歲了,八進(jìn)制和十六進(jìn)制序列都表示彼得的歲數(shù)9這個(gè)字符的ASCII代碼。ASCII代碼的清單詳見(jiàn)附錄B。 反引號(hào)字符串: 對(duì)于反引號(hào)字符串是否是真正的文本還存在爭(zhēng)論,這是因?yàn)镻HP使用反引號(hào)字符串來(lái)運(yùn)行系統(tǒng)命令。當(dāng)PHP看到反引號(hào)字符串時(shí),它將字符串?dāng)?shù)值傳遞給Windows、UNIX或者用戶使用的其他類(lèi)型操作系統(tǒng)。清單3.2顯示了這個(gè)過(guò)程是如何完成的,圖3.2顯示在Web瀏覽器窗口中的系統(tǒng)命令輸出結(jié)果。 反引號(hào)字符串使用反引號(hào)(`)括起來(lái)。 清單3.2 back_quoted_string.php3--使用反引號(hào)字符串執(zhí)行命令 <?php echo '<pre>'; echo `ls *.php3`; echo '</pre>'; ?> Page 37 圖3.2 圖3.2在Web瀏覽器中顯示的系統(tǒng)命令所顯示的文本 在雙引號(hào)字符串使用的轉(zhuǎn)義序列也能在反引號(hào)字符串中使用。 3.2 變量 數(shù)字僅能解決用來(lái)程序當(dāng)中的內(nèi)部數(shù)據(jù)的一部分問(wèn)題。當(dāng)需要保存數(shù)據(jù)值,并在運(yùn)行程序時(shí)需要進(jìn)行改變的時(shí)候,就需要用到變量。PHP有三種類(lèi)型的變量: 標(biāo)量 -- 一次保存一個(gè)特定數(shù)字或字符串。我通常用scl_作為標(biāo)量名的起始字符。如果該變量只保存一種類(lèi)型的值時(shí),我將在其名字前使用int_或str_前綴。 數(shù)組 -- 存儲(chǔ)數(shù)值的列表。這些數(shù)值可能是數(shù)字、字符串或是另一個(gè)數(shù)組。我通常用arr_作為數(shù)組變量的起始字符。 對(duì)象 -- 存儲(chǔ)變量信息和函數(shù)。更詳細(xì)的信息請(qǐng)參看第十章“面向?qū)ο蟆薄N彝ǔS胦bj_作為對(duì)象變量的起始字符。 提示:推薦對(duì)不同類(lèi)型的數(shù)據(jù)使用可區(qū)分的變量名,除非有更好的理由。如果需要使用同一個(gè)名字的時(shí)候,可以嘗試使用名字的復(fù)數(shù)作為數(shù)組變量名。例如,使用 $name作為標(biāo)量名,并使用$names作為數(shù)組變量名。這將在以后的編程中避免一些混亂。 注意:在PHP中的變量名是區(qū)分大小寫(xiě)的。這意味著$scl_varname、$scl_Valname、$scl_varName和$scl_VARNAME都代表不同的變量。 在本章下面的部分將分別討論每一種變量類(lèi)型。你將讀到如何命名變量、設(shè)置它的值、以及它們的一些用處。 3.2.1 標(biāo)量 標(biāo)量常用來(lái)跟蹤單個(gè)信息。例如,客戶的名字或出售的數(shù)量。只要標(biāo)量名以$為第一個(gè)字符,第二個(gè)字符是字母或下劃線,就可以使用任一個(gè)可以從名字想象出是什么東西的名字作為標(biāo)量名。 提示:如果曾經(jīng)使用Visual Basic進(jìn)行過(guò)編程,那么在命名變量時(shí)必須特別小心。要記住所有的標(biāo)量名都是以$為開(kāi)始的,而不只是字符串;名字的開(kāi)始字符是$,而不是名字的結(jié)尾字符是$。 讓我們現(xiàn)在看看一些變量的名字: * $int_page_number--存儲(chǔ)當(dāng)前頁(yè)碼。 * $str_magazine_title--存儲(chǔ)雜志的標(biāo)題。 * $0--無(wú)效的變量名字。變量名不能以數(shù)字字符開(kāi)始。 我較喜歡使用具有描述能力的變量名。對(duì)我來(lái)說(shuō),$int_book_number比$booknum更好,這是由于$int_book_number的描述性更好。由于較長(zhǎng)的文件名有助于理解程序,因此在程序不使用比較短的變量名較好。PHP變量名的長(zhǎng)度實(shí)際上沒(méi)有什么限制,但是我一般把長(zhǎng)度限制到二十個(gè)字符以內(nèi)。比二十個(gè)字符還長(zhǎng)的名字,有可能增加產(chǎn)生拼寫(xiě)失誤的機(jī)會(huì)。 使用具有描述性的名字:int_book_number比booknum更好。 明白了什么是標(biāo)量名之后,現(xiàn)在讓我們看看如何給變量賦值。對(duì)一個(gè)標(biāo)量賦值通常使用等號(hào),如以下清單3.3所示。 清單3.3 assign_scalars.php3--使用賦值操作符 <?PHP $int_page_number=46; $str_magazine_title = 'PHP is good!'; ?> 以上代碼給變量賦值。當(dāng)給變量賦給簡(jiǎn)單的文本值時(shí),由于使用單符號(hào)字符串效率更高,所以通常使用單符號(hào)字符串。 注意:PHP使用雙斜杠(//)來(lái)作為注釋的開(kāi)始,在雙斜杠字符后面的任何字符都會(huì)被忽略。 對(duì)變量賦值以后,可以根據(jù)需要改變它們的值。下一個(gè)例子,清單3.4,先對(duì)一個(gè)變量賦值,然后使用第二次賦值來(lái)改變變量的值。第二次賦值使原有的數(shù)值加一。 清單3.4 change_scalars.php3--改變變量的值 <?PHP $int_page_number = 46; $int_page_number =$int_page_number +1; ?> 注意:在PHP編程中,永遠(yuǎn)不必聲明、定義或分配簡(jiǎn)單的數(shù)據(jù)類(lèi)型(標(biāo)量或數(shù)組),第一次使用變量名就相當(dāng)于定義它。 3.2.2 數(shù)組變量 一個(gè)數(shù)組就是把一系列數(shù)字和字符串作為一個(gè)單元來(lái)處理。數(shù)組中的每一片信息都被認(rèn)為是數(shù)組的一個(gè)元素。例如,可以用數(shù)組存儲(chǔ)一個(gè)文件中的所有行或者存儲(chǔ)一個(gè)地址列表。 只要不用數(shù)字作為數(shù)組變量名的第一個(gè)字符,而且在創(chuàng)建數(shù)組名時(shí)只使用數(shù)字、字母和下劃線的時(shí)候,就不必操心數(shù)組變量的命名規(guī)則。 數(shù)組元素有三種方法設(shè)置初始值,可以對(duì)每一個(gè)元素分別賦值: $arr_zoo['pelican'] = 'Bird with a big beak, '; $arr_zoo['cheetah'] = 'Fast cat. '; $arr_zoo['horse'] = 'Four-legged animal. '; 也可以用下面的方法同時(shí)對(duì)多個(gè)元素賦值: $arr_zoo = arry( 'pelican' => 'Bird with a big beak. ' , 'cheetah'=> 'Fast cat. ' , 'horse' => 'Four-legged animal. ' ); 最后,最快的方法是簡(jiǎn)單在數(shù)組的下一個(gè)空余位置上增加一個(gè)元素,第一個(gè)位置是0,第二個(gè)位置是1,依次類(lèi)推。例如,下面的代碼給$arr_names數(shù)組增加了三個(gè)元素,這三個(gè)元素的下標(biāo)分別為1、2和3(假設(shè)這個(gè)數(shù)組沒(méi)有其它元素存在)。 $arr_names[] = 'Mitch'; $arr_names[] = 'Gerry'; $arr_names[] = 'Tim'; 在知道了如何給數(shù)組元素賦值之后,下一步讓我們討論一下如何如何獲取這些值。 為了得到數(shù)組名為arr_zoo,且數(shù)組下標(biāo)為'pelican'的值時(shí),可以使用以下方法: $key = 'pelican' $value = $arr_zoo[$key] 這兩行代碼運(yùn)行以后,$value的值變?yōu)?bird with a big beak'。文本字符串也可以用來(lái)指定要哪一個(gè)數(shù)組元素的值。例如: $value = $arr_zoo[pelican]; 用于數(shù)組下標(biāo)的字符值不應(yīng)該用單引號(hào)括起來(lái)(Perl稱它們?yōu)槁阍~)。由于可以使用裸詞,數(shù)組下標(biāo)中不應(yīng)該有空格。 注意:當(dāng)讀取一個(gè)并沒(méi)有賦值的數(shù)組元素時(shí),PHP返回空或零字符串。 PHP數(shù)組的數(shù)組下標(biāo)和數(shù)組值是成對(duì)出現(xiàn)的,由于沒(méi)有一個(gè)很方便的方法顯示數(shù)組中的所有值,這個(gè)事實(shí)偶爾會(huì)引起一些麻煩。在測(cè)試和調(diào)試程序階段中,這種功能性的缺乏可能會(huì)妨礙程序的開(kāi)發(fā)。雖然本書(shū)中還沒(méi)有提及這些函數(shù),清單3.5提供了一個(gè)這樣的函數(shù)。現(xiàn)在只要把dump_array函數(shù)當(dāng)成黑箱子即可,等讀完本書(shū)后,就會(huì)明白此函數(shù)的含義。把這個(gè)例子當(dāng)成模板,程序中的注釋說(shuō)明了如何使用這個(gè)函數(shù)。圖3.3顯示了使用dump_array函數(shù)的結(jié)果。 清單3.5 dump_array.php3--改變變量的值 Page 42, 清單 3.5 注意:dump_array函數(shù)沒(méi)有按特殊的順序顯示數(shù)組下標(biāo)和數(shù)組值對(duì)。第四章討論了可以對(duì)數(shù)組進(jìn)行排序的函數(shù)。 Page 43,圖3.3, 圖3.3 dump_array函數(shù)顯示任一個(gè)數(shù)組的數(shù)組下標(biāo)和值 以上我們只采用了字符串作為數(shù)組下標(biāo),讓我們思維更活躍一點(diǎn),考慮一下下面所創(chuàng)建的數(shù)組初始值的數(shù)組下標(biāo)是什么? $arr_mixed = array( 1 ,434 , 'Jake' => '23 First Lane' , 'Rebecca' ); arry_mixed數(shù)組的數(shù)組下標(biāo)分別是0、1、Jake和2。如果數(shù)組下標(biāo)沒(méi)有給定,PHP就自動(dòng)提供一個(gè)。默認(rèn)的數(shù)組下標(biāo)是以0開(kāi)始的,以后當(dāng)數(shù)組下標(biāo)沒(méi)有賦值時(shí)默認(rèn)值每次加一。 可以用標(biāo)量變量替換所有的數(shù)值下標(biāo)(數(shù)字和字符串),并仍能獲取它們?cè)械闹怠?梢赃@樣寫(xiě): $key = 1; echo $arr_mixed[$key]; 以上兩行將顯示434,讓我們用這個(gè)例子顯示PHP是如何按照需要,而把數(shù)字?jǐn)?shù)據(jù)類(lèi)型轉(zhuǎn)換成字符數(shù)據(jù)類(lèi)型的。在以下的代碼行中,數(shù)組下標(biāo)被初始化成字符串: $key = '1'; echo $arr_mixed[$key]; 這兩行代碼也顯示434,表明了PHP可以自動(dòng)地把字符串轉(zhuǎn)換成數(shù)值。 有時(shí),可能需要在數(shù)組初始化過(guò)程中使用變量。例如: $int_page_number = 434; $str_first_name = 'Jake'; $arr_mixed = array( 1 ,$int_page_number ,$str_first_name => '23 First Lane' ,'Rebecca' ); 3.2.3 多維數(shù)組 對(duì)于大多數(shù)程序來(lái)說(shuō),僅有一個(gè)簡(jiǎn)單的數(shù)值列表是很不夠的。例如,假如既要存書(shū)的總頁(yè)數(shù),又要存儲(chǔ)出版商的名字。這需要使用兩個(gè)列表:lst_number_of_pages和lst_publisher_names,在需要增加或修改信息的時(shí)候,就很不方便了。并且保證兩個(gè)列表的同步也留下了隱患。 多維數(shù)組提供了一個(gè)極靈活的數(shù)據(jù)結(jié)構(gòu),每一個(gè)數(shù)組元素均可以包含另外一個(gè)數(shù)組。遺憾的是,多維數(shù)組(multidimensional)名字實(shí)在太長(zhǎng)--我更喜歡稱它為散列表,它體現(xiàn)了在存貯器中數(shù)據(jù)結(jié)構(gòu)是如何組織的。 注意:我不打算詳細(xì)講述散列表的數(shù)據(jù)結(jié)構(gòu)是怎樣有效的使用存儲(chǔ)空間,以及它為什么能快速找到域值。不過(guò),如果你有興趣的話,我建議閱讀一本數(shù)據(jù)結(jié)構(gòu)方面的書(shū),以便進(jìn)一步學(xué)習(xí)。 散列表可以按以下格式進(jìn)行初始化: $arr_books = array( '0-679-76781-9' => array( 'name' => 'The Demolished Man' ,'pages' => 243 ,'publisher' => 'Vintage Books' ) , '0-312-85395-5' => array( 'name' => 'Children of the Mind' , 'pages' => 349 , 'publisher' => 'Tor Books' ) ); 在上例中使用了每本書(shū)的ISBN號(hào)作為檢索數(shù)組$arr_books的散列表下標(biāo),且每本書(shū)都有它自己的子散列表,用以描述其自己的特定信息。為了查詢子散列表中的信息,正常的數(shù)組下標(biāo)被擴(kuò)展為采用兩個(gè)下標(biāo),例如:要查《The Demolished Man》一書(shū)的頁(yè)數(shù)有多少,可以用以下的表達(dá)式 $arr_books[0-31-85395-5][pages] 你會(huì)發(fā)現(xiàn)散列表十分靈活方便。毫不夸張地說(shuō),在我寫(xiě)的每一個(gè)程序中都會(huì)使到散列表。之所以這樣,其中一個(gè)很重要的原因就是散列表使用起來(lái)是如此的靈活,以至于隨時(shí)都可以加入需要的元素。假如在程序運(yùn)行過(guò)程中,你覺(jué)得應(yīng)該將作者名也存進(jìn)去的話,那么沒(méi)有問(wèn)題,只需簡(jiǎn)單的在散列表中加入如下信息: $arr_books[0-312-85395-5][author] = 'Orson Scott Card'。 注意散列表數(shù)據(jù)結(jié)構(gòu)允許在一個(gè)子散列表中加入一項(xiàng)內(nèi)容,而不會(huì)影響其它數(shù)據(jù)。當(dāng)開(kāi)始使用PHP從多個(gè)數(shù)據(jù)庫(kù)表中收集信息時(shí),散列表能用來(lái)組合這些信息。例如,當(dāng)使用一個(gè)涉及到多個(gè)產(chǎn)品供應(yīng)商的產(chǎn)品數(shù)據(jù)庫(kù)時(shí),可以從第一個(gè)產(chǎn)品供應(yīng)商開(kāi)始將相關(guān)信息存入散列表中。然后,再讀取第二個(gè)產(chǎn)品供應(yīng)商的信息,并將這些新信息寫(xiě)入同一個(gè)散列表中。將所有產(chǎn)品供應(yīng)商信息讀取、并全部寫(xiě)入散列表以后,這一個(gè)散列表就包含了所有的貨存信息。 在前面給出的3.5列表中的函數(shù)dump_array,闡明了散列表的組織結(jié)構(gòu)。圖3.4顯示了使用dump_array函數(shù)解釋的散列表$arr_books的組織結(jié)構(gòu)。 Page 46, 圖3.4 圖3.4 使用dump_arry函數(shù)顯示的散列表 3.2.4 變量替換 雙引號(hào)字符串還有一個(gè)特性,由于涉及到變量,我們以前還沒(méi)有討論。既然現(xiàn)在我們已經(jīng)對(duì)PHP變量是如何工作的已經(jīng)很熟悉了,讓我們?cè)龠M(jìn)一步討論一下雙引號(hào)字符串。 變量替換 意味著PHP可以用在雙引號(hào)字符串中變量的值替換其名字,把這個(gè)概念延伸到通常含義即是變量代表了它們的值。例如,如果$int_count為14,那么$int_count + 14就真正是14 + 14。PHP,以及大多數(shù)計(jì)算機(jī)語(yǔ)言,這種替換是在字符串內(nèi)完成的。例如: $str_size = 'big'; echo "Jack was a $str_size man. "; 將顯示 Jack was a big man. 但是,如果需要在變量后面立即跟隨非空格或非標(biāo)點(diǎn)符號(hào)外的其它字符時(shí),就會(huì)出現(xiàn)問(wèn)題。以下代碼段顯示了這是如何發(fā)生的: $str_size = 'big'; echo "Jack was a $str_sizeger man. "; PHP不會(huì)尋找后面跟有字符串('ger')的變量($str_size),而是尋找變量名為$str_sizeger的變量。把變量名用大括號(hào)括起來(lái)可以解決這個(gè)問(wèn)題: $str_size = 'big'; echo "Jack was a ${str_size}ger man. "; 在使用過(guò)變量替換多次之后,字符串和變量的組合就變的很自然。清單3.6顯示了一些變量替換的例子。 清單3.6 interpolation.php3--變量替換的例子 Page 47 第7行= Page 48 第13行 清單 3.6 圖3.5顯示了散列表$arr_books有三級(jí)組成,第三級(jí)包含有書(shū)籍的名稱。正常情況下可以用類(lèi)似下面的方式訪問(wèn)散列表的命名元素: echo "The name is $arry_books[lst_books][0-679-76781-9][name]."; // The previous line of code produces a PHP parse error. Page 48 圖3.5 圖3.5 使用標(biāo)量和數(shù)組變量進(jìn)行變量替換 然而不幸的是,當(dāng)使用變量替換時(shí),PHP3不允許同時(shí)使用多于一個(gè)的數(shù)組下標(biāo)。PHP的安全存取書(shū)籍名的方法如下: $second_level = $arr_books[lst_books]; $third_levwl = $second_level[0-679-76781-9]; echo "The name is $third_level[name]."; 3.2.5 動(dòng)態(tài)變量名 PHP允許用戶動(dòng)態(tài)的創(chuàng)建變量名。當(dāng)程序運(yùn)行時(shí),使用特殊的符號(hào)可以創(chuàng)建新的變量名: // store the name of the dynamic variable. $scl_dynamic = 'str_name'; // assign a value to the dynamic variable. $$scl_dynamic = 'John'; echo "\$str_name = $str_name\n"; 此程序?qū)@示 $str_name =John 盡管動(dòng)態(tài)變量名存在一些吸引使用的方面,但是我在二十年的編程經(jīng)歷中,從沒(méi)有發(fā)現(xiàn)有使用它們的需要。數(shù)組的靈活性應(yīng)該足以解決大多數(shù)有可能需要使用動(dòng)態(tài)變量名的問(wèn)題。 3.3 常量 常量可以幫助你以一種簡(jiǎn)單的方法使程序增加可讀性。使用BUFFER_SIZE比直接使用1024使程序更容易讓人理解。此外,由于大多數(shù)常量都在程序文件的開(kāi)頭部分定義,對(duì)它們進(jìn)行更改也非常容易。 可以同時(shí)定義數(shù)字常量和字符串常量。在以下的例子顯示了如何這樣做: <?php define('PI', 3.1415); define('HOST', '192.168.0.2'); ?> 除了不需要在常量名前加$符號(hào)外,存取常量值和存取變量值非常類(lèi)似。在上面定義的兩個(gè)常量可以用如下的方式存取: echo 'PI = ' . PI; echo 'HOST = ' . HOST; 因?yàn)椴皇褂贸跏嫉?符號(hào),所以變量替換并不適合常量。 3.4 操作符 操作符指揮計(jì)算機(jī)應(yīng)該進(jìn)行什么操作。我們可以這樣理解操作符,就好比你在向汽車(chē)司機(jī)發(fā)布“左轉(zhuǎn)”或“右轉(zhuǎn)”的命令。這些命令可以認(rèn)為是方向操作符,與進(jìn)行加或減操作的數(shù)學(xué)操作符有同樣的操作方式。然而在另一方面,在汽車(chē)行駛時(shí)對(duì)司機(jī)大喊“停車(chē)!”的話,這將凌駕于其他命令之上。也就是說(shuō),“停車(chē)”命令級(jí)別高于“左轉(zhuǎn)”和“右轉(zhuǎn)”。 現(xiàn)在,對(duì)大部分PHP操作符你應(yīng)該都已經(jīng)比較熟悉了。在學(xué)習(xí)操作符時(shí),請(qǐng)相信直覺(jué),已經(jīng)知道的一些定義也許仍然是對(duì)的。 所有操作符都是指揮操作數(shù)的。所謂操作數(shù)就是可以在其上進(jìn)行操作的對(duì)象。實(shí)際上,操作數(shù)指的就是數(shù)值、變量或者表達(dá)式。在本章前面已經(jīng)學(xué)習(xí)了什么是數(shù)值和變量,表達(dá)式指的是由操作符和操作數(shù)組成的,進(jìn)行運(yùn)算的一個(gè)單元。 操作數(shù)本身就具有遞歸的屬性。在PHP中,表達(dá)式4/2,由兩個(gè)操作數(shù)和一個(gè)除號(hào)組成,可以認(rèn)為是一個(gè)值為2的操作數(shù)。再舉一個(gè)例子:表達(dá)式(5+9)-7,由兩個(gè)操作數(shù)和減號(hào)組成,第一個(gè)操作數(shù)是(5+9),第二個(gè)操作數(shù)為7。 3.4.1 操作符的優(yōu)先級(jí) 在每一種計(jì)算機(jī)語(yǔ)言中,操作符的優(yōu)先級(jí)問(wèn)題都是很重要的,PHP也不例外。所謂優(yōu)先級(jí)指的是哪一個(gè)操作符應(yīng)該首先計(jì)算。PHP根據(jù)相關(guān)性決定哪些操作符應(yīng)放在一起。例如,減號(hào)操作符有右到左的相關(guān)性,這是因?yàn)樗⒓从绊懰疫叺牟僮鲾?shù)。你也許沒(méi)有認(rèn)識(shí)到這一點(diǎn),甚至用于存取數(shù)組元素的方括號(hào)也是操作符。表3.2包括了所有的操作符,但是不必?fù)?dān)憂它們的優(yōu)先順序。憑經(jīng)驗(yàn),你也許會(huì)發(fā)現(xiàn)操作符優(yōu)先級(jí)僅僅影響算術(shù)操作符和邏輯操作符。 表3.2是一系列操作符,并且是按照優(yōu)先級(jí)劃分級(jí)別--級(jí)別越高,它的優(yōu)先級(jí)也越高。在同一級(jí)的操作符有同樣的優(yōu)先級(jí),并從左到右進(jìn)行計(jì)算,否則,較高的優(yōu)先級(jí)先計(jì)算。使用括號(hào)可以精確的控制優(yōu)先順序,任何在括號(hào)的東西都應(yīng)該首先進(jìn)行計(jì)算。 表3.2 優(yōu)先級(jí)的順序和操作符的相關(guān)性 級(jí)別 操作符 描述 相關(guān)性 15 => 在數(shù)組定義中連接數(shù)組下標(biāo)與值 從左到右 14 -> 類(lèi)操作符 從左到右 13 ? : 三重操作符 從左到右 12 <, <=,>, >= 小于,小于或等于,大于,大于或等于 沒(méi)有 11 ==, !=, <> 等于,不等于,不等于 沒(méi)有 10 +, -, !, ~ 正號(hào),負(fù)號(hào),邏輯或,位轉(zhuǎn)換 從右到左 09 ++, -- 加一,減一 從左到右 08 <<, >> 左移位,右移位 從左到右 07 /, *, % 除,乘,取模 從左到右 06 +, - 加,減 從左到右 05 &, . 位邏輯與,字符串連接 從左到右 04 |, ^ 位邏輯或,位邏輯異或 從左到右 03 ||, && 邏輯或,邏輯與 從左到右 02 =, +=, -=, *=,/=, .=, %=, &=, |=, ^=, <<=, >>= 賦值操作符 從左到右 01 or and xor 低優(yōu)先級(jí)或 低優(yōu)先級(jí)與 低優(yōu)先級(jí)異或 從左到右 在討論單個(gè)操作符的例子之前,讓我們看看有關(guān)操作符優(yōu)先級(jí)的一些特定例子。這樣,我們可以驗(yàn)證在表3.2中列出的優(yōu)先級(jí)的級(jí)別。 下面的例子顯示了算術(shù)減號(hào)操作符比加一操作符有更高的級(jí)別: $a = 5; $b = $a++; echo "a = $a<br>"; echo "b = $b<br>"; 以上代碼行結(jié)果將顯示 a = 6 b = 5 在變量$a加一之前,變量$b被賦予$a的值。現(xiàn)在讓我們看看在負(fù)算術(shù)加號(hào)起作用前,有什么事情發(fā)生: $a = 5; $b = -$a++; echo "a = $a<br>"; echo "b = $b<br>"; 以上代碼行結(jié)果將顯示 a = 6 b = -5 只有在變量$a的值進(jìn)行負(fù)操作(換句話說(shuō)為-6),然后進(jìn)行加一操作的時(shí)候,變量$b的最后結(jié)果值才為-5。這證明了負(fù)號(hào)操作符比加一操作符的級(jí)別更高。1 由于括號(hào)內(nèi)部的操作總是首先執(zhí)行,所以下面的例子中清楚地顯示了除號(hào)比加號(hào)有更高的級(jí)別: // parens around the first two operands. echo (5 + 9) / 2; echo "<br>"; // parens around the second two operands. echo 5 + (9 / 2); echo "<br>"; // the default precedence. echo 5 + 9 / 2; echo "<br>"; 以上代碼行結(jié)果將顯示: 7 9.5 9.5 最后一行所顯示的是采用默認(rèn)優(yōu)先級(jí)的結(jié)果,因?yàn)榻Y(jié)果(9.5)和第二行的結(jié)果是一致的,所以可以得出結(jié)論,除號(hào)操作符是在加號(hào)操作符前先執(zhí)行的。 等號(hào)操作符和其它操作符一樣也是操作符,而沒(méi)有什么不同,知道這一點(diǎn)也很重要,等號(hào)操作符同樣也有優(yōu)先級(jí)。這個(gè)概念可能和直覺(jué)不一樣,下面的例子說(shuō)明了這個(gè)概念。 首先我們用一個(gè)簡(jiǎn)單的賦值語(yǔ)句,把變量$a設(shè)為1。 $a = 1; 右面的操作數(shù)(1),把值賦予了左面的操作數(shù)($a)。現(xiàn)在讓我們看一個(gè)比較費(fèi)解的例子,把一個(gè)賦予變量的結(jié)果賦予另一個(gè)變量: $b = $a = 1; 上面的代碼行把數(shù)字1賦予變量$b,這是因?yàn)橛?jì)算$a = 1的結(jié)果為1。由于可能會(huì)引起混亂,所以我不推薦在程序中使用這種風(fēng)格,然而也可以偶爾隨手使用。現(xiàn)在讓我們?cè)谝陨系拇a行中增加and操作符。這樣,變量$b是賦予0,還是1的問(wèn)題也就會(huì)被解決。如果 = 操作符的優(yōu)先級(jí)高于and操作符,變量$b將被賦予值$a = 1。如果and操作符優(yōu)先級(jí)高于 = 操作符,那么$b將被賦予值1和0的與,即0: $b =$a =1 and 0; 在以上的代碼行執(zhí)行以后,得出結(jié)果是,變量$a和變量$b的值都為1。這樣,可以得出 = 操作符有比較高的優(yōu)先級(jí)。 如果想使and 操作符首先執(zhí)行(人為地提高它的優(yōu)先級(jí)),可以使用以下的模式: $b = (($a = 1) and 0); 以上代碼行的結(jié)果是,$a被賦予1,且$b被賦予0。 本章的其它部分將著重討論不同的操作符,并且討論它們是如何工作。=>操作符在本章較早“數(shù)組變量”的部分已經(jīng)討論過(guò)了。而->操作符也將在第十章“面向?qū)ο蟆敝杏懻摗? 3.4.2三重操作符 三重操作符是在給定的條件下,在兩個(gè)選擇項(xiàng)中做選擇。例如:如果公園是在一英里內(nèi),那么約翰將會(huì)步行去;否則,他會(huì)駕車(chē)去。語(yǔ)法如下: CONDITION-PART ? TRUE-PART : FALSE-PART 這是以下語(yǔ)句的縮略形式: if (CONDITION-PART) { TREU-PART } else { FALSE-PART } 在第四章“程序控制”中,能找到有關(guān)if語(yǔ)句的更多信息。 在三重操作符和它的操作數(shù)執(zhí)行后,通常把結(jié)果值賦給變量: $bin_page_two = ($int_page_number == 2) ? 1 : 0; $bin_page_two的值依賴于此語(yǔ)句中條件部分CONDITION-PART($int_page_number==2)運(yùn)行的結(jié)果。如果CONDITION-PART結(jié)果為真,那么TRUE-PART的值將賦給$bln_page_two。如果CONDITION-PART結(jié)果為假,那么FALSE-PART的值將賦給$bln_page_two。 bln_前綴表明此變量應(yīng)該只保存邏輯值。換句話說(shuō),只保存1或0。 在一些參考書(shū)中,三重操作符也被稱作條件操作符,并且它常用來(lái)控制運(yùn)行代碼的哪一個(gè)部分。然而,我不推薦使用此操作符,因?yàn)樗赡苁沟贸绦蚋y讀。 在下面的例子中,你將有機(jī)會(huì)看到這些語(yǔ)句是如何費(fèi)解。當(dāng)需要考慮多于兩個(gè)選擇時(shí),可以在三重操作符內(nèi)部嵌套使用另一個(gè)三重操作符。然而當(dāng)看到下面的例子的時(shí)候,就會(huì)發(fā)現(xiàn)這是些多么令人難懂的代碼。 1 ? $int_firstVar++ : $int_secondVar++; 0 ? $int_firstVar++ : $int_secondVar++; $int_firstVar = $int_temp == 0 ? $int_number_of_files++ : ($int_temp == 1 ? $int_number_of_records++ : ($int_number == 3 ? $int_number_of_bytes++ : $int_number_of_errors++)); 以這種方法編程,會(huì)使程序更難理解且難于維護(hù)。而使用if語(yǔ)句,程序就會(huì)變得好看且易于維護(hù)代碼。更詳細(xì)信息參見(jiàn)第四章“程序控制”。 3.4.3 算術(shù)操作符 算術(shù)操作符所反映的東西在學(xué)校中已經(jīng)學(xué)過(guò)了。加、減、乘和除是絕大多數(shù)算術(shù)語(yǔ)句中最基本的東西。取模操作符有一點(diǎn)深?yuàn)W;它是取兩個(gè)操作數(shù)相除的余數(shù)。例如,10 % 7等于3,這是由于10 / 7等于1,余3。 當(dāng)程序需要在一列表中循環(huán),并且每若干項(xiàng)需要運(yùn)行一些代碼時(shí),取模操作符的作用是無(wú)法估量的。清單3.7顯示了當(dāng)每十項(xiàng)運(yùn)行一些代碼時(shí),應(yīng)該怎么做。 清單3.7 modulus.php3--每十項(xiàng)顯示一段消息 <?php for ($index = 1; $index <= 100; $index++) { if ($index % 10 == 0) { echo "$index<br>"; } } ?> 此程序的輸出結(jié)果應(yīng)該如圖3.6所示。 Page 56 圖3.6 圖3.6使用取模操作符,每十個(gè)循環(huán)項(xiàng)顯示一次 注意是每十項(xiàng)顯示一次。當(dāng)改變?nèi)∧_\(yùn)算符右邊的數(shù)值時(shí),將改變?cè)谙@示前有多少項(xiàng)被忽略。改成15即意味著每十五項(xiàng)顯示一次消息。第四章“程序控制”將詳細(xì)地描述了if和for語(yǔ)句。 3.4.4 條件操作符 這些條件操作符將測(cè)試一個(gè)變量(或數(shù)字)和另一個(gè)變量之間的關(guān)系。例如,5是否大于12(5 GREATER THAN 12)?運(yùn)算條件操作符和它的操作數(shù)的結(jié)果總是真(值為1)或假(值為0)。表3.3顯示了在PHP中的條件操作符。 表3.3 PHP中的條件操作符 操作符 描述 判斷相等操作符 op1 == op2 如果op1等于op2,返回真。 例如,6==6為真。 op1 != op2 如果op1不等于op2,返回真。 例如,6!=7為真。 op1 <> op2 如果op1不等于op2,返回真。 例如,6<>7為真。 比較操作符 op1 < op2 如果op1小于op2,返回真。 例如,6<7為真。 op1 <= op2 如果op1小于或等于op2,返回真。 例如,7<=7為真。 op1 > op2 如果op1大于op2,返回真。 例如,6>5為真。 op1 >= op2 如果op1大于或等于op2,返回真。 例如,7>=7為真。 注意:認(rèn)識(shí)到等于操作符是兩個(gè)等號(hào),而不是一個(gè),這一點(diǎn)非常重要。人們經(jīng)常忘掉此規(guī)則,在測(cè)試條件中使用單個(gè)等號(hào),這種錯(cuò)誤經(jīng)常在編程過(guò)程中發(fā)生。 3.4.5 一元操作符 一元操作符只影響單個(gè)操作數(shù)。它們常用來(lái)改變操作數(shù)的符號(hào),以及把操作數(shù)的值加一或減一。加一即在它原有值的基礎(chǔ)上加一,減一即在它原有值的基礎(chǔ)上減一。表3.4列出了在PHP中的一元操作符。 表3.4一元算術(shù)操作符 操作符 描述 +op1 把操作數(shù)的正負(fù)號(hào)改變?yōu)橄嗤? -op1 把操作數(shù)的正負(fù)號(hào)改變?yōu)橄喾? !op1 取操作數(shù)的邏輯非 ~op1 轉(zhuǎn)換操作數(shù)的位值 ++op1 在操作數(shù)在起作用前,操作數(shù)值加一 --op1 在操作數(shù)在起作用前,操作數(shù)值減一 op1++ 在操作數(shù)在起作用后,操作數(shù)值加一 op1-- 在操作數(shù)在起作用后,操作數(shù)值減一 當(dāng)介紹到一元操作符時(shí),由于增加了難使用的負(fù)數(shù),而使操作符變得復(fù)雜。沒(méi)有幾個(gè)人會(huì)編寫(xiě)象這樣的數(shù)學(xué)語(yǔ)句:345 + -23。然而,在PHP中你可能使用354 + $int_gas_bill的語(yǔ)句,在這里$int_gas_bill代表$23.00的債務(wù);換句話說(shuō),這是一個(gè)負(fù)數(shù)。 使用正號(hào)操作符不會(huì)有任何影響,PHP會(huì)忽略它。單個(gè)負(fù)號(hào)操作符可以把一個(gè)正數(shù)變成負(fù)數(shù),或把一個(gè)負(fù)數(shù)變成正數(shù)。例如,如果有一個(gè)名為$int_first的變量,它的值為34。當(dāng)顯示時(shí),-$int_first將顯示-34。 邏輯非(!)操作符常用來(lái)把邏輯真轉(zhuǎn)換為邏輯假。例如,!34為零,且!0為真。 注意:邏輯真的值為1,邏輯假的值為0。 位轉(zhuǎn)換操作符是指把操作數(shù)的每一位都從1轉(zhuǎn)變?yōu)?,把0轉(zhuǎn)變?yōu)?。在我二十年的編程經(jīng)歷中,我從沒(méi)有覺(jué)得必須使用這個(gè)操作符。因此,我不再浪費(fèi)你的時(shí)間,提供有關(guān)與此的例子了。 如果++或--操作符出現(xiàn)在操作符的前面,那么操作數(shù)的值在起作用前,其值就加一或減一。如果++或--操作符出現(xiàn)在操作符后面,那么操作數(shù)的值在按需要起作用后,其值再加一或減一。清單3.8顯示了如何使用先加一的操作符。 清單3.8 preincrement.php3--使用先加一操作符 <?php // Original Way $int_number_of_pages = 5; $int_number_of_pages = $int_number_of_pages + 1; echo "$int_number_of_pages<br>"; // New Way $int_number_of_pages = 5; echo "++$int_number_of_pages<br>"; ?> 此程序運(yùn)行的結(jié)果如下: 6 6 新的編碼方式比原有的編碼方式要簡(jiǎn)短些。語(yǔ)句echo "++$int_number_of_pages<br>",首先$int_number_of_pages變量加一,然后執(zhí)行echo命令。 先減一操作符的使用方法和先加一操作符的使用方法一樣。下一個(gè)例子,清單3.9顯示了如何使用后加一操作符。 清單3.9 postincrement.php3--使用后加一操作符 <?php // Original Way $int_number_of_pages = 5; $int_current_page_number = $int_number_of_pages; $int_number_of_pages = $int_number_of_pages + 1; echo "$int_number_of_pages $int_current_page_number<br>"; // New Way $int_number_of_pages = 5; $int_current_page_number = $int_number_of_pages++; echo "$int_number_of_pages $int_current_page_number<br>"; ?> 此程序運(yùn)行的結(jié)果如下: 6 5 6 5 語(yǔ)句$int_current_page_number = $int_number_of_pages++,表示先把變量$int_number_of_page的值賦給$int_current_of_page,然后變量$int_number_of_page的值加一。這個(gè)例子有助于理解后加一操作符和后減一操作符不會(huì)影響在賦值操作符左邊變量的值。如果看到了后加一操作符和后減一操作符時(shí),要忽略它們,先執(zhí)行語(yǔ)句。然后,當(dāng)執(zhí)行完以后,然后按需要運(yùn)用后加一操作符和后減一操作符。 3.4.6 位操作符 位移動(dòng)操作符,如表3.5所示,常用來(lái)向左或右按給定次數(shù)移動(dòng)操作數(shù)中的所有位。當(dāng)需要乘或除整數(shù)值時(shí),就可以方便地使用比特操作符。例如,數(shù)值3也可等于二進(jìn)制的11,或((1*2)+1)。在二進(jìn)制中每一個(gè)字都表示一個(gè)比特位,它是在計(jì)算機(jī)內(nèi)存中可以修改的最小單元。 表3.5 比特操作符 操作符 描述 op1 << op2 左移操作符向左邊移動(dòng)比特位,丟棄最左面的比特位,并且最右面的比特位置0。每向左移動(dòng)一位相當(dāng)于op1乘以2,但效率更高。 op1 >> op2 右移操作符向右邊移動(dòng)比特位,丟棄最右面的比特位,并且最左面的比特位置0。每向右移動(dòng)一位相當(dāng)于op1除以2,但效率更高。 op1 & op2 與操作符比較兩個(gè)操作數(shù)相對(duì)應(yīng)的比特位,如果兩個(gè)比特位都為1,那么結(jié)果為1;否則,返回0。 op1 | op2 或操作符比較兩個(gè)操作數(shù)相對(duì)應(yīng)的比特位,如果兩個(gè)比特位有一位為1,那么結(jié)果為1;否則,返回0。 op1 ^ op2 異或操作符比較兩個(gè)操作數(shù)相對(duì)應(yīng)的比特位,如果兩個(gè)比特位相同,那么結(jié)果為1;否則,返回0。 下面的例子中用>>操作符表示除以4。 $int_a = 128; $int_b = $int_s >> 2; echo "$int_b<br>"; 此程序運(yùn)行的結(jié)果如下: 32 現(xiàn)在讓我們看看在移動(dòng)操作之前和之后變量的位模式。首先,$int_a被賦予128(十進(jìn)制)或10000000(二進(jìn)制)。然后$int_a的值向左移動(dòng)兩次。所以,移動(dòng)后的值為00100000或32,然后把32賦給變量$int_b。 當(dāng)向右移動(dòng)比特位時(shí),最右邊的比特位就會(huì)丟失。在下面的例子中,用>>操作符代替除以8的操作: $int_a = 129; $int_b = $int_a >> 3; echo "$int_b<br>"; 此程序運(yùn)行的結(jié)果如下: 16 因?yàn)?6的比特值為00010000,可以發(fā)現(xiàn)最右邊的比特位消失了。這里有一個(gè)用<<操作符的例子。我們把128乘以8: $int_a = 128; $int_b =$int_a << 3; echo "$int_b<br>"; 此程序運(yùn)行的結(jié)果如下: 1024 正如所能看到的,1024的值是八比特位所能表示的最大值。這說(shuō)明能使用的比特位并不限于一個(gè)字節(jié)。事實(shí)上,PHP使用一個(gè)標(biāo)量所表示的字節(jié)數(shù)量是有限制的,在大多數(shù)情況下,這個(gè)限制為四。 3.4.7 字符串連接操作符 字符串相加操作符把兩個(gè)字符串連接起來(lái)。如果兩個(gè)操作數(shù)中有一個(gè)是數(shù)字時(shí),它將自動(dòng)轉(zhuǎn)化為字符串。下面顯示的例子中進(jìn)行了自動(dòng)轉(zhuǎn)換: $str_a = "This box can hold " . 55 . " items."; echo "$str_a<br>"; 這些代碼運(yùn)行的結(jié)果如下: This box can hold 55 items. 數(shù)字55自動(dòng)轉(zhuǎn)換成字符串,然后再和其它字符串相結(jié)合。注意在最終字符生成時(shí),字符文本中有空格,數(shù)字兩邊也有空格;這樣做可以使句子更容易讀懂。 也可以用變量當(dāng)做操作數(shù),進(jìn)行如下所示的連接操作: $str_a = 'AAA'; $str_a = 'BBB'; $str_c = $str_a . $str_b; echo "$str_c<br>"; 這些代碼運(yùn)行的結(jié)果如下: AAABBB 注意字符串連接時(shí)不需要加入空格或者其它分隔符。如果希望字符串連接以后之間有空格的話,必須保證至少在一個(gè)字符串中有空格字符,位置在第一個(gè)字符串的尾部,或是在第二個(gè)字符串的首部。 3.4.8 邏輯操作符 邏輯操作符執(zhí)行布爾邏輯操作,或者稱為真/假邏輯操作。在這樣一個(gè)句子中:“如果約翰發(fā)燒,而且鼻塞或者耳朵痛,并且年齡不超過(guò)60歲的話,那么約翰就是感冒了。”該句中的“和”(and),“或”(or)以及“非”(not)就是邏輯操作符。 邏輯操作符常用于程序的if 或while控制語(yǔ)句中。控制語(yǔ)句將在下章“程序控制”中講述,然而,在這里我們可以先對(duì)邏輯操作符做一解釋。表3.6中給出了PHP的邏輯操作符。 表3.6 邏輯操作符 操作符 說(shuō)明 op1 && op2 對(duì)兩個(gè)操作數(shù)進(jìn)行邏輯與操作 op1 || op2 對(duì)兩個(gè)操作數(shù)進(jìn)行邏輯或操作 op1 and op2 對(duì)兩個(gè)操作數(shù)進(jìn)行邏輯與操作 op1 or op2 對(duì)兩個(gè)操作數(shù)進(jìn)行邏輯或操作 op1 xor op2 對(duì)兩個(gè)操作數(shù)進(jìn)行邏輯異或操作 邏輯操作符可以控制程序,根據(jù)多個(gè)不同條件來(lái)決定應(yīng)該執(zhí)行什么動(dòng)作。每一個(gè)操作符和操作數(shù)運(yùn)算后都會(huì)得出一個(gè)真或假值。在下面的例子中演示了使用邏輯條件的幾種不同方法。 邏輯運(yùn)算符與(&&)用于確定兩個(gè)操作數(shù)是否都為真。表3.7給出了使用與(&&)操作的四種不同組合的結(jié)果值。 表3.7 與(&&)操作結(jié)果表 op1 op2 op1&&op2 0 0 0 1 0 0 0 1 0 1 1 1 下面的代碼顯示了如何使用與(&&)操作符: if ($int_a == 10 && $int_b == 9) { echo 'Error!'; }; 如果兩個(gè)操作數(shù)至少有一個(gè)為假時(shí),都不會(huì)執(zhí)行echo命令。順便說(shuō)一下,在此例子中顯示了==操作符有比&&操作符更高的優(yōu)先級(jí)。每一個(gè)==操作符都先執(zhí)行,且結(jié)果值被當(dāng)成&&操作符的兩個(gè)操作數(shù)。 或操作符(||)用于確定兩個(gè)操作數(shù)是否有一個(gè)為真。表3.8給出了使用或(||)操作的四種不同組合的結(jié)果值。 表3.8 或(||)操作結(jié)果表 Op1 op2 op1||op2 0 0 0 1 0 1 0 1 1 1 1 1 下面的代碼顯示了如何使用或(||)操作符: if ($int_a == 10 || $int_b == 9) { echo 'Error!'; }; 如果兩個(gè)==操作符執(zhí)行的結(jié)果有一個(gè)為真時(shí),那么都會(huì)執(zhí)行echo命令。 邏輯與和邏輯或操作符都有短路特性。邏輯與操作符的目的是確定兩個(gè)操作數(shù)是否都為真。如果PHP確定第一個(gè)操作數(shù)為假時(shí),那么就不需判斷第二個(gè)操作數(shù)。邏輯或操作符的目的是確定兩個(gè)操作數(shù)是否至少有一個(gè)為真。如果第一個(gè)操作數(shù)為真時(shí),那么就不需判斷第二個(gè)操作數(shù)。 如果不小心的話,那么短路特性可能會(huì)成為失誤的源泉。例如,在下面的代碼段中,如果$int_a++執(zhí)行結(jié)果為真時(shí),那么變量$int_b將不會(huì)加一。 if ($int_a++ || $int_b++) { echo "true<br>"; echo "a=$int_a b=$int_b<br>"; } 小心:也許你會(huì)使用以下代碼來(lái)確定$int_a是否等于9或10。但請(qǐng)不要這樣做。 if ($int_a == (9 ||10)) { echo "Error!<br>"; }; PHP不能正確執(zhí)行以上代碼。測(cè)試$int_a的正確方法是明確地書(shū)寫(xiě)每一個(gè)需要判定是否為真的子條件。正確的代碼方法如下: if ($int_a == 9 || $int_a == 10) { echo "Error!<br>"; }; 與、或和異或這些優(yōu)先級(jí)比較低的操作符,和它們較高優(yōu)先級(jí)的同伴一樣可以執(zhí)行同樣的操作。然而,它們的低優(yōu)先級(jí)特征,使得它們非常適合有條件的執(zhí)行一些代碼,而不必重寫(xiě)if語(yǔ)句。不幸的是,低優(yōu)先級(jí)邏輯操作符使用的大多數(shù)情況涉及到函數(shù),有關(guān)話題本書(shū)還沒(méi)有討論過(guò)。在不考慮有關(guān)函數(shù)細(xì)節(jié)的條件下,讓我們先看一個(gè)或操作符的例子。 每一個(gè)PHP函數(shù)都返回一個(gè)值,這個(gè)值又常被當(dāng)成操作數(shù)。因而,操作符的短路特性常用于控制程序流。如果或操作符的第一個(gè)操作數(shù)為真時(shí),那么將執(zhí)行第二個(gè)操作。反過(guò)來(lái)看,如果第一個(gè)操作結(jié)果為假時(shí),那么將進(jìn)行第二個(gè)操作。當(dāng)函數(shù)出現(xiàn)錯(cuò)誤時(shí),大多數(shù)函數(shù)返回假。因此,僅僅當(dāng)出現(xiàn)錯(cuò)誤時(shí),或操作符可用來(lái)執(zhí)行代碼。例如: 0 or die("Problem connecting to printer.<br>"); echo "Program Over.<br>"; 這些代碼運(yùn)行的結(jié)果為 Problem connecting to printer. 把或操作符左邊的操作數(shù)改為1時(shí),將顯示 Program Over. 3.4.9 賦值操作符 本章以前提到的例子中都使用到了基本的賦值操作符。除了基本的賦值操作符外,PHP有一些簡(jiǎn)單的賦值操作符和另一個(gè)操作符組合在一起的快捷賦值操作符。例如,代替書(shū)寫(xiě)$int_a = $int_a / $int_b,而可以簡(jiǎn)寫(xiě)為$int_a /= $int_b。使用快捷操作符的優(yōu)點(diǎn)是,除了可以少輸入字符外,使用賦值操作符的目的也會(huì)變得非常清晰。 表3.9列出了在PHP中的所有賦值操作符。在讀完本章中其它部分中對(duì)不同操作符類(lèi)型的介紹之后,應(yīng)該對(duì)下表中描述的所有操作符都很熟悉。 表3.9 賦值操作符 操作符 描述 var = op1 把op1的值賦給var。 var += op1 把var+op1的值賦給var。 var -= op1 把var-op1的值賦給var。 var *= op1 把var*op1的值賦給var。 var /= op1 把var/op1的值賦給var。 var %= op1 把var%op1的值賦給var。 var .= op1 把var.op1的值賦給var。 var &= op1 把var&op1的值賦給var。 var |= op1 把var|op1的值賦給var。 var ^= op1 把var^op1的值賦給var。 var <<= op1 把var<<op1的值賦給var。 var >>= op1 把var>>op1的值賦給var。 你會(huì)發(fā)現(xiàn)賦值操作符的另一方面不是憑直覺(jué)可以想到的,可以象其它操作符一樣使用賦值操作符。例如,以下的代碼將把變量$int_a和$int_b都賦予3: $int_a = $int_b = 3; 3.5 總結(jié) 本章介紹了有關(guān)數(shù)值、變量、常量和操作符的概念。數(shù)值是直接放在源碼中的數(shù),并且程序不能改變它的值。變量放在保存程序數(shù)據(jù)的計(jì)算機(jī)內(nèi)存中。之所以叫變量,是因?yàn)榭梢园葱枰x予不同的值。常量從本質(zhì)上說(shuō)是命名的數(shù)字(例如π),它對(duì)程序歸檔來(lái)說(shuō)有用,并且使代碼更容易安排。操作符是告訴計(jì)算機(jī)要做什么操作。 數(shù)值有時(shí)被稱為硬編碼的數(shù),你應(yīng)該已經(jīng)理解了數(shù)值,以及它們的三種不同的表示方式,十進(jìn)制、八進(jìn)制和十六進(jìn)制。非常大或非常小的值可以使用科學(xué)表示法來(lái)描述。 字符串有一點(diǎn)復(fù)雜,單引號(hào)字符串、雙引號(hào)字符串和反引號(hào)字符串都常用來(lái)保存一系列字符。反引號(hào)字符串還有一個(gè)其它的作用,它們告訴PHP把字符串送到操作系統(tǒng)去執(zhí)行。 轉(zhuǎn)義字符常用來(lái)表示難于從鍵盤(pán)輸入的字符,或者表示此字符有許多其它作用。例如,如果要在雙引號(hào)包含的字符串中使用時(shí)雙引號(hào)時(shí),可能會(huì)在真正結(jié)束輸入字符串前,結(jié)束此字符串。反斜杠字符被用來(lái)改變它原來(lái)的含義。 你已經(jīng)了解了兩種類(lèi)型的變量:標(biāo)量和數(shù)組。標(biāo)量保存一個(gè)單一的數(shù)字或文本字符串。數(shù)組變量保存有一系列標(biāo)量。數(shù)組中每一個(gè)元素都有一個(gè)相關(guān)聯(lián)的數(shù)組下標(biāo),因而,數(shù)組是一種保存下標(biāo)-數(shù)值對(duì)的方式。當(dāng)一個(gè)數(shù)組中包含有另一個(gè)數(shù)組時(shí),即為多維數(shù)組或散列表。在下標(biāo)和數(shù)值對(duì)中的數(shù)值中是一個(gè)數(shù)組時(shí),就創(chuàng)建了多維數(shù)組或散列表。 變量替換是用來(lái)在字符串內(nèi)部用變量的值來(lái)替換變量的。但是,變量替換不能用于多于一級(jí)深度的數(shù)組。 動(dòng)態(tài)數(shù)組名提供了可以隨時(shí)創(chuàng)建的變量名的能力。由于PHP數(shù)組允許創(chuàng)建復(fù)雜的數(shù)據(jù)結(jié)構(gòu),所以我認(rèn)為不需要這種能力。 當(dāng)同樣的數(shù)字在程序中出現(xiàn)多次時(shí),就需要?jiǎng)?chuàng)建常量。使用常量可以把歸檔的因素加入到程序中。此外,如果在程序的開(kāi)始部分定義常量時(shí),修改程序就會(huì)變得容易些。 你已經(jīng)學(xué)習(xí)了操作符是如何命令PHP執(zhí)行什么操作的,一些操作符有比較高的優(yōu)先級(jí),因而會(huì)首先執(zhí)行它們和它們的操作數(shù)。一個(gè)操作數(shù)可以很簡(jiǎn)單,如數(shù)字10;也可以非常復(fù)雜,包含有變量、數(shù)字和其它操作符。這意味著它們本質(zhì)上是遞歸的。 PHP有許多類(lèi)型的操作符,它們中的大多數(shù)都在本章討論過(guò)。剛開(kāi)始介紹了三重操作符和算術(shù)操作符,然后介紹了條件操作符和一元操作符。在本章也介紹了加一和減一操作符,隨后,介紹了位操作符和邏輯操作符。當(dāng)需要快速整數(shù)相乘和相除時(shí),有時(shí)可能會(huì)用到位移操作符。 字符串連接操作符常用來(lái)把兩個(gè)字符串連接起來(lái),賦值操作符是用來(lái)給一個(gè)變量賦值。大多數(shù)賦值操作符都有縮寫(xiě),這樣不僅可以減少輸入,而且可以使賦值的意義更加清晰。 下一章“程序控制”將討論語(yǔ)句的定義,以及如何使用函數(shù)來(lái)使程序模塊化。 該文章在 2012/9/27 10:13:04 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |