官术网_书友最值得收藏!

第二部分 PHP篇

第3章 PHP基礎(chǔ)

3.1 PHP的工作原理

PHP(Hypertext Preprocessor)是當(dāng)下最受歡迎的Web開發(fā)語言之一。PHP最初由Rasmus Lerdorf創(chuàng)建于1995年,而現(xiàn)在,PHP的標(biāo)準(zhǔn)由PHP Group和開放源代碼社區(qū)負(fù)責(zé)維護(hù)。PHP以PHP License作為許可協(xié)議,因?yàn)樵搮f(xié)議限制了PHP名稱的使用,所以和開放源代碼許可協(xié)議GPL不兼容。

PHP的應(yīng)用范圍相當(dāng)廣泛,尤其是Web應(yīng)用。一般來說,PHP大多在服務(wù)器端執(zhí)行,通過執(zhí)行PHP代碼來產(chǎn)生用戶瀏覽的頁面。此外,還可以用來開發(fā)命令行腳本程序和客戶端的GUI應(yīng)用程序。PHP可以在多種不同的服務(wù)器和操作系統(tǒng)平臺(tái)上執(zhí)行,也可以和多種類型的數(shù)據(jù)庫系統(tǒng)結(jié)合使用,其中的最佳搭檔是MySQL。PHP是完全免費(fèi)的,官方組織PHP Group提供了完整的程序源代碼,允許用戶修改、編譯和擴(kuò)展。根據(jù)2010年4月的統(tǒng)計(jì)資料顯示,PHP已經(jīng)被安裝在超過4000萬個(gè)網(wǎng)站和300萬臺(tái)服務(wù)器上。

PHP的工作原理如圖3-1所示。

圖3-1 PHP的工作原理示意圖

3.2 PHP的版本變遷

經(jīng)過近15年的發(fā)展,PHP在不斷發(fā)展和成熟的過程中經(jīng)歷了從1.0到5.0的多個(gè)版本,為了使得初學(xué)者對(duì)PHP有一個(gè)全面的認(rèn)識(shí),本書特將PHP的版本變化歷程詳盡地呈現(xiàn)了出來,如表3-1所示,其中不僅包含了各個(gè)版本的現(xiàn)有狀態(tài)和發(fā)布時(shí)間,更重要的是介紹了各個(gè)版本在功能特性上所做的重要改進(jìn)和更新。其中,從PHP 1.0.0到PHP 5.1.0為舊版本,官方已經(jīng)停止支持;從PHP 5.2.0到PHP 5.2.9也為舊版本,但官方仍在維護(hù)中;PHP 5.3.6為當(dāng)前最新的版本;PHP 6.0則是下一個(gè)即將發(fā)布的重大版本。

表3-1 PHP的版本變化歷程

3.3 PHP的特性

在學(xué)會(huì)使用PHP之前,我們先來看看PHP具有哪些特性,具體如下所示。

?PHP完全免費(fèi)和開源,升級(jí)快,同時(shí)有很多成熟的框架支持,如ZendFramework、ThinkPHP、FleaPHP、CakePHP等。

?支持模板化開發(fā),實(shí)現(xiàn)程序邏輯與用戶界面的完全分離,開發(fā)周期短、效率高。

?PHP的便捷性:程序開發(fā)快,運(yùn)行快,易于學(xué)習(xí)。

?具有良好的跨平臺(tái)性:由于PHP是運(yùn)行在服務(wù)器端的腳本,支持UNIX、Linux、Windows、FreeBSD、OS2等多種操作系統(tǒng)平臺(tái)。

?同目前主流的技術(shù)相兼容,如WebService、Ajax、XML等技術(shù)都支持PHP。

?簡(jiǎn)單的語言:PHP堅(jiān)持以腳本語言為主,與Java和C++不同。

?支持所有的主流與非主流數(shù)據(jù)庫,支持JDBC,提供MySQL、Oracle、Sybase和SQL Server等多種數(shù)據(jù)庫的訪問接口。

?面向?qū)ο螅涸赑HP4和PHP5中,面向?qū)ο蠓矫娑加泻艽蟮母倪M(jìn),現(xiàn)在PHP完全可以用來開發(fā)大型的商業(yè)程序。

?相對(duì)于其他語言,PHP的編輯簡(jiǎn)單,實(shí)用性強(qiáng),更適合初學(xué)者。

3.4 PHP的應(yīng)用范圍

PHP幾乎可以做任何事情。由于PHP是服務(wù)器端的腳本語言,所以其他CGI程序能做到的事情它同樣也能做到,如表單提交的數(shù)據(jù)、生成動(dòng)態(tài)網(wǎng)頁、接/發(fā)cookie,而且PHP還可以做得更多。

PHP腳本主要應(yīng)用于以下三個(gè)領(lǐng)域:服務(wù)器端腳本、命令行腳本、編寫桌面應(yīng)用程序。直至今日,PHP已經(jīng)可以支持絕大多數(shù)的Web服務(wù)器,如Apache、IIS、Nginx、PWS、Netscape、iPlant server、Xitami等。

由此可見,PHP可以任意選擇操作系統(tǒng)和Web服務(wù)器。而且在開發(fā)PHP項(xiàng)目的時(shí)候可以選擇使用面向過程或面向?qū)ο蟮某绦蛟O(shè)計(jì)方法,或二者并用。PHP 5包括新的對(duì)象模型,擁有更多新的功能、更快的處理速度、代碼質(zhì)量更高、企業(yè)項(xiàng)目的開發(fā)更容易等優(yōu)點(diǎn)。

3.5 PHP的基本語法

3.5.1 PHP標(biāo)記

多數(shù)情況下,PHP代碼都是與HTML代碼混在一起的。當(dāng)包含了PHP程序的頁面被請(qǐng)求時(shí),Web服務(wù)器會(huì)自動(dòng)編譯、處理頁面中“<?php”標(biāo)記和“?>”標(biāo)記之間的代碼,并將處理后的結(jié)果以HTML的形式發(fā)送到頁面中,從而在頁面中顯示處理結(jié)果。

要想讓W(xué)eb服務(wù)器能夠區(qū)分PHP代碼與普通的HTML代碼,就要將PHP代碼放在特殊標(biāo)記內(nèi),PHP一共提供了4種不同的標(biāo)記風(fēng)格供我們使用,如下所示:

(1)<?php...?>

官方推薦風(fēng)格,標(biāo)記之間的代碼將被自動(dòng)解釋為PHP腳本語言。

(2)<?...?>

短標(biāo)記風(fēng)格,使用這種標(biāo)記之前須在配置文件php.ini中將short+open_tag設(shè)置為開啟,不推薦這種風(fēng)格。

(3)<%...%>

ASP風(fēng)格,使用這種標(biāo)記之前須在配置文件php.ini中將asp_tags設(shè)置為開啟。

(4)<script language="php"> ...</script>

JavaScript標(biāo)記的風(fēng)格,這種標(biāo)記風(fēng)格是最長(zhǎng)的,如果讀者使用過JavaScript或VBScript,就會(huì)熟悉這種風(fēng)格。如果你所使用的HTML編輯器無法支持其他標(biāo)記風(fēng)格,則可以使用它。這種風(fēng)格在任何環(huán)境下都是可以用的,只是我們并不常使用。

3.5.2 PHP中的注釋

為代碼添加注釋是一種良好的編程習(xí)慣,不僅可以使程序更清晰,也更利于團(tuán)隊(duì)開發(fā)。PHP提供的注釋主要有兩種類型:?jiǎn)涡凶⑨尯投嘈凶⑨專@兩種注釋的語法和示例如下所示。

(1)單行注釋

?C++風(fēng)格的單行注釋

注釋通常不會(huì)超過一行。因?yàn)檫@種注釋很簡(jiǎn)短,所以沒必要界定注釋的結(jié)束。PHP支持C++的單行注釋語法,在某一行代碼中,//符號(hào)后面的所有內(nèi)容均被視為注釋,如下所示:

        //這里寫注釋內(nèi)容

?shell風(fēng)格的單行注釋

PHP還支持另一種C++風(fēng)格的單行注釋,稱為shell風(fēng)格,它以#號(hào)開頭。在某一行代碼中,#符號(hào)后面的所有內(nèi)容均被視為注釋,如下所示:

        #這里寫注釋內(nèi)容

(2)多行注釋

代碼中通常要有一些詳細(xì)的功能描述或其他的解釋內(nèi)容,這些說明可能有多行。雖然可以在每行的前面都加上C++或shell風(fēng)格的注釋符,但PHP還支持一種多行注釋的形式,同時(shí)標(biāo)注注釋的開始和結(jié)束。多行注釋以/*符號(hào)開頭,以*/符號(hào)結(jié)束,在這兩個(gè)符號(hào)之間可以寫入多行注釋,如下所示:

        /*
        *這里寫注釋內(nèi)容
        */

3.5.3 編寫你的第一個(gè)PHP應(yīng)用

前面已經(jīng)搭建好了PHP的開發(fā)環(huán)境,現(xiàn)在來學(xué)習(xí)究竟如何編寫PHP應(yīng)用,讓我們先從一個(gè)簡(jiǎn)單的“Hello World!”應(yīng)用開始吧。先新建一個(gè)helloworld.php文件,輸入以下的代碼,并將該文件放入www文件夾內(nèi),在瀏覽器中輸入http://127.0.0.1:80/helloworld.php,你將看到如圖3-2所示的結(jié)果。

圖3-2 “Hello World!”運(yùn)行結(jié)果圖

        <html>
            <body>
            <h1><?php echo "Hello World!"; ?></h1>
            </body>
        </html>

3.6 PHP中的變量與常量

3.6.1 變量

最好的理解是把變量想象為存儲(chǔ)數(shù)據(jù)的容器。PHP中的變量本質(zhì)上是靈活多變的:可以為一個(gè)變量賦值、在變量中檢索數(shù)據(jù)(而不影響變量的值)、為變量賦新的值,以及在需要的時(shí)候進(jìn)行循環(huán)。但是PHP中的變量也是臨時(shí)的,它們只存在于一個(gè)腳本的執(zhí)行期間,也就是說,它們只有在此時(shí)才有一個(gè)值。當(dāng)用戶單擊一個(gè)鏈接或者提交表單時(shí),將獲得一個(gè)新的頁面,同時(shí)這些變量也將不復(fù)存在。除非使用特殊的方法改變他們的生存期。

1. 變量聲明

我們已經(jīng)對(duì)變量有了一個(gè)初步的了解,在掌握了正確的語法后,就可以自己創(chuàng)建變量。變量總是以美元符號(hào)$開頭,然后是變量名。聲明變量時(shí)必須遵循如下規(guī)則:

?所有的變量名必須以美元符號(hào)($)開頭。

?美元符號(hào)后的第一個(gè)字符必須為字母(A~Z,a~z)或者下劃線(_)(不能使用數(shù)字)。

?變量名剩下的部分可以是任何數(shù)量的字母、數(shù)字和下劃線組合。

?變量名中不能出現(xiàn)空格(通常使用下劃線進(jìn)行字符分隔)。

?變量名是區(qū)分大小寫的,這就意味著$phpchina和$PHPChina是截然不同的變量,因此將兩個(gè)變量進(jìn)行如此相似的命名是非常不明智的。

這些變量是合法的:$phpchina、$phpchina_zend、$_phpchina。

注意

與其他語言不同,PHP通常不需要在使用變量前聲明或初始化變量。換句話說,可以在定義變量類型之前先引用。盡管如此,最好還是不要這樣做,好的編程習(xí)慣是:所有的變量都應(yīng)當(dāng)在使用前進(jìn)行聲明,最好還要帶有注釋。

2. 變量賦值

聲明變量之后,就可以為其賦值。變量賦值有兩種方法:值賦值和引用賦值。所謂值賦值就是將賦值表達(dá)式的值復(fù)制到變量中,這是最常見的一類賦值。下面是幾個(gè)例子:

        <?php
        $name_1='張三';
        $name_2 = $name_1;          //為$name_1的值創(chuàng)建一個(gè)副本,賦值給$name2
        $name_1='李四';             //改變$name_1的值
        echo $name_2;               //結(jié)果會(huì)輸出“張三”,$name_2的值不會(huì)因$name_1的改變而改變
        ?>

如果希望兩個(gè)變量指向一個(gè)值的同一個(gè)副本,則需要通過引用賦值,下面將介紹引用賦值。

PHP4提供了一種新的方式給變量賦值,這就是引用賦值。引用賦值同樣也是使用“=”將一個(gè)變量的值賦給另一個(gè)變量,但是需要在等號(hào)右邊的變量前加上一個(gè)“&”符號(hào)。實(shí)際上這種賦值方式并不是真正意義上的賦值,而是一個(gè)變量引用另一個(gè)變量。在使用引用賦值時(shí),兩個(gè)變量將會(huì)指向內(nèi)存中的同一個(gè)存儲(chǔ)空間。因此任何一個(gè)變量的變化都會(huì)引起另外一個(gè)變量的變化。使用引用賦值的示例如代碼清單3-1所示:

代碼清單3-1引用賦值示例

        <?php
        $name_1 = '張三';
        $name_2 = '李四';
        //這里將新變量$name_2指向$name_1;
        $name_2 = &$name_1;
        //改變$name_2的值
        $name_2 = 'Bob';
        $name_2 = 'My name is'.$name_2;
        //輸出原始變量$name_1
        Echo $name_1;
        ?>

使用以上的引用賦值時(shí)將輸出如圖3-3所示的結(jié)果。

圖3-3 引用賦值示例的結(jié)果

3. 可變變量

PHP支持對(duì)變量名稱進(jìn)行動(dòng)態(tài)解析,也就是說,可以將變量名存儲(chǔ)在另一個(gè)變量名中。如B變量存儲(chǔ)了A變量的名稱,通過對(duì)B變量的解析,即可得到A變量的值,如代碼清單3-2所示。

代碼清單3-2可變變量

        <?
        /*
        *$temp_2:變量A        $temp_1:變量B
        */
        $temp_1 = 'temp_2';                 //變量B存儲(chǔ)了變量A的名稱
        $temp_2 = "I'm temp_2";             //為變量A賦值
        echo $temp_1;                       //將輸出I'm temp_2
        ?>

注意 因?yàn)榭勺冏兞繒?huì)使代碼變得難以閱讀和理解,所以在項(xiàng)目開發(fā)中應(yīng)盡量少用。

4. 變量作用域

總之無論怎樣聲明變量(按值或按引用),在PHP腳本的任何位置都可以聲明變量。但是,聲明的位置會(huì)大大影響變量的訪問范圍,這個(gè)可訪問的范圍稱為作用域。PHP變量有4種作用域:

(1)局部變量

在函數(shù)中聲明的變量被認(rèn)為是局部變量,即它只能在該函數(shù)中引用。如果在函數(shù)外賦值,將被認(rèn)為是完全不同的另一個(gè)變量。注意,退出聲明變量的函數(shù)時(shí),該變量及相應(yīng)的值就會(huì)撤銷。

局部變量的作用非常大,因?yàn)樗顺霈F(xiàn)意外副作用的可能性,否則,這些副作用將導(dǎo)致全局訪問的變量被有意或無意地修改。

(2)函數(shù)參數(shù)

PHP與其他很多編程語言一樣,任何接收參數(shù)的函數(shù)都必須在函數(shù)的首部中聲明這些參數(shù)。雖然這些參數(shù)接收函數(shù)外部的值,但退出函數(shù)后就無法再訪問這些參數(shù)。

注意

雖然在聲明參數(shù)的函數(shù)內(nèi)部可以訪問和處理這些參數(shù),但當(dāng)函數(shù)執(zhí)行結(jié)束時(shí),參數(shù)就會(huì)被撤銷。

?全局變量

與局部變量相反,全局變量可以在程序的任何地方訪問。但是,為了修改一個(gè)全局變量,就必須在要修改該變量的函數(shù)中將其顯式地聲明為全局變量。這點(diǎn)很容易做到,只要在變量的前面加上關(guān)鍵字GLOBAL即可將其標(biāo)識(shí)為全局變量。如果將GLOBAL關(guān)鍵字放在一個(gè)已有的變量的名稱前面,則表示PHP要使用同名的變量。

注意

無論用何種方法將變量轉(zhuǎn)換為全局變量,都要當(dāng)心。全局變量一直以來都是困擾程序員的一個(gè)問題,因?yàn)椴萋适褂脮?huì)導(dǎo)致意外的結(jié)果。

?靜態(tài)變量

靜態(tài)變量的作用域稱為靜態(tài)(static)作用域。函數(shù)參數(shù)的值在函數(shù)退出時(shí)會(huì)被撤銷,與聲明為函數(shù)參數(shù)的變量不同,靜態(tài)變量在函數(shù)退出時(shí)不會(huì)丟失值,當(dāng)再次調(diào)用此函數(shù)時(shí)還能保留這個(gè)值。在變量名前面加上關(guān)鍵字STATIC就可以聲明一個(gè)靜態(tài)變量。

5. 超級(jí)全局變量

PHP提供了很多有用的預(yù)定義變量,可以在執(zhí)行腳本的任何位置訪問,用于提供與環(huán)境有關(guān)的大量信息??梢酝ㄟ^這些變量獲得關(guān)于當(dāng)前用戶的會(huì)話、用戶操作環(huán)境和本地操作環(huán)境等詳細(xì)信息。PHP會(huì)創(chuàng)建部分變量,而其他許多變量的可用性和值則取決于操作系統(tǒng)和Web服務(wù)器。PHP的全部超級(jí)全局變量如下所示:

?$GLOBALS:包含所執(zhí)行腳本內(nèi)部全部可用的變量所組成的數(shù)組,數(shù)組的鍵即為變量的名稱。

?$_SERVER:包含正在執(zhí)行的腳本的周邊環(huán)境信息,例如服務(wù)器的名稱和正在運(yùn)行的頁面的名稱等。

?$_GET和$_POST:包含可發(fā)送到服務(wù)器的變量。其中$_GET以u(píng)rl的形式傳參,而POST則以包的形式傳參。$_GET有字?jǐn)?shù)限制(一般為2083B),且以u(píng)rl方式傳參安全性不高,相對(duì)的,$_POST理論上沒有字符限制,以HTTP包的形式傳參,安全性更高。

?$_SESSION和$_COOKIE:SESSION可以儲(chǔ)存用戶整個(gè)會(huì)話過程中的狀態(tài)信息。COOKIE可設(shè)置并在本地保留明碼信息。

?$_REQUEST:用戶輸入的所有變量數(shù)組,包含$_POST、$_GET和$_SESSION數(shù)組。

3.6.2 常量

常量是指在程序執(zhí)行中無法修改的值。當(dāng)處理絕對(duì)不需要修改的值時(shí),常量非常有用,例如π(3.141592)。常量一旦定義,就無法在程序的其他地方修改(或重新定義)。

1. 自定義常量

在PHP中使用define定義常量。常量一經(jīng)定義就永遠(yuǎn)不能改變,如果要再次定義常量值,則會(huì)產(chǎn)生警告并且再次定義的值會(huì)被忽略。查看常量是否被定義可以使用函數(shù)defined,函數(shù)的返回值為布爾類型。其形式如下:

        boolean define(staring name,mixed value[, bool case_insensitive])

如果使用可選參數(shù)case_insensitive,并且這個(gè)參數(shù)的值為TRUE,那么后面對(duì)此常量的引用將不區(qū)分大小寫。下面來看一個(gè)簡(jiǎn)單的示例:

        <?php
            define("PI", 3.141592);               //聲明一個(gè)常量PI
            $pi2 = 2 * PI;                          //使用常量PI
            Print("PI doubled equals f%", $pi2);
        ?>

定義常量名稱時(shí)不可用字符“$”開頭,并且常量的值只能是特定的類型,如整數(shù)、浮點(diǎn)數(shù)、字符串和布爾值。

2. 魔術(shù)常量

PHP為它運(yùn)行的任何腳本提供了大量的預(yù)定義常量。不過很多常量都是由不同的擴(kuò)展庫來定義的,只有在加載了這些擴(kuò)展庫時(shí)才會(huì)出現(xiàn),或者動(dòng)態(tài)加載后,或者在編譯時(shí)已經(jīng)包括進(jìn)去了。有5個(gè)魔術(shù)常量需要根據(jù)它們使用的位置而改變,具體說明可參考表3-2。

表3-2 魔術(shù)常量參照表

最后要提醒大家,魔術(shù)常量的值會(huì)根據(jù)使用該常量的文件位置的改變而改變,這些特殊常量不區(qū)分大小寫。

3.7 表達(dá)式

表達(dá)式是PHP最重要的組成元素,下面是幾個(gè)例子:

        $a = 5;                      //將整數(shù)5賦予變量$a
        $a = '5';                    //將字符串5賦予變量$a
        $sum = 5 + $a;               //將5+$a的結(jié)果賦予變量$sum

3.7.1 表達(dá)式分類

下面來看一個(gè)簡(jiǎn)單的表達(dá)式:

        <?php
        $a = 100; //賦值語句,$a=100是最簡(jiǎn)單的表達(dá)式
        ?>

從這個(gè)表達(dá)式中可以看到只有一個(gè)操作數(shù)$a。因此根據(jù)運(yùn)算數(shù)的個(gè)數(shù),PHP表達(dá)式一般可以分成三類:

?單目表達(dá)式:運(yùn)算數(shù)只有一個(gè),如$a或zhanglei等;

?雙目表達(dá)式:運(yùn)算數(shù)有兩個(gè),如$a+$b,$a=100等;

?三目表達(dá)式:運(yùn)算數(shù)有三個(gè),如$a ? $b:$c。

3.7.2 表達(dá)式的應(yīng)用

下面先給出一個(gè)包含常量和變量的簡(jiǎn)單例子。當(dāng)你寫$a = 5時(shí),即將值'5'賦給了$a(這種情況下,5是一個(gè)整型常量)。在此,你是希望把$a賦值成5,所以當(dāng)你寫$b = $a時(shí),希望的結(jié)果就是$b = 5,即$a是一個(gè)值為5的表達(dá)式。復(fù)雜表達(dá)式多應(yīng)用在函數(shù)部分。例如,以下函數(shù):

        function foo() {
        return 5;
        }

如果你認(rèn)為$c = foo()和$c = 5實(shí)際上是一樣的,那么你是對(duì)的。函數(shù)是值為其返回值的表達(dá)式。因?yàn)閒oo()返回5,所以表達(dá)式foo()的值為5。

PHP的值當(dāng)然不限于整型,且通常都不是。PHP支持三種類型的值:整型值、浮點(diǎn)值和字符串值。PHP還支持兩種混合類型(non-scalar):數(shù)組和對(duì)象。這兩種類型的值可以賦給變量或從函數(shù)中返回。PHP還是一種面向表達(dá)式的語言,所以幾乎所有的東西都可成為表達(dá)式??紤]前面已經(jīng)討論過的例子$a = 5,很容易看出這里有兩個(gè)值,整型常量5的值和已被賦為5的變量 $a的值。但是這里實(shí)際上還有一個(gè)附加的值,就是賦值語句本身的值。賦值語句本身的值就是被賦予的值,本例中為5。事實(shí)上,它意味著不考慮$a = 5要做什么,它就是一個(gè)值為5的表達(dá)式。這樣,諸如$b = ($a = 5)的語句,就如同$a = 5; $b = 5;(每條語句末尾都有一個(gè)分號(hào))。因?yàn)橘x值的順序可以從右向左,所以也可以寫成$b= $a = 5。

最常見的表達(dá)式是比較表達(dá)式。這種表達(dá)式的計(jì)算結(jié)果是0或1,分別意味著false或是true。PHP支持 >(大于)、>=(大于等于)、==(等于)、<(小于)及 <=(小于等于)。這種表達(dá)式通常用于條件執(zhí)行語句里,例如if語句。最后要討論的表達(dá)式是混合賦值表達(dá)式。你已經(jīng)知道如果要使 $a加1,則可以簡(jiǎn)單地寫一句$a++或++$a。但是,如果要增加的值比1大,那該怎么辦?例如要使它加3,你可以多寫幾次$a++,但這顯然不是一種高效的或令人樂于接受的辦法。另外一個(gè)通常的辦法是寫成$a = $a + 3。先計(jì)算$a + 3的值,再賦回到$a,這樣$a就加上3了。在PHP中,你可以像在其他幾種語言中(例如C)一樣將它簡(jiǎn)寫,這樣更清晰和簡(jiǎn)潔易懂。把當(dāng)前的變量$a加3可以寫成$a += 3。這句話的意思是“取出$a的值,把它加3,再賦給$a”。這樣寫除了能使語句簡(jiǎn)短和清晰,還能使它執(zhí)行得更快。表達(dá)式$a += 3的值和一個(gè)嚴(yán)格的賦值語句一樣,是所賦的值。

注意

不是3,而是$a加3的值(這才是賦給$a的值)。任何雙操作符都可以用于這種賦值操作模式,例如'$a -= 5'(變量$a減去5),'$b *= 7'(變量$b乘以7),等等。

最后值得一提的是表達(dá)式的真值。很多時(shí)候(主要是在條件執(zhí)行和循環(huán)時(shí)),你并不關(guān)心表達(dá)式的特定值,而只是關(guān)注它代表true還是false(PHP沒有專用的布爾類型)。PHP中使用類似Perl的方法來計(jì)算表達(dá)式的真值。任何非零的值為true,零則為false。請(qǐng)一定注意負(fù)數(shù)也是非零值,并被視為true。空字符串和字符串“0”為false,其他的字符串均為true。對(duì)于非數(shù)量值(數(shù)組和對(duì)象)—如果它的值不含任何元素,則為false,否則為true。

3.7.3 操作數(shù)

操作數(shù)是表達(dá)式的輸入。下面是操作數(shù)的一些例子:

        $a++;                                          //$a是一個(gè)操作數(shù)
        $sun = $value1 + $value2;                      //$sum,$value1和$value2都是操作數(shù)

3.7.4 操作符

操作符是用來操作各種操作數(shù)的符號(hào),只有理解各種操作符的用法,才能更高效地開發(fā)出PHP程序。PHP會(huì)根據(jù)操作符的類型自動(dòng)進(jìn)行類型轉(zhuǎn)換,這在其他的編程語言中并不多見。

操作符根據(jù)功能特性可分為:算數(shù)操作符、賦值操作符、比較操作符、邏輯操作符和其他操作符。操作符的優(yōu)先級(jí)和結(jié)合性是PHP語言特性中的重要部分,表3-3根據(jù)優(yōu)先級(jí)從高到低的順序詳細(xì)介紹了PHP中的各種操作符。

表3-3 操作符優(yōu)先級(jí)

對(duì)于表3-3所給的各個(gè)運(yùn)算符的優(yōu)先級(jí),我們不必刻意全部記住。如果在開發(fā)過程中要使用復(fù)雜的表達(dá)式運(yùn)算,可以通過添加“()”來限制各子表達(dá)式運(yùn)算的優(yōu)先級(jí)。

3.8 PHP中的數(shù)據(jù)類型

PHP提供了一個(gè)不斷擴(kuò)充的數(shù)據(jù)類型集合,可以將不同的數(shù)據(jù)保存在不同的數(shù)據(jù)類型中。但PHP語言是一種弱類型檢查的語言,與其他語言不同的是,變量或常量的數(shù)據(jù)類型由程序的上下文來決定。在強(qiáng)類型語言中,變量要先指定類型,然后才可以存儲(chǔ)對(duì)應(yīng)的指定類型的數(shù)據(jù)。而PHP這種弱類型語言,變量的類型則是由數(shù)據(jù)決定的。

PHP中的數(shù)據(jù)類型可劃分為三大類別:基本數(shù)據(jù)類型、復(fù)合數(shù)據(jù)類型和特殊數(shù)據(jù)類型。各種數(shù)據(jù)類型所包括的內(nèi)容如表3-4所示。

表3-4 PHP數(shù)據(jù)類型分類

3.8.1 布爾型

布爾數(shù)據(jù)類型以數(shù)學(xué)家喬治·布爾的名字命名,他被認(rèn)為是信息論的創(chuàng)始人之一。布爾變量表示真實(shí)性,布爾型是最簡(jiǎn)單的數(shù)據(jù)類型,表達(dá)式的值只有TURE和FALSE兩個(gè),不區(qū)分大小寫。

注意 -1和其他非零值(不論正負(fù))一樣,被認(rèn)為是TURE,而不是FALSE。

3.8.2 整型

整型就是一個(gè)不包含小數(shù)部分的數(shù),整型值可以指定為十進(jìn)制、十六進(jìn)制或八進(jìn)制,八進(jìn)制數(shù)字前必須加上零(0),十六進(jìn)制符號(hào)數(shù)字前必須加上0x。例如:

        $num_1 = 123    //一個(gè)十進(jìn)制數(shù)
        $num_2 = 0123   //一個(gè)八進(jìn)制數(shù)(等于十進(jìn)制數(shù)中的83)
        $num_3 = 0x3A   //一個(gè)十六進(jìn)制數(shù)(等于十進(jìn)制數(shù)中的58)

因?yàn)镻HP中不存在整除,所以,如果運(yùn)算結(jié)果超出整型范圍,則返回float,即整型的1/2等于float 0.5。

3.8.3 字符串

字符串就是一個(gè)連續(xù)的字符的序列。一般可通過以下兩種方式指定一個(gè)字符串的值。

1. 單引號(hào)

當(dāng)字符串應(yīng)當(dāng)按照聲明的原樣解釋時(shí),可以使用單引號(hào)括起這個(gè)字符串。這表示,解析字符串時(shí),變量和轉(zhuǎn)義序列都不會(huì)進(jìn)行解析。示例如下:

        <?php echo 'this is a simple of string insingle-quoted.';?>

如果要在字符串中包含單引號(hào),則需在它前面加上反斜線,這叫做字符的轉(zhuǎn)義(escape),示例如下:

        <?php echo 'this is a simple of string insingle-quoted(\').';?>

如果要在字符串中包含反斜線,則需要對(duì)反斜線進(jìn)行轉(zhuǎn)義。示例如下:

        <?php echo 'this is a simple of string insingle-quoted(\\).';?>
2. 雙引號(hào)

相對(duì)于單引號(hào)的字符串,PHP處理程序會(huì)剖析雙引號(hào)括起的字符串,以便查找和替換特別的轉(zhuǎn)義序列和變量。PHP轉(zhuǎn)義序列如下所示:

        \n                   換行字符
        \r                   回車字符
        \t                   制表符
        \\                   反斜線字符
        \$                   美元符號(hào)
        \0                   值在0~255之間的字符,八進(jìn)制表示法
        \x                   值在0~255之間的字符,十六進(jìn)制表示法

3.8.4 數(shù)組

由多個(gè)數(shù)值以鍵值對(duì)的形式存儲(chǔ)而成的數(shù)據(jù)集合稱為數(shù)組,其中,鍵也稱為索引。由于PHP中的數(shù)組結(jié)構(gòu)沒有固定的要求,所以非常靈活。PHP中數(shù)組的鍵不像Java那樣只能是數(shù)字,也可以是字符串,而由于PHP弱語言的特性,數(shù)組的值也可以是各種數(shù)據(jù)類型。

注意

在開發(fā)PHP項(xiàng)目的時(shí)候,應(yīng)盡量避免數(shù)組中存在類似'<abc'這樣的值,瀏覽器在解析數(shù)組的值時(shí),會(huì)將'<abc'解析為HTML標(biāo)記,而由于標(biāo)記不完整(沒有表示結(jié)束的'>'),所以數(shù)組后面的值將不會(huì)解析出來,這樣就會(huì)導(dǎo)致數(shù)據(jù)的丟失。

利用count()函數(shù)可以取得數(shù)組元素的個(gè)數(shù)。由于數(shù)組的值也可以是數(shù)組,所以在PHP中可以很輕松地創(chuàng)建多維數(shù)組。可使用print_r()將數(shù)組全部打印出來以便查看數(shù)組的結(jié)構(gòu)。

數(shù)組排序

簡(jiǎn)單的數(shù)組排序是對(duì)一個(gè)數(shù)組元素的值進(jìn)行排序,PHP的sort()和rsort()函數(shù)實(shí)現(xiàn)了這個(gè)功能。這兩個(gè)函數(shù)既可以按照數(shù)字的大小排列,也可以按照字母的順序進(jìn)行排列,并且具有相同的參數(shù)列表。

sort()函數(shù)會(huì)按照數(shù)組元素的值進(jìn)行排序,按照先數(shù)字后字母的順序由小到大進(jìn)行排序,排序后數(shù)組的索引將會(huì)重置。rsort()與sort()正好相反,它是按照由大到小的順序?qū)υ氐闹颠M(jìn)行排序。

使用數(shù)組時(shí),會(huì)根據(jù)鍵名對(duì)數(shù)組重新排序,ksort()和krsort()函數(shù)實(shí)現(xiàn)了這個(gè)功能。ksort()函數(shù)按照數(shù)組的鍵名(索引順序)對(duì)數(shù)組進(jìn)行由小到大的排序。krsort()函數(shù)和ksort()相反,是將數(shù)組進(jìn)行由大到小的排序。

如果想使用數(shù)組中元素的值進(jìn)行排序來取代鍵值排序,PHP也能滿足你的要求。只需要使用asort()函數(shù)來代替先前提到的ksort()函數(shù)就可以了,如果按值從大到小排序,則可以使用arsort()函數(shù)。asort()與sort()的功能類似,唯一的區(qū)別在于執(zhí)行asort()排序后的數(shù)組索引將不會(huì)重置,完全保留原數(shù)組鍵值的對(duì)應(yīng)信息。

注意

使用sort()函數(shù)排序后的數(shù)值型數(shù)組是按數(shù)據(jù)值的大小進(jìn)行排序的,字符型數(shù)組是按ASCII碼的順序進(jìn)行排序的。如果一個(gè)數(shù)組的內(nèi)容中同時(shí)包含英文字符、漢字字符和數(shù)字,使用sort()函數(shù)進(jìn)行排序的順序則依次為數(shù)字、英文字符和漢字字符。

3.8.5 對(duì)象

創(chuàng)建對(duì)象的過程稱為實(shí)例化,當(dāng)一個(gè)對(duì)象被創(chuàng)建后,就包含了三個(gè)方面的特性:句柄、屬性和方法。在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,對(duì)象是一個(gè)非常重要的核心概念。

1. 對(duì)象的句柄

對(duì)象被創(chuàng)建后,該對(duì)象就會(huì)獲得一塊存儲(chǔ)空間,該控件的地址即為對(duì)象的標(biāo)識(shí),也就是對(duì)象的句柄。

2. 屬性與方法

在面向?qū)ο缶幊讨校K被組織成一個(gè)個(gè)對(duì)象。這些對(duì)象擁有方法和屬性,從抽象的角度來看,方法是一個(gè)對(duì)象所做的動(dòng)作,而屬性是對(duì)象的特性。從編程的角度來看,方法就是函數(shù),而屬性就是變量。在一個(gè)理想化的面向?qū)ο篌w系中,每個(gè)部分都是一個(gè)對(duì)象,體系由對(duì)象及對(duì)象間通過方法形成的聯(lián)系所構(gòu)成。

關(guān)于對(duì)象的具體應(yīng)用,將在第8章詳細(xì)介紹。

3.8.6 其他類型

除了上面講到的類型,PHP在特定情況下會(huì)用到以下幾種類型:

1. 資源

PHP有時(shí)會(huì)處理一些數(shù)據(jù)庫連接或操作系統(tǒng)對(duì)象的句柄。它們是被稱為資源(resource)的特殊變量。一般情況下,資源在函數(shù)之間傳遞,這些函數(shù)知道如何處理它們。當(dāng)不再需要這些資源時(shí),PHP就會(huì)自動(dòng)釋放它們。

2. NULL

NULL是PHP中的特殊類型和值,它代表“無值”。如果變量符合下列要求,則它們的值為NULL。

?被設(shè)置為大小寫敏感的關(guān)鍵字NULL。

?從未被賦過值。

?使用unset()方法后清除。

NULL、0、空字符的區(qū)別:NULL表示無值,0和空字符表示有值,值為0和空。

3.9 強(qiáng)制類型轉(zhuǎn)換

在項(xiàng)目開發(fā)中,經(jīng)常會(huì)用到類型轉(zhuǎn)換,例如把商品的價(jià)格由整型轉(zhuǎn)換為字符型,與別的信息連在一起組成一張價(jià)目表。

3.9.1 顯式和隱式強(qiáng)制類型轉(zhuǎn)換

1. 隱式強(qiáng)制類型轉(zhuǎn)換

隱式強(qiáng)制類型轉(zhuǎn)換是一種最常見的轉(zhuǎn)換方式,也是由PHP語言引擎自動(dòng)解析的轉(zhuǎn)換方式。

最簡(jiǎn)單的例子是:將一個(gè)整數(shù)與一個(gè)浮點(diǎn)數(shù)進(jìn)行數(shù)學(xué)運(yùn)算,PHP會(huì)將整數(shù)轉(zhuǎn)換成浮點(diǎn)數(shù)后再進(jìn)行運(yùn)算;又如,將一個(gè)字符串與一個(gè)整數(shù)進(jìn)行數(shù)學(xué)運(yùn)算,PHP會(huì)將字符串轉(zhuǎn)換成整數(shù)后再進(jìn)行運(yùn)算。一些特定的方法和操作符也會(huì)將參數(shù)進(jìn)行轉(zhuǎn)換,例如,echo方法和print方法需要它們的參數(shù)為字符串,在執(zhí)行操作時(shí),PHP會(huì)盡可能地將非字符串變量轉(zhuǎn)換為字符串。

2. 顯式強(qiáng)制類型轉(zhuǎn)換

有時(shí),PHP引擎認(rèn)為轉(zhuǎn)換類型后的數(shù)據(jù)會(huì)改變或丟失,將不自動(dòng)轉(zhuǎn)換,在這種情況下,可以使用(type cast)的方式顯式強(qiáng)制轉(zhuǎn)換某變量的值。

?(int)/(integer):轉(zhuǎn)換為整數(shù)

?(float)/(double)/(real):轉(zhuǎn)換為浮點(diǎn)數(shù)

?(string):轉(zhuǎn)換為文本字符串

?(bool)/(boolean):轉(zhuǎn)換為布爾值

?(array):轉(zhuǎn)換為數(shù)組

?(object):轉(zhuǎn)換為對(duì)象

3.9.2 有用的強(qiáng)制類型轉(zhuǎn)換函數(shù)

is_type():判斷當(dāng)前是否為某種類型的變量。

gettype:得到當(dāng)前變量的類型。

settype:有兩個(gè)參數(shù)為要轉(zhuǎn)換的變量和要轉(zhuǎn)換的類型,函數(shù)返回布爾值,表示轉(zhuǎn)換成功。

3.10 PHP的語句

任何復(fù)雜的程序設(shè)計(jì)都離不開流程控制語句,這些語句決定了程序的走向。PHP中共包含了三種控制結(jié)構(gòu):順序結(jié)構(gòu)、分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。

3.10.1 循環(huán)語句

程序中經(jīng)常會(huì)有些代碼塊要被執(zhí)行多次,雖然形式可能會(huì)有所不同,但是所有流行的編程語言中都必定有循環(huán)語句。這不奇怪,因?yàn)橥枰貜?fù)一段指令直到滿足特定條件為止,這是程序中非常常見的,而循環(huán)機(jī)制為此提供了一種簡(jiǎn)單的方式。PHP為此提供了幾種這樣的循環(huán)機(jī)制,如果你熟悉其他編程語言,應(yīng)該會(huì)很快掌握。

1. while循環(huán)

while語句制定了一個(gè)條件,在其嵌入的代碼執(zhí)行結(jié)束前,必須滿足這個(gè)條件。其語句格式是:

        while(condition){    //條件
        statement;           //執(zhí)行語句
        }

循環(huán)流程:condition返回值為true時(shí),繼續(xù)執(zhí)行statement語句,之后接著檢查condition條件。condition返回值為false時(shí),直接跳出循環(huán),不再執(zhí)行statement語句。使用continue和break都可以跳出循環(huán)。區(qū)別在于,continue只跳出一次循環(huán),跳出后繼續(xù)檢查condition條件,而break則直接跳到循環(huán)外。

2. do...while循環(huán)

do...while循環(huán)條件是while的一種變體,它在代碼塊的結(jié)束處驗(yàn)證循環(huán)條件,而不是在開始處。其語句格式是:

        do
        {
            statement
        }while(condition)

循環(huán)流程:首先執(zhí)行一次statement語句,再檢查condition條件,后面的流程與while循環(huán)一樣。do...while循環(huán)與while循環(huán)的唯一區(qū)別在于while循環(huán)先檢查條件,而do...while循環(huán)則先執(zhí)行一次statement語句再檢查條件。

3. for循環(huán)

for語句提供了比while語句更加復(fù)雜的循環(huán)機(jī)制。其語句格式是:

        for(expression1; expression2; expression3){
            循環(huán)體
        }

expression1的作用是初始化變量;expression2是一個(gè)循環(huán)控制語句,返回一個(gè)布爾值;expression3用于控制變量的遞增或遞減,即用于控制循環(huán)次數(shù)。

循環(huán)控制語句返回一個(gè)布爾值,為true時(shí),繼續(xù)執(zhí)行下面括號(hào)中的循環(huán)體;為false時(shí),停止循環(huán)。

使用PHP的for循環(huán),需要記住以下幾點(diǎn)規(guī)則:

?第一個(gè)表達(dá)式expression1在第一次循環(huán)時(shí)自動(dòng)進(jìn)行運(yùn)算。

?第二個(gè)表達(dá)式expression2在每次循環(huán)時(shí)進(jìn)行計(jì)算。這個(gè)表達(dá)式用來確定是否繼續(xù)循環(huán)。

?第三個(gè)表達(dá)式expression3在每次循環(huán)結(jié)束時(shí)進(jìn)行計(jì)算。

?任何一個(gè)表達(dá)式都可以為空,它們可以由for塊內(nèi)部的邏輯所取代。

3.10.2 條件判斷語句

順序結(jié)構(gòu)的程序雖然能解決計(jì)算和輸出等問題,但進(jìn)行判斷后就不能再選擇了。對(duì)于要先做判斷再做選擇的問題就要使用分支結(jié)構(gòu),這種結(jié)構(gòu)又稱為選擇結(jié)構(gòu)或條件結(jié)構(gòu)。分支結(jié)構(gòu)的執(zhí)行是依據(jù)一定的條件選擇執(zhí)行路徑,而不是嚴(yán)格按照語句出現(xiàn)的物理順序執(zhí)行。分支結(jié)構(gòu)程序設(shè)計(jì)方法的關(guān)鍵在于構(gòu)造合適的分支條件和分析程序流程,根據(jù)不同的程序流程選擇適當(dāng)?shù)姆种дZ句。分支結(jié)構(gòu)適合于帶有邏輯或關(guān)系比較等條件判斷的計(jì)算。即程序在執(zhí)行過程中依照條件的結(jié)果來改變程序執(zhí)行的順序,滿足條件時(shí)執(zhí)行某一語句塊,反之則執(zhí)行另一語句塊。

1. if語句

if、else和else if語句經(jīng)常一起被使用,這3個(gè)語句中只有if可以單獨(dú)使用,而else和else if語句則需要與if語句結(jié)合使用。

語句格式:

        if(condition)
        {
            statement
        }else if(condition){
            statement
        }else{
            statement
        }

else if語句在if的condition為false時(shí),逐個(gè)往下執(zhí)行,若condition為true時(shí),則執(zhí)行內(nèi)部的statement;若沒有,則繼續(xù)向下查看else if語句。若所有else if的condition為false,有else語句則執(zhí)行else語句內(nèi)的statement,沒有則繼續(xù)往下執(zhí)行。

if else語句內(nèi)部仍可套用if else語句來做更細(xì)致的判斷??筛鶕?jù)下面的代碼來修改$num的值來查看判斷的流程。

          <?php
          $num = 5;
          if($num>3){
              echo 'num>3<br/>';
              if($num<6){
                echo 'num<6<br/>';
              }else{
                echo 'num>=6<br/>';
              }
          }else if($num<3){
              echo 'num<3<br/>';
              if($num>-1){
                echo 'num>-1<br/>';
              }else if($num<-1){
                echo 'num<-1<br/>';
              }else{
                echo 'num=-1<br/>';
              }
          }else{
              echo 'num=3<br/>';
          }
          ?>
2. switch語句

對(duì)于條件判斷結(jié)果很多的情況,如果使用if語句將會(huì)變得非常麻煩,這時(shí)可以使用switch選擇語句。語句結(jié)構(gòu):

        switch($temp)
        {
            case 'value_1': statement; break;
            case 'value_2': statement ; break;
            case 'value_3': statement ; break;
                    ·
                    ·
            default: statement;
        }

執(zhí)行流程:從第一個(gè)case開始判斷,若$temp的值等于value_1,則執(zhí)行case 'value_1'冒號(hào)后面的語句,若沒有則繼續(xù)向下執(zhí)行。若執(zhí)行語句后有break,則case找到對(duì)應(yīng)的語句執(zhí)行完后直接跳出switch語句;若沒有break語句,則將后面所有case語句的statement都執(zhí)行一遍,直到遇到break才跳出。default可寫可不寫,當(dāng)遍歷所有case后都沒有與$temp對(duì)應(yīng)的值時(shí),則執(zhí)行默認(rèn)的default語句。

switch語句在多個(gè)值匹配一個(gè)變量的情況下非常管用,雖然if else語句也可以實(shí)現(xiàn)同樣的效果,但switch語句執(zhí)行起來更快捷、更簡(jiǎn)單,而且更穩(wěn)定,遇到復(fù)雜的邏輯判斷時(shí)語句結(jié)構(gòu)也一目了然。

3.11 小結(jié)

本章介紹了PHP的工作原理及發(fā)展?fàn)顩r,并通過一些簡(jiǎn)單的示例對(duì)PHP基礎(chǔ)語法、變量和常量、數(shù)據(jù)類型、數(shù)據(jù)類型之間的轉(zhuǎn)換、表達(dá)式和運(yùn)算符,以及流程控制語句等知識(shí)點(diǎn)進(jìn)行了介紹。掌握這些基礎(chǔ)知識(shí)將會(huì)為以后更好地掌握PHP打下堅(jiān)實(shí)基礎(chǔ)。

主站蜘蛛池模板: 枝江市| 张家港市| 田林县| 阳朔县| 浦城县| 彭阳县| 庆安县| 上蔡县| 澄城县| 盘锦市| 蓬莱市| 太康县| 鄂州市| 长泰县| 玉环县| 孙吴县| 镇江市| 章丘市| 温州市| 惠安县| 江阴市| 虞城县| 涟源市| 嵊州市| 沧州市| 昆明市| 武汉市| 徐水县| 剑川县| 重庆市| 会泽县| 勃利县| 平乐县| 大港区| 宝鸡市| 龙岩市| 麻城市| 台东市| 湘阴县| 西青区| 汾阳市|