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

第3章 PHP基本語法詳解

PHP的語法與C語言很相似,如果有C語言編程經(jīng)驗,很容易上手。本章將詳細(xì)介紹PHP的基本語法,內(nèi)容涵蓋了最基本的數(shù)據(jù)類型、變量、操作符、數(shù)組、字符串操作和流程控制語句。

3.1 在HTML中嵌入PHP

大多數(shù)PHP代碼被嵌入HTML或XML文件中,為了識別PHP代碼的執(zhí)行區(qū)域和非PHP源代碼,PHP提供了以下4種方法:

1. PHP代碼段以<? php開始,以?>結(jié)束。

        <? php
            //PHP代碼
        ?>

2.可以使用縮寫的<?開始,以?>結(jié)束。

        <?
            //PHP代碼
        ?>

3.使用script標(biāo)記

        <script language="php">
            //PHP代碼
        </script>

從HTML中區(qū)分PHP代碼塊的方法是使用一個<script>標(biāo)簽來允許在HTML頁面中進行PHP編程,PHP代碼被嵌入JavaScirpt的標(biāo)簽中,只需簡單地指定 "PHP" 作為標(biāo)簽屬性language的值:

        <script language=”php" >
            echo  "hello" ;
        </script>

4.可以使用<%作為開始,以%>結(jié)束.

        <%
            //PHP代碼
        %>

1. 和2. 是最常見的用法。3. 是類似JavaScript的編寫方式。

對于從Windows平臺的ASP投向PHP的使用者來說,4. 似曾相似,只要用PHP 3.0.4版本以后的服務(wù)器都可以用<%作為開始,以%>作為結(jié)束PHP的區(qū)段;但運用4. 的使用者別忘了在php.ini加入asp_tags,或是在編譯PHP時加入--enable-asp-tags的選項,才能使4. 有效。建議少用4.,當(dāng)PHP與ASP源代碼混在一起時就麻煩了。

優(yōu)先選用的方式為1.<? php...? >,在XML或者XHTML中嵌入PHP代碼,需要使用<? php...? >形式的標(biāo)記以適應(yīng)XML的標(biāo)準(zhǔn)。

PHP代碼每條簡單語句以分號結(jié)尾。復(fù)合語句用大括號來標(biāo)記代碼塊,在右括號后面不要用分號。和其他語言不一樣的地方是,右括號前的分號是必須的,例如:

        If ($IsValue == TRUE)
        {
            echo   "true" ;    //這里要求有分號
        }                   //這里不要求有分號

PHP結(jié)束標(biāo)簽前的分號是可選的:

        <? PHP
            echo   "hello"     // PHP結(jié)束標(biāo)簽前不要求有分號
        ?>

包含可選分號是好的編程習(xí)慣,這樣做使得以后更容易添加代碼。不推薦省略分號,因為這有可能在修改代碼時導(dǎo)致出錯。

PHP插入注釋時使用符號“//”,例:

        echo   "hello"         // PHP結(jié)束標(biāo)簽前不要求有分號
        使用/*和*/可插入注釋塊:
        /*
          這是一個Cookie函數(shù)
        */

下面是一個完整的在HTML中嵌入PHP的例子:

        <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
        <HTML>
        <HEAD>
        <TITLE> HTML中嵌入PHP的例子</TITLE>
        </HEAD>
        <BODY>
            <p>我最喜歡的顏色:
              <? php  echo “紅色”; ? >
        </p>
        </BODY>
        </HTML>

運行結(jié)果如圖3-1所示:

圖3-1 HTML中嵌入PHP

當(dāng)用戶訪問此頁面并且查看源代碼時,看到的是:

        <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
        <HTML>
        <HEAD>
        <TITLE> HTML中嵌入PHP的例子</TITLE>
        </HEAD>
        <BODY>
            <p>我最喜歡的顏色:紅色</p>
        </BODY>
        </HTML>

在此頁面的源代碼中,看不到PHP代碼蹤跡,用戶看到的是PHP代碼的輸出結(jié)果。PHP代碼可以放在文件的任何地方,甚至是有效的HTML標(biāo)簽中。例如:

        <INPUT TYPE="text" NAME="FileName" value=”<? php echo “文件名”? >”>

也可以插入到JavaScript代碼中,以達(dá)到PHP給JavaScript變量賦值的效果:

        <SCRIPT LANGUAGE="JavaScript">
        <! -
            Var FileName = ‘<? php echo “文件名”? >' ;
        //-->
        </SCRIPT>

上面這段代碼等效于:

        <SCRIPT LANGUAGE="JavaScript">
        <! -
            Var FileName = ‘文件名’;
        //-->
        </SCRIPT>

3.2 PHP5.0的變量

3.2.1 常量

常量是一個簡單值的標(biāo)識符,在腳本執(zhí)行期間其值是不能改變的。常量默認(rèn)為大小寫敏感。按照慣例,常量標(biāo)識符總是大寫的。

常量名和其他任何PHP標(biāo)簽遵循同樣的命名規(guī)則,合法的常量名以字母或下劃線開始,后面跟著任何字母,數(shù)字或下劃線。常量的范圍是全局的,不用管作用域就可以在腳本的任何地方訪問常量。

常量使用define ()函數(shù)來定義,一旦被定義,就不能再改變或者取消定義。

常量只能包含標(biāo)量數(shù)據(jù)(boolean, integer, float和string)。

可以簡單地通過指定其名字來取得常量的值,不要在常量前面加上$符號。如果常量名是動態(tài)的,也可以用函數(shù)constant ()來讀取常量的值。用get_defined_constants ()可以獲得所有已定義的常量列表。

注意:常量和(全局)變量在不同的名字空間中。這意味著例如TRUE和$TRUE是不同的。

如果使用了一個未定義的常量,PHP假定想要的是該常量本身的名字,如同用字符串調(diào)用它一樣(CONSTANT對應(yīng)"CONSTANT")。此時將發(fā)出一個E_NOTICE級的錯誤。如果只想檢查是否定義了某常量,可以用defined ()函數(shù)來查看。

常量和變量的不同:

● 常量前面沒有美元符號($);

● 常量只能用define ()函數(shù)定義,而不能通過賦值語句;

● 常量可以不用理會變量范圍的規(guī)則而在任何地方定義和訪問;

● 常量一旦定義就不能被重新定義或者取消定義;

● 常量的值只能是標(biāo)量。

定義常量例子:

        <? php
        define ("CONSTANT", "Hello world.");
        echo CONSTANT; // 輸出 "Hello world."
        ?>

PHP提供了大量的預(yù)定義常量。不過很多常量都是由不同的擴展庫定義的,只有在加載了這些擴展庫時才會出現(xiàn),可以是動態(tài)加載,或者在編譯時就已經(jīng)包括進去了。

有四個魔術(shù)常量根據(jù)它們使用的位置而改變。例如__LINE__的值就依賴于它在腳本中所處的行來決定。這些特殊的常量不區(qū)分大小寫,如表3-1所示。

表3-1 php的魔術(shù)變量

3.2.2 初始化變量

PHP中一個美元符號后面跟上一個變量名稱,即表示一個變量。變量的名稱是對大小寫敏感的。變量名與PHP中其他的標(biāo)簽一樣遵循相同的命名規(guī)則。變量命名規(guī)則有:

● 第一個符號必須為字母或是一下劃線。

● 變量可以只包含字母以及下劃線。

● 變量要是包含多個字意的話,應(yīng)該使用下劃線來隔開。

        例如:$var = “0”; // 定義一個變量
              $hello
              $hello_value
              $InValue
              $_int

上面都是正確的變量名,下面是一些非法的變量名:

        $hello value    //變量名不能包含空格
        $'              //變量名不能包含特殊字符
        $3hello         //變量不能以數(shù)字開頭

變量名區(qū)別大小寫,下面這些變量是不相同的。

        $inData $INDATA $INdata

PHP4.0提供了另外一種給變量賦值的方式:傳地址賦值。這意味著新的變量簡單地引用了原始變量。改動新的變量將影響到原始變量,反之亦然。這同樣意味著其中沒有執(zhí)行復(fù)制操作;因而,這種賦值操作更加快速。

使用傳地址賦值,簡單地追加一個(&)符號到將要賦值的變量前(源變量)。例如,下列代碼片斷兩次輸出‘My name is Bob' :

        <? php
        $foo = ' Bob' ;               // 賦值 ’ Bob’ 給變量 $foo
        $bar = &$foo;               // 把變量 $foo的地址賦值給變量 $bar.
        $bar = "My name is $bar";    // 使用$bar變量
        echo $bar;                  // 顯示變量$bar的值為Bob
        echo $foo;                  // 顯示變量$bar的值為Bob
        ?>

運行結(jié)果如圖3-2所示:

圖3-2 初始化變量

需要注意的是只有命名變量才可以傳地址賦值,這一點非常重要。

        <? php
        $foo = 25;
        $bar = &$foo;               // 把變量 $foo的地址賦值給變量 $bar.
        $bar = &(24 * 7);           // 錯誤用法,只有命名變量才可以傳地址賦值
        function test ()
        {
          return 25;
        }
        $bar = &test ();   // 錯誤的用法
        ?>

變量可以存放任何類型的值,可以用另一個不同類型的值取代變量的值:

        $inData =   "hello, word" ;
        $inData = 100;
        $inData = Array (1,2,3,4);

在PHP中沒有顯示的語法來聲明變量,在第一次設(shè)置變量值時,變量就被創(chuàng)建了。一個沒有設(shè)置值的變量,其值為NULL。

3.2.3 類型的轉(zhuǎn)換和變化

PHP在變量定義中不需要明確的類型定義;變量類型是根據(jù)使用該變量的上下文所決定的。也就是說,如果把一個字符串值賦給變量$var, $var的值就成了一個字符串。如果又把一個整型值賦給$var,那它的值就成了一個整數(shù)。

PHP自動類型轉(zhuǎn)換的一個例子是加號“+”。如果任何一個運算數(shù)是浮點數(shù),則所有的運算數(shù)都被當(dāng)成浮點數(shù),結(jié)果也是浮點數(shù)。否則運算數(shù)會被解釋為整數(shù),結(jié)果也是整數(shù)。注意這并沒有改變這些運算數(shù)本身的類型;改變的僅是這些運算數(shù)如何被求值。

        <? php
        $foo = "0";                     // $foo為字符串(ASCII 48)
        $foo += 2;                      // $foo為整型(2)
        $foo = $foo + 1.3;          // $foo為浮點數(shù)(3.3)
        $foo = 5 + "10 Little Piggies";  // $foo為整型(15)
        $foo = 5 + "10 Small Pigs";  // $foo為整型(15)
        ?>

PHP支持通過偏移量進行的字符串索引,這和數(shù)組索引的語法一樣,下面是這種使用方法的例子:

        <? php
        $a   = "abc";       // $a為一個字符串
        $a{1} = "f";        // $a目前為 "afc"
        ?>

PHP中的類型強制轉(zhuǎn)換和C中的非常類似:在要轉(zhuǎn)換的變量之前加上用括號括起來的目標(biāo)類型。

下面是演示PHP類型強制轉(zhuǎn)換的例子:

        <? php
        $foo = 10;                  // $foo為整型
        $bar = (boolean) $foo;       // $bar為布爾型
        ?>

允許的強制轉(zhuǎn)換有:

(int),(integer)——轉(zhuǎn)換成整型

(bool),(boolean)——轉(zhuǎn)換成布爾型

(float),(double),(real)——轉(zhuǎn)換成浮點型

(string)——轉(zhuǎn)換成字符串

(array)——轉(zhuǎn)換成數(shù)組

(object)——轉(zhuǎn)換成對象

注意:在括號內(nèi)允許有空格和制表符,所以下面兩個例子功能相同:

        <? php
        $foo = (int) $bar;
        $foo = (int) $bar;
        ?>

注意:為了將一個變量還原為字符串,可以將變量放置在雙引號中。

        <? php
        $foo = 1;                   // $foo為整型
        $str = "$foo";              // $str為字符串
        $fst = (string) $foo;        // $fst強制轉(zhuǎn)變?yōu)樽址?
        // 輸出 "使用雙引號還原成字符串"
        if ($fst == $str) {
            echo "使用雙引號還原成字符串";
        }
        ?>

3.2.4 獲取或設(shè)置變量類型

可以使用gettype函數(shù)來獲取變量類型。

gettype:獲取變量類型。

返回的字符串的可能值為:

● "boolean" (從PHP 4.2.0起)

● "integer"

● "double" (由于歷史原因,如果是float則返回 "double",而不是 "float")

● "string"

● "array"

● "object"

● "resource"(從PHP 4.2.0起)

● "NULL" (從PHP 4.2.0起)

● "unknown type"

注意:一般不建議使用gettype函數(shù)來測試某種變量類型,因為其返回的字符串在未來的版本中可能需要改變。此外,由于包含了字符串的比較,其運行效率也是較慢的。建議使用is_array ()、is_bool ()、is_float ()、is_integer ()、is_null ()、is_numeric ()、is_object ()、is_resource ()、is_scalar () 、is_string ()函數(shù)代替。

PHP使用settype函數(shù)來設(shè)置變量的類型:

        bool settype (mixed var, string type)

將變量var的類型設(shè)置成type。

type的可能值為:

● "boolean" (或為 "bool",從PHP 4.2.0起)

● "integer" (或為 "int",從PHP 4.2.0起)

● "float" (只在PHP 4.2.0之后可以使用)

● "string"

● "array"

● "object"

● "null" (從PHP 4.2.0起)

如果成功則返回TRUE,失敗則返回FALSE。

settype ()函數(shù)示例:

        <? php
        $foo = "1hello";        // $foo為字符串
        $bar = true;                //$bar為布爾型
        settype ($foo, "integer");    // $foo現(xiàn)在是 5  (integer)
        settype ($bar, "string");     // $bar現(xiàn)在是 "1" (string)
        ?>

3.3 運算符及其優(yōu)先級

3.3.1 算術(shù)運算符

表3-2 算術(shù)運算符

3.3.2 賦值運算符

表3-3 賦值運算符

3.3.3 位運算符

表3-4 位運算符

3.3.4 邏輯運算符

表3-5 邏輯運算符

3.3.5 比較運算符

表3-6 比較運算符

3.3.6 執(zhí)行運算符

PHP支持一個執(zhí)行運算符:反引號(``)。PHP嘗試將反引號中的內(nèi)容作為外殼命令來執(zhí)行,并返回其輸出信息。使用反引號運算符“`”的效果與函數(shù)shell_exec ()相同。

        <? php
        $output = `ls -al`;
        echo "<pre>$output</pre>";
        ?>

注意:反引號運算符在安全模式下或者關(guān)閉了shell_exec ()時是無效的。

3.3.7 字符串運算符

有兩個字符串運算符。第一個是連接運算符(“.”),它返回其左右參數(shù)連接后的字符串。第二個是連接賦值運算符(“.=”),它將右邊參數(shù)附加到左邊的參數(shù)后。

      $a = "Hello ";
      $b = $a ."World! ";  // 變量$b的值為"Hello World! "
      $a = "Hello ";
      $a .= "World! ";    // 變量$a的值為"Hello World! "

3.3.8 錯誤控制運算符

PHP支持一個錯誤控制運算符:@。當(dāng)將其放置在一個PHP表達(dá)式之前,該表達(dá)式可能產(chǎn)生的任何錯誤信息都將被忽略掉。

如果激活了track_errors特性,表達(dá)式所產(chǎn)生的任何錯誤信息都被存放在變量$php_errormsg中。此變量在每次出錯時都會被覆蓋,如果想用它的錯誤信息可以對它進行檢查。

        <? php
        /*文件錯誤信息*/
        $my_file = @file (' non_existent_file') or
            die ("打開文件失敗:錯誤為:' $php_errormsg' ");
        //
        $value = @$cache[$key];
        ?>

注意:@ 運算符只對表達(dá)式有效。例如,可以把它放在變量、函數(shù)和include ()調(diào)用、常量等等之前,不能把它放在函數(shù)或類的定義之前,也不能用于條件結(jié)構(gòu),例如if和foreach等。

3.4 流程控制

3.4.1 if..else條件控制

if結(jié)構(gòu)是很多語言包括PHP在內(nèi)的重要特性之一,它允許按照條件執(zhí)行代碼片段。PHP的if結(jié)構(gòu)和C語言相似:

        if (expr)
            statement

expr按照布爾求值。如果expr的值為TRUE, PHP將執(zhí)行statement;如果值為FALSE,將忽略statement。

如果$a大于$b,則以下例子將顯示$a大于$b:

        <? php
        if ($a > $b)
            echo  "$a大于$b";
        ?>

經(jīng)常需要按照條件執(zhí)行不止一條語句,當(dāng)然并不需要給每條語句都加上一個if子句。可以將這些語句放入語句組中。例如,如果$a大于$b,以下代碼將顯示$a大于$b,并且將$a的值賦給$b:

        <? php
        if ($a > $b) {
            echo  "$a大于 $b";
          $b = $a;
      }
      ?>

if語句可以無限層地嵌套在其他if語句中。經(jīng)常需要在滿足某個條件時執(zhí)行一條語句,而在不滿足該條件時執(zhí)行其他語句,可以使用else的功能。else延伸了if語句,可以在if語句中的表達(dá)式的值為FALSE時執(zhí)行語句。例如以下代碼在$a大于$b時顯示$a大于$b,反之則顯示$a小于$b:

        <? php
        if ($a > $b) {
            echo  "$a大于 $b";
        } else {
            echo "$a小于 $b";
        }
        ?>

else語句僅在if以及elseif(如果有的話)語句中的表達(dá)式的值為FALSE時執(zhí)行。

elseif,和此名稱暗示的一樣,是if和else的組合。和else一樣,它延伸了if語句,可以在原來的if表達(dá)式值為FALSE時執(zhí)行不同語句。但是和else不一樣的是,它僅在elseif的條件表達(dá)式值為TRUE時執(zhí)行語句。例如以下代碼將根據(jù)條件分別顯示$a大于$b, $a等于$b或者$a小于$b:

        <? php
        if ($a > $b) {
            echo "$a大于$b";
        } elseif ($a == $b) {
            echo  "$a等于 $b";
        } else {
            echo  "$a小于 $b";
        }
        ?>

在同一個if結(jié)構(gòu)中可以有多個elseif語句。第一個表達(dá)式值為TRUE的elseif語句將會執(zhí)行。在PHP中,也可以寫成 "else if",它和 "elseif" 的行為完全一樣。elseif的語句僅在之前的if或elseif的表達(dá)式值為FALSE時執(zhí)行,而當(dāng)前的elseif表達(dá)式值要為TRUE時執(zhí)行。

3.4.2 switch條件控制

switch語句和具有同樣表達(dá)式的一系列的IF語句相似。在需要時把同一個變量或表達(dá)式與很多不同的值比較,并根據(jù)它等于哪個值來執(zhí)行不同代碼時可以使用switch語句。

下面兩個例子使用兩種不同方法實現(xiàn)同樣的功能,一個用一系列的if語句,另一個用switch語句:

        <? php
        //使用if ..elseif語句的代碼
        if ($i == 0) {
            echo "i等于 0";
        } elseif ($i == 1) {
            echo "i等于 1";
        } elseif ($i == 2) {
            echo "i等于 2";
        }
        //使用switch的代碼,等效于上面的代碼
        switch ($i) {
            case 0:
              echo "i等于 0";
              break;
            case 1:
              echo "i等于 1";
              break;
            case 2:
              echo "i等于 2";
              break;
        }
        ?>

switch語句一行接一行地執(zhí)行,開始時沒有代碼被執(zhí)行,僅當(dāng)一個case語句中的值和switch表達(dá)式的值匹配時PHP才開始執(zhí)行語句,直到switch的程序段結(jié)束或者遇到第一個break語句為止。如果不在case的語句段最后寫上break的話,PHP將繼續(xù)執(zhí)行下一個case中的語句段。例如:

        <? php
        switch ($i) {
            case 0:
              echo "i等于 0";
            case 1:
              echo "i等于 1";
            case 2:
              echo "i等于 2";
        }
        ?>

在上面的例子中,如果$i等于0, PHP將執(zhí)行所有的echo語句。如果$i等于1, PHP將執(zhí)行后面兩條echo語句。只有當(dāng)$i等于2時,才得到“預(yù)期”的結(jié)果——只顯示 "i等于2”。所以,別忘了break語句就很重要。

在switch語句中條件只求值一次并用來和每個case語句比較,而在elseif語句中條件會再次求值。如果條件比一個簡單的比較要復(fù)雜得多或者在一個很多次的循環(huán)中,那么用switch語句可能會快一些。

在一個case中的語句也可以為空,這樣只不過將控制轉(zhuǎn)移到了下一個case中的語句。

        <? php
        switch ($i) {
            case 0:
          case 1:
          case 2:
              echo "i不等于3";
              break;
          case 3:
              print "i等于3";
      }
      ?>

還可以在switch語句中添加default,當(dāng)條件和case都不匹配的情況時就執(zhí)行default后的語句,default語句應(yīng)該放在最后一條case語句后面。例如:

        <? php
        switch ($i) {
            case 0:
              echo "i等于 0";
              break;
            case 1:
              echo "i等于1";
              break;
            case 2:
              echo "i等于2";
              break;
            default:
              echo "i不等于 0、 1或者2";
        }
        ?>

case表達(dá)式可以是任何求值為簡單類型的表達(dá)式,即整型或浮點數(shù)以及字符串。不能用數(shù)組或?qū)ο螅撬鼈儽唤獬说胶唵晤愋偷囊谩?/p>

switch支持轉(zhuǎn)換替代的流程控制。例如:

        <? php
        switch ($i):
            case 0:
              echo "i等于 0";
              break;
            case 1:
              echo "i等于1";
              break;
            case 2:
              echo "i等于2";
              break;
            default:
              echo "i不等于 0、 1或者2";
        endswitch;
        ?>

注意:與其他語言不同,continue語句作用到switch上的作用類似于break。如果在循環(huán)中有一個switch并希望continue到外層循環(huán)中的下一個輪回,用continue 2。

下面是在switch語句中使用continue的例子:

        <? php
        $i = 1;
        while ($i <= 10) {
            switch ($i) {
            case 0:
              echo "i等于 0";
              break;
            case 1:
              echo "i等于1";
              break;
            case 2:
              echo "i等于2";
              continue 2;           //跳出while循環(huán)
            default:
              echo "i不等于 0、 1或者2";
        }
        }
        ?>

3.4.3 for循環(huán)

for循環(huán)是PHP中最復(fù)雜的循環(huán)結(jié)構(gòu),它的行為和C語言的相似。for循環(huán)的語法是:

        for (expr1; expr2; expr3) statement

expr1:在循環(huán)開始前無條件求值一次。

expr2:在每次循環(huán)開始前求值。如果值為TRUE,則繼續(xù)循環(huán),執(zhí)行嵌套的循環(huán)語句。如果值為FALSE,則終止循環(huán)。

expr3:在每次循環(huán)之后被求值執(zhí)行。

每個表達(dá)式都可以為空。expr2為空意味著將無限循環(huán)下去,PHP默認(rèn)其值為TRUE。這可能不如想像中那樣沒有用,因為經(jīng)常會希望用break語句來結(jié)束循環(huán)而不是用for的表達(dá)式真值判斷。

以下的例子它們都顯示數(shù)字1到10:

        <? php
        /* 例1 */
        for ($i = 1; $i <= 10; $i++) {
            echo $i;
        }
        /* 例2 */
        for ($i = 1; ; $i++) {
            if ($i > 10) {
              break;        //如果$i>10則跳出for循環(huán)
            }
            echo $i;
        }
        /* 例3 */
        $i = 1;
        for (; ;) {
            if ($i > 10) {
              break;        //如果$i>10則跳出for循環(huán)
            }
            echo $i;     //輸出$i
            $i++;            //$i自增1
        }
        /* 例4 */
        for ($i = 1; $i <= 10; echo $i, $i++);
        ?>

輸出結(jié)果都是:12345678910

第一個例子和第四個例子最常用,但有的時候for循環(huán)中用空的表達(dá)式會很方便。

PHP也支持用冒號的for循環(huán)的替代語法。

        for (expr1; expr2; expr3): statement; ...; endfor;

例如:

        <? php
        /* 例1 */
        for ($i = 1; $i <= 10; $i++) :
            echo $i;
        endfor
        ?>

3.4.4 while循環(huán)

while循環(huán)是PHP中最簡單的循環(huán)類型,它和C語言中的while的用法一樣。while語句的基本格式是:

        while (expr) statement

while語句的含意很簡單,只要while表達(dá)式的值為TRUE就重復(fù)執(zhí)行嵌套中的循環(huán)語句。表達(dá)式的值在每次開始循環(huán)時檢查,所以即使這個值在循環(huán)語句中改變了,語句也不會停止執(zhí)行,直到本次循環(huán)結(jié)束。有時候如果while表達(dá)式的值一開始就是FALSE,則循環(huán)語句一次都不會執(zhí)行。

和if語句一樣,可以在while循環(huán)中用花括號括起一個語句組,或者用替代語法:

        while (expr): statement ...endwhile;

下面兩個例子完全一樣,都顯示數(shù)字1到10:

        <? php
        /* 例子1 */
        $i = 1;
        while ($i <= 10) {
            echo $i++;  /* 輸出$i*/
        }
        /* 例子 2 */
        $i = 1;
        while ($i <= 10):
            echo $i;  //輸出$i
            $i++;        //$i=$i+1
        endwhile;
        ?>

3.4.5 do…while循環(huán)

do..while和while循環(huán)非常相似,區(qū)別在于表達(dá)式的值是在每次循環(huán)結(jié)束時檢查而不是在開始時。和正規(guī)的while循環(huán)相比主要的區(qū)別是do..while的循環(huán)語句保證會執(zhí)行一次,表達(dá)式的真值在每次循環(huán)結(jié)束后檢查,然而在正規(guī)的while循環(huán)中就不一定了,表達(dá)式真值在循環(huán)開始時檢查,如果一開始就為FALSE則整個循環(huán)立即終止。

do..while循環(huán)只有一種語法:

        do{
            statement
        }while (expr)

下面是一個使用do..while的例子:

        <? php
        $i = 0;
        do {
          echo $i;  //輸出$i
          $i++;     //$i=$i+1
        } while ($i > 0);
        ?>

以上循環(huán)將正好運行一次,因為經(jīng)過第一次循環(huán)后,當(dāng)檢查表達(dá)式的真值時,其值為FALSE($i不大于0)而導(dǎo)致循環(huán)終止。

熟悉C語言的用戶可能熟悉另一種不同的do..while循環(huán)用法,把語句放在do..while (0)之中,在循環(huán)內(nèi)部用break語句來結(jié)束執(zhí)行循環(huán)。

以下代碼示范了此方法:

        <? php
        $i=10;
        do {
            if ($i < 5) {
              echo "i小于5";
              break;
            }
          $i--;
        } while (0);
        ?>

3.4.6 foreach循環(huán)

PHP 4包括了foreach結(jié)構(gòu),和Perl以及其他語言很像,這只是一種遍歷數(shù)組簡便方法。foreach僅能用于數(shù)組,當(dāng)試圖將其用于其他數(shù)據(jù)類型或者一個未初始化的變量時會產(chǎn)生錯誤。語法如下:

        foreach (array_expression as $value) statement
        foreach (array_expression as $key => $value) statement

第一種格式遍歷給定的array_expression數(shù)組。每次循環(huán)中,當(dāng)前單元的值被賦給$value并且數(shù)組內(nèi)部的指針向前移一步,下一次循環(huán)中將會得到下一個單元。

第二種格式實現(xiàn)同樣的功能,當(dāng)前單元的鍵值在每次循環(huán)中被賦給變量$key。

注意:當(dāng)foreach開始執(zhí)行時,數(shù)組內(nèi)部的指針會自動指向第一個單元,這意味著不需要在foreach循環(huán)之前調(diào)用reset ()。

foreach操作的是指定數(shù)組的一個拷貝,而不是該數(shù)組本身。因此即使有each ()的構(gòu)造,原數(shù)組指針也沒有變,數(shù)組單元的值也不受影響。

注意:foreach不支持用“@”來禁止錯誤信息的能力。

以下的代碼功能完全相同:

        <? php
        $arr = array ("英格蘭", "巴西", "意大利");   //定義一個數(shù)字索引從 0開始的數(shù)組
        //將數(shù)組的內(nèi)部指針指向第一個單元
        reset ($arr);
        /*
        使用while語句遍歷數(shù)組
        list函數(shù):把數(shù)組中的值賦給一些變量
        each函數(shù):返回數(shù)組中當(dāng)前的鍵/值對并將數(shù)組指針向前移動一步
        */
        while (list (, $value) = each ($arr)) {
            echo "值:$value<br>\n";      //顯示數(shù)組值
        }
        //使用foreach語句遍歷數(shù)組
        foreach ($arr as $value) {
            echo "值:$value<br>\n";      //顯示數(shù)組值
        }
        ?>

再來看一個例子,以下的代碼功能完全相同:

        <? php
        $arr = array ("英格蘭", "巴西", "意大利");
        reset ($arr);
        //使用while語句遍歷數(shù)組
        while (list ($key, $value) = each ($arr)) {
            echo "Key: $key; Value: $value<br>\n";    //顯示鍵及鍵值
        }
        //使用foreach語句遍歷數(shù)組
        foreach ($arr as $key => $value) {
            echo "Key: $key; Value: $value<br>\n";    //顯示鍵及鍵值
    }
    ?>

輸出結(jié)果如圖3-3所示:

圖3-3 foreach循環(huán)

下面是foreach用法的一些范例:

    <? php
    /* foreach例子1*/
    $a = array (1, 2, 3, 17);
    foreach ($a as $v) {
      echo " 值為:$v\n ";
    }
    /* 輸出結(jié)果為:值:1值:2值:3值:17*/
    /* foreach例子2 */
    $a = array (1, 2, 3, 17);
    $i = 0; /* 數(shù)字索引*/
    foreach ($a as $v) {
        echo " [$i] => $v\n";    //使用數(shù)組下標(biāo)
        $i++;
    }
    /* 輸出結(jié)果為:[0] => 1 [1] => 2 [2] => 3 [3] => 17 */
    /* foreach例子 3 */
    $a = array (
        "one" => 1,
        "two" => 2,
        "three" => 3,
        "seventeen" => 17
    );
    foreach ($a as $k => $v) {
        echo "[$k] => $v\n"; //顯示鍵及鍵值
    }
    /* 輸出結(jié)果為:[one] => 1 [two] => 2 [three] => 3 [seventeen] => 17  */
    /* foreach例子 4,遍歷一個二維數(shù)組 */
    $a[0][0] = "a";
        $a[0][1] = "b";
        $a[1][0] = "y";
        $a[1][1] = "z";
        // foreach嵌套的例子
        foreach ($a as $v1) {
            foreach ($v1 as $v2) {
              echo  "$v2\n";
            }
        }
        /* 輸出結(jié)果為:a b y z  */
        /* foreach例子 5 */
        foreach (array (1, 2, 3, 4, 5) as $v) {
            echo "$v\n";
        }
        /* 輸出結(jié)果為:1 2 3 4 5  */
        ?>

3.4.7 跳轉(zhuǎn)語句

break結(jié)束當(dāng)前for, foreach, while, do..while或者switch結(jié)構(gòu)的執(zhí)行。break可以接受一個可選的數(shù)字參數(shù)來決定跳出幾重循環(huán)。

        <? php
        $arr = array (' one' , ' two' , ' three' , ' four' , ' stop' , ' five');
        //使用while循環(huán)遍歷數(shù)組
        while (list (, $val) = each ($arr)) {
            if ($val == ' stop') {
              break;   /* 跳出while循環(huán),默認(rèn)break 1.*/
            }
            echo "$val<br>\n";
        }
        /* 演示在while循環(huán)中跳出switch的例子. */
        $i = 0;
        while (++$i) {
            switch ($i) {
            case 5:
              echo "At 5<br>\n";
              break 1;  /* 跳出switch循環(huán). */
            case 10:
              echo "At 10; quitting<br>\n";
              break 2;  /* 跳出switch語句和while循環(huán). */
            default:
              break;
            }
        }
        ?>

輸出如圖3-4所示:

圖3-4 break跳轉(zhuǎn)語句

continue在循環(huán)結(jié)構(gòu)中用來跳過本次循環(huán)剩余的代碼,并開始執(zhí)行下一次循環(huán)。

注意:在PHP中switch語句被認(rèn)為是作為continue目的的循環(huán)結(jié)構(gòu)。

continue接受一個可選的數(shù)字參數(shù)來決定跳過幾重循環(huán)到循環(huán)結(jié)尾。

    <? php
    //跳出while循環(huán)
    while (list ($key, $value) = each ($arr)) {
        if (! ($key % 2)) { //跳過奇數(shù)
          continue;
        }
    }
    /* 下面是在while循環(huán)中跳出switch的代碼. */
    $i = 0;
    while ($i++ < 5) {
          while (1) {
          echo "第二層循環(huán)<br>\n";
          while (1) {
              echo "第三層循環(huán)<br>\n";
              continue 3;
          }
          echo "第二層循環(huán)結(jié)束.<br>\n";
        }
        echo "第一層循環(huán)結(jié)束.<br>\n";
    }
    /*輸出結(jié)果為:
    第二層循環(huán)
    第三層循環(huán)
    第二層循環(huán)
    第三層循環(huán)
    第二層循環(huán)
    第三層循環(huán)
    第二層循環(huán)
    第三層循環(huán)
    第二層循環(huán)
    第三層循環(huán)*/
    ?>

3.5 數(shù)組

3.5.1 初始化數(shù)組

數(shù)組可以使用下述兩種方法來進行賦值:

● 使用一系列連續(xù)數(shù)值;

● 使用array ()函數(shù)構(gòu)造。

函數(shù)array ():新建一個數(shù)組。array的語法為 "index => values",用逗號分開,定義了索引和值,索引可以是字符串或數(shù)字。如果省略了索引,會自動產(chǎn)生從0開始的整數(shù)索引。如果索引是整數(shù),則下一個產(chǎn)生的索引將是目前最大的整數(shù)索引+1。注意如果定義了兩個完全一樣的索引,則后面一個會覆蓋前一個。

例如:$color_arr = array (“紅色”, ”藍(lán)色”, ”黑色”);

要將連續(xù)的數(shù)值加進數(shù)組,只需將要賦值賦給不帶下標(biāo)的數(shù)組變量,該值會作為數(shù)組的最后元素加進數(shù)組中。

例:

        $color_arr[]="紅色";   //$color_arr[0]="紅色"
        $color_arr[]="黑色";   //$color_arr[1]="黑色"

3.5.2 獲得數(shù)組的大小

PHP中可以使用函數(shù)count ()和sizeof ()函數(shù)獲得數(shù)組的元素數(shù)。

count ()函數(shù)原型為:int count (mixed var [, int mode]),返回var中的單元數(shù)目。可選的mode參數(shù)設(shè)為COUNT_RECURSIVE(或1), count ()將遞歸地對數(shù)組計數(shù)。對計算多維數(shù)組的所有單元尤其有用。mode的默認(rèn)值是0。

下面是通過count ()函數(shù)遞歸得到數(shù)組大小例子:

        <? php
        $color_arr = array (' color1'  => array (‘紅色’, ’ 綠色’, ’藍(lán)色’),
                  'color2'  => array (’黑色’, ’白色’));
        // count遞歸
        echo count ($color_arr, COUNT_RECURSIVE);      // 輸出 7
        // count
        echo count ($color_arr);                     // 輸出 2
        ?>

sizeof ()函數(shù)是count ()函數(shù)的別名,用法和count ()函數(shù)相同

3.5.3 對數(shù)組進行排序操作

排序改變數(shù)組中元素的內(nèi)部順序,并且通過重新寫鍵來反映這個新順序。PHP提供三種方法來對數(shù)組進行排序操作,分別為:鍵排序、值排序不改變鍵值和值排序改變鍵值。每一種排序可以是升序、降序和由用戶自定義函數(shù)定義的順序。

PHP提供的排序函數(shù)如表3-7所示。

表3-7 PHP排序數(shù)組函數(shù)

下面的代碼實現(xiàn)的是按字母升序排序顏色:

        <? php
        $color_arr = array ("blue", "aliceblue", "gold", "yellow");
        //升序
        sort ($color_arr);      //排序的結(jié)果為:aliceblue、blue、gold、yellow
        ?>

如果要獲取降序的結(jié)果只需要使用rsort ()替換sort ()函數(shù)即可。

如果需要對那些單元順序很重要的結(jié)合數(shù)組進行排序可以使用arsort ()函數(shù),例如:

        <? php
        $color_arr = array ("b"=>" blue ", "a"=>" aliceblue ", "g"=>" gold ", "y"=>"
    yellow ");
        arsort ($color_arr);                //排序
        reset ($color_arr);                 //將數(shù)組的內(nèi)部指針指向第一個單元
        while (list ($key, $val) = each ($color_arr)) {
            echo "$key = $val<br>\n";        //輸出數(shù)組
        }
        ?>

上面的例子輸出的結(jié)果為:

        a = yellow
        d = gold
        b = blue
        c = aliceblue

如果用戶需要按照自己特殊的標(biāo)準(zhǔn)進行排序,可以使用自定義的比較函數(shù)對數(shù)組進行排序。下面是一個使用用戶提供的比較函數(shù)對數(shù)組中的鍵名進行排序的例子:

        <? php
        /*
        比較函數(shù)
        */
        function cmp ($a, $b) {
            if ($a == $b) return 0;
            return ($a > $b) ? -1 : 1;
        }
        $a = array (4 => "four", 3 => "three", 20 => "twenty", 10 => "ten");
        uksort ($a, "cmp");             //對鍵名排序
        while (list ($key, $value) = each ($a)) {
          echo "$key: $value\n";       //顯示排序結(jié)果
      }
      ?>

上面的例子將顯示:

        20: twenty 10: ten 4: four 3: three

如果需要對多個數(shù)組或多維數(shù)組進行排序,可以使用array_multisort ()函數(shù)。該函數(shù)排序時保留原有的鍵名關(guān)聯(lián)。函數(shù)原型為:

        bool array_multisort (array ar1 [, mixed arg [, mixed ...[, array ...]]])

第一個參數(shù)ar1必須是一個數(shù)組,后面的每個參數(shù)可以是數(shù)組或者是下面列出的排序標(biāo)志。

排序順序標(biāo)志:

● SORT_ASC - 按照升序排序

● SORT_DESC - 按照降序排序

排序類型標(biāo)志:

● SORT_REGULAR - 將項目按照通常方法比較

● SORT_NUMERIC - 將項目按照數(shù)值比較

● SORT_STRING - 將項目按照字符串比較

每個數(shù)組之后不能指定兩個同類的排序標(biāo)志。每個數(shù)組后指定的排序標(biāo)志僅對該數(shù)組有效,在此之前為默認(rèn)值SORT_ASC和SORT_REGULAR。

如果成功則返回TRUE,失敗則返回FALSE。

例:對多個數(shù)組排序

        <? php
        $ar1 = array ("10", 100, 100, "a");      //數(shù)組1
        $ar2 = array (1, 3, "2", 1);             //數(shù)組2
        array_multisort ($ar1, $ar2);            //排序
        ?>

本例中經(jīng)過排序后,第一個數(shù)組將包含"10", "a",100,100。第二個數(shù)組將包含1, 1, "2",3。第二個數(shù)組中的項目順序完全和第一個數(shù)組中相應(yīng)的項目(100和100)順序一致。

例:對多維數(shù)組排序

        <? php
        //定義一個多維數(shù)組
        $arr = array (array ("10", 100, 100, "a"),
                array (1, 3, "2", 1));
        //對多維數(shù)組進行排序
        array_multisort ($arr[0], SORT_ASC, SORT_STRING,
                      $arr[1], SORT_NUMERIC, SORT_DESC);
        //輸出第一個數(shù)組的各元素:
            echo $arr[0][0]."<br>";
            echo $arr[0][1]."<br>";
            echo $arr[0][2]."<br>";
            echo $arr[0][3]."<br>";
            //輸出第二個數(shù)組的各元素:
            echo $arr[1][0]."<br>";
            echo $arr[1][1]."<br>";
            echo $arr[1][2]."<br>";
            echo $arr[1][3];
        ?>

本例中經(jīng)過排序后,第一個數(shù)組將包含"10",100,100, "a"(作為字符串升序排序),第二個數(shù)組將包含1,3, "2",1(作為數(shù)值降序排序)。

3.5.4 搜索數(shù)組中的元素

搜索數(shù)組中的元素可以使用array_search ()函數(shù)。array_search ()函數(shù)在數(shù)組中搜索給定的值,如果成功則返回相應(yīng)的鍵名。函數(shù)原型如下:

        mixed array_search (mixed needle, array haystack [, bool strict])

在haystack中搜索needle參數(shù)并在找到的情況下返回鍵名,否則返回FALSE。

如果可選的第三個參數(shù)strict為TRUE,則array_search ()還將在haystack中檢查needle的類型。

下面是一個使用array_search ()函數(shù)的例子:

        <? php
        $code = array ("a", "b", "a", "c", "a", "b", "b");
        $key1=array_search ("b", $code); //值為1-> $code[1]擁有b
        echo $key1;
        echo $code[1];
        $key2=array_search ("c", $code); //值為 3-> $code[3]擁有c
        echo $key2;
        echo $code[3];
        $key3=array_search ("X", $code); //返回false或空值即’’
        echo $key3;
        ?>

3.6 字符串操作

在編程過程中遇到最多的就是與字符串相關(guān)的操作,PHP提供了大量的字符串操作函數(shù),功能強大,使用也比較簡單。PHP是弱類型語言,所以其他類型的數(shù)據(jù)一般可以直接應(yīng)用于字符串操作函數(shù),自動轉(zhuǎn)換成字符串類型進行處理,如:

        echo substr ("1234567", 1, 3);

        echo substr (123456,1, 3);

輸出的結(jié)果是一樣的。

3.6.1 定義字符串

在PHP中一般用雙引號或單引號標(biāo)識一個字符串。比如:

        $str = "i love u";
        $str = ' i love u' ;

上述兩種方法是有一些區(qū)別的:后者將單引號內(nèi)的所有內(nèi)容都當(dāng)作字符處理;前者則不然。比如:

        $test = "iwind";
        $str = "i love $test";
        $str1 = ' i love $test' ;
        echo $str; //將得到i love iwind
        echo $str1; //將得到i love $test

同樣,以下兩個例子的結(jié)果也是不一樣的:

        echo "i love \test"; // 將得到i love est,已經(jīng)將\t視為轉(zhuǎn)義
        echo ' i love \test' ; // 將得到i love \test

用雙引號括起來的字符串替換變量并且擴展許多PHP轉(zhuǎn)義序列,表3.8列出了PHP的雙引號字符串里的轉(zhuǎn)義序列。

表3-8 PHP轉(zhuǎn)義序列

如果在一個雙引號括起來的字符串里發(fā)現(xiàn)了一個未知轉(zhuǎn)義序列,則該序列將被忽視略。例如:

        $str =  "i love \d test。”;
        echo $str;      //顯示的結(jié)果為:i love \d test。

3.6.2 字符串輸出

PHP里的輸出最常用的是echo, print,它們兩者都不是真正的函數(shù),而是語言構(gòu)造,所以調(diào)用時不必用雙括號(比如echo ("test"); print ("test"))。在輸出的時候兩者都可以實現(xiàn)賦值:

        echo $str="test"; //一方面輸出test,一方面把"test"賦給字符串變量 $str
        print $str="test";

兩者除了名字不一樣外,還存在以下的區(qū)別:print具有返回值,一直返回1,而echo沒有,所以echo比print要快一些:

        $return = print "test";
        echo $return; // 輸出1

也正因為這個原因,print能應(yīng)用于復(fù)合語句中,而echo則不能。

        isset ($str) or print "str變量未定義"; // 將輸出"str變量未定義"
        isset ($str) or echo "str變量未定義";  // 將提示分析錯誤

echo一次可輸出多個字符串,而print則不可以:

        echo "i ", "love ", "iwind";   // 將輸出 "i love iwind"
        print "i ", "love ", "iwind";  // 將提示錯誤

echo, print還可以輸出被稱作“文檔句法”的字符串,句法如:

        echo <<< 標(biāo)簽名稱
        ...
        字符串內(nèi)容
        ...
        標(biāo)簽名稱;

比如:

        echo <<< test
        i love iwind
        test;

注意:語句開始和結(jié)束的兩個標(biāo)簽名稱是一樣的,且后一個標(biāo)簽名稱前不能有空白,即要頂格寫。文檔句法輸出的內(nèi)容識別變量名稱和常用符號,大致形同雙引號的作用。

輸出除echo, print外,PHP還提供了一些格式化字符串的函數(shù),比如printf, sprintf, vprintf, vsprintf。

函數(shù)printf ()將一個通過替換值建立的字符串輸出到格式字符串中,其函數(shù)原型為:

        void printf (string format [, mixed args])

第一個參數(shù)是格式字符串,剩下的參數(shù)是將要替換進來的值,格式字符串里的字符%指出一個替換標(biāo)記。

格式字符串中的每一個替換標(biāo)記都由一個百分號(%)組成,后面可能跟有下面列出的修飾符,并以類型說明符結(jié)尾(用’%%’在輸出中得到單個百分字符)。修飾符必須按下面列出的次序出現(xiàn):

● 一個填充字符,表明該字符用于填充結(jié)果,使結(jié)果為適當(dāng)大小的字符串。規(guī)定其為0、一個空格或任何以一個單引號為前綴的字符,默認(rèn)情況下用空格填充。

● 一個對齊方式字符。符號對字符串和數(shù)字有不同的作用。對于字符串,減號(-)使該字符串右對齊(默認(rèn)為左對齊),對于數(shù)字,加號(+)使正數(shù)在輸出的時候以一個加號開頭。

● 字段寬度。如果結(jié)果少于這個字符串,符號和填充說明符將決定如何填充到這個長度。

● 對于浮點數(shù),一個精確說明符由一個句點和一個數(shù)字組成;該說明符規(guī)定顯示幾位十進制數(shù)。對于非雙精度類型的類型,這個說明符將被忽略。

類型說明符告訴printf ()什么類型的數(shù)據(jù)將被替換,這決定了對前面列出的修飾符的解釋,一共有十二種類型,如表3-9所示。

表3-9 printf ()類型說明符

下面是一些使用printf ()函數(shù)進行輸出的例子:

        printf (‘%.2f' ,30.123);   // 將一個浮點數(shù)轉(zhuǎn)換成只有兩位小數(shù)的數(shù)
        printf (‘%d' ,888);       // 輸出一個十進制
        printf (‘%x' ,888);       //輸出一個十六進制
        printf (‘%100d' ,1);      // 將一個整數(shù)填充成四位十進制
        printf (‘%04d/%02d/%02d' ,2006,2,2); // 格式化一個日期
        printf (‘%.2f%%' ,1.3);    // 輸出一個百分?jǐn)?shù)

函數(shù)sprintf ()所帶的參數(shù)和printf ()函數(shù)一樣,但是返回的是內(nèi)置的字符串而不是輸出,使得可以在變量中存儲字符串供以后使用,例如:

        $isodate = sprintf ("%04d-%02d-%02d", $year, $month, $day);

函數(shù)vprintf ()允許在格式后面用數(shù)組作為參數(shù),用法和printf ()函數(shù)基本相同。

計算字符串長度:

PHP提供strlen函數(shù)來計算字符串的長度:

        $str = "test";
        echo strlen ($str);  // 將輸出 4

strlen將中、日等漢字以及全角字符都當(dāng)作兩個或四個長度來計算。好在mbstring或icon兩個函數(shù)可以幫助解決這個問題,比如:

        $len = iconv_strlen ($str, "GBK");
        $len = mb_strlen ($str, "GBK");

注意:mbstring模塊提供了大量對含有多字節(jié)字符的字符串的處理函數(shù),推薦多加應(yīng)用,由于本章講的是字符串入門,所以不打算詳細(xì)解說。

3.6.3 裁剪

一個字符串首和尾,可能存在不想要的空白符,就可以用trim, rtrim, ltrim等函數(shù),分別去除一個字符串兩端的空白符,一個是字符串尾部空白符,另一個是字符串首部空白符。函數(shù)原型如下:

        trim (string str [, string charlist])
        ltrim (string str [, string charlist])
        rtrim (string str [, string charlist])

可選參數(shù)charlist是一個字符串,該字符串指定所要刪除的字符。默認(rèn)情況下刪除如表3-10中字符。

表3-10 trim ()、ltrim ()和rtrim ()的默認(rèn)刪除字符

        echo trim (" i love you ");   // 將得到 "i love you"
        echo rtrim (" i love you ");  // 將得到 " i love you"
        echo ltrim (" i love you ");  // 將得到 "i love you "

裁剪第二個參數(shù)指定的字符,如:

        echo trim (",10,22,35,44, ", ", "); // 將得到 10,22,35,44兩端的", "號被裁掉了。

3.6.4 大小寫

對于英文字母來說,可以用strtoupper, strtolower將其轉(zhuǎn)變成大寫或小寫。

        strtoupper (str);
        strtolower (str);

下面是轉(zhuǎn)換字符串字母大小的例子:

        echo strtoupper ("Mary Had A Little Lamb "); // 輸出MARY HAD A LITTLE LAMB
        echo strtolower ("Mary Had A Little Lamb "); // 將得到mary had a little lamb

3.6.5 比較

一般可以用!=, = =比較兩個對象是否相等,只所以說是兩個對象,是因為它們不一定全部為字符串,也可以為整型,等等。比如:

        $a = "l love";
        $b = "you";
        if ($a ! = $b)
        {
            echo "不相等";
        }
        else
        {
            echo "相等";
        }

如果用 ! = =, == =(可以看到多了一個等號)比較的話,兩個對象的類型要嚴(yán)格相等才能返回true;否則用= =, ! =則會將字符串自動轉(zhuǎn)換成相應(yīng)的類型,以便進行比較。

        22 == "22";     // 返回true
        22 === "22";    // 返回false

正因為這樣,所以時常會發(fā)生一些想不到的“意外”:

        0 == "我愛你";   // 返回true
        1 == "1我愛你";  // 返回true

PHP里還有這樣一組用于字符串比較的函數(shù):strcmp, strcasecmp, strncasecmp (), strncmp (),如果前者比后者大,則它們都是返回大于0的整數(shù);如果前者比后者小,則返回小于0的整數(shù);如果兩者相等,則返回0。它們比較的原理與其他語言的規(guī)則都是一樣的。

strcmp是用于區(qū)分大小寫(即大小寫敏感)的字符串比較:

        echo strcmp ("abcdd", "aBcde");       // 返回 1 (>0),比較的是 "b"和"B"

strcasecmp用于不區(qū)分大小寫的字符串比較:

        echo strcasecmp ("abcdd", "aBcde");   // 返回 -1 (<0),比較的是"d"和"e"

strncmp用于比較字符串的一部分,從字符串的開頭開始比較,第三個參數(shù),為要比較的長度:

        echo strncmp ("abcdd", "aBcde", 3);   // 返回 1 (>0),比較了abc和aBc。

strncasecmp用于不區(qū)分大小寫的比較字符串的一部分,從字符串的開頭開始比較,第三個參數(shù),為要比較的長度:

        echo strncasecmp ("abcdd", "aBcde", 3);   // 返回 0

比較了abc和aBc,由于不區(qū)分大小寫,所以兩者是相同的。

還有一種情況是單單比較字符串大小還達(dá)不到我們預(yù)定的要求,比如按一般情況10.gif會比5.gif大,但如果應(yīng)用上面幾個函數(shù),就會返回 -1,即表示10.gif比5.gif小,針對這種情況,PHP提供了兩個自然對比的函數(shù)strnatcmp, strnatcasecmp:

        echo strnatcmp ("10.gif", "5.gif"); // 返回 1 (>0)
        echo strnatcasecmp ("10.GIF", "5.gif"); // 返回 1 (>0)

3.6.6 替換

替換的意義在于將一個字符串的一部分進行改變,使之成為一個新的字符串,以滿足新的要求。PHP里通常用str_replace ()函數(shù)進行替換,其函數(shù)原型為:

        str_replace (search, replace, subject [, int &count])

下面是使用str_replace ()函數(shù)的例子:

        echo str_replace ("%body%", "black", "<body text=' %body%' >");
        //輸出"<body text=' black' > "

即將原字符串中的所有"%body%"都替換成了" black "。

str_replace ()函數(shù)對大小寫敏感,還可以實現(xiàn)多對一,多對多的替換,但無法實現(xiàn)一對多的替換:

        $vowels = array ("a", "e", "i", "o", "u", "A", "E", "I", "O", "U");
        echo str_replace ($vowels, "", "Hello World of PHP");

將會輸出

Hll Wrld f PHP

        $phrase  = "You should eat fruits, vegetables, and fiber every day.";
        $healthy = array ("fruits", "vegetables", "fiber");
        $yummy   = array ("pizza", "beer", "ice cream");
        echo  str_replace ($healthy, $yummy, $phrase);

將輸出You should eat pizza, beer, and ice cream every day。也就是說第一個數(shù)組中的元素被第二個數(shù)組中的相對應(yīng)的元素替換掉了,如果有一個數(shù)組比另一個數(shù)組元素數(shù)要少,那么不足的部分都會當(dāng)作空來處理。

此外,PHP還提供了substr_replace函數(shù)用來實現(xiàn)替換字符串的一部分,具體語法如下:

        substr_replace (str, replacement, start [, int length])

參數(shù)str為原字符串,參數(shù)replacement為要替換的字符串,參數(shù)start為開始替換位置,參數(shù)length為替換的長度。

其中,開始替換的位置從0開始計算,應(yīng)該小于原字符串的長度。要替換的長度是可選的。

        echo substr_replace ("abcdefgh", "DEF", 3);       // 將輸出 "abcDEF"
        echo substr_replace ("abcdefgh", "DEF", 3, 2);    // 將輸出 "abcDEFfgh"

第一個例子中,從第三個位置(即"d")開始替換,從而把 "defgh"都替換成了 "DEF"。

第二個例子中,也是從第三個位置(即"d")開始替換,但只能替換2個長度,即到e,所以就把"de"替換成了"DEF"。

PHP還提供了preg_replace, preg_replace_callback, ereg_replace, eregi_replace等函數(shù)應(yīng)用正則表達(dá)式來完成字符串替換。

3.6.7 查找與匹配

PHP里用于查找、匹配或者定位的函數(shù)非常多,它們都有不同的意義。這里只講述用得比較多的strstr與stristr,它們兩者的功能、返回值都一樣,只是不區(qū)分大小寫。

strstr ()函數(shù)用來查找子字符串在母字符串中第一次出現(xiàn)的位置,并返回母字符串中從子字符串開始到母字符串結(jié)束的部分。語法如下:

        strstr (haystack, needle)

其中haystack為母字符串,needle為子字符串。

比如:

        echo strstr ("abcdefg", "e"); //將輸出 "efg"

如果找不到子字符串,則返回空。因為可以用來判斷一個字符串中是否含有另外一個字符串:

        $needle = "you";
        $str = "i love you";
        if (strstr ($str, $needle))
        {
            echo "里面有you";
        }
        else
        {
            echo "里面沒有you";
        }

將會輸出"里面有you"。

3.6.8 HTML相關(guān)

1.htmlspecialchars($string)

函數(shù)htmlspecialchars ()將特殊字符轉(zhuǎn)成HTML的字符串格式,該函數(shù)轉(zhuǎn)換的特殊字符為:

● &(和)轉(zhuǎn)成 &amp;

● "(雙引號)轉(zhuǎn)成 &quot;

● <(小于)轉(zhuǎn)成 &lt;

● >(大于)轉(zhuǎn)成 &gt;

具體語法如下:

        htmlspecialchars (str [, quote_style [, charset]])

參數(shù)str為需要轉(zhuǎn)換的字符串。quote_style的值為:ENT_COMPAT、ENT_NOQUOTES和ENT_QUOTES。參數(shù)charsets的值為:ISO-8859-1、ISO-8859-15、UTF-8、cp866、cp1251、cp1252、KOI8-R、BIG5、GB2312、BIG5-HKSCS、Shift_JIS或EUC-JP。

例如:

        <? php
        echo htmlspecialchars ("<a href=' test' >Test</a>", ENT_QUOTES);
        ?>

將會輸出:

        &lt; a href=&#039; test&#039; &gt; Test&lt; /a&gt;

2.htmlentities($string)

將所有能轉(zhuǎn)換成實體形式的字符都轉(zhuǎn)換成實體形式。例如:

        <? php
        $str = "A ' quote' is <b>bold</b>";
        echo htmlentities ($str);
        //輸出結(jié)果為:A ' quote' is &lt; b&gt; bold&lt; /b&gt;
        echo htmlentities ($str, ENT_QUOTES);
        //輸出結(jié)果為:A &#039; quote&#039; is &lt; b&gt; bold&lt; /b&gt;
        ?>

3.html_entity_decode($string);

PHP4.3.0以后加入的具有與htmlentities($string)相反功能的函數(shù)html_entity_decode。例如:

        <? php
        $orig = "I' ll \"walk\" the <b>dog</b> now";
        $a = htmlentities ($orig);
        $b = html_entity_decode ($a);
        echo $a; //輸出:I' ll &quot; walk&quot; the &lt; b&gt; dog&lt; /b&gt; now
        echo $b; //輸出:I' ll "walk" the <b>dog</b> now
        // 還原h(huán)tmlentities函數(shù)
        function unhtmlentities ($string)
        {
            //獲取htmlspecialchars ()和htmlentities ()內(nèi)部使用的轉(zhuǎn)換表格,類型為
    HTML_ENTITIES和HTMLSPECIALCHARS
            $trans_tbl = get_html_translation_table (HTML_ENTITIES);
            $trans_tbl = array_flip ($trans_tbl);     //交換數(shù)組中的鍵和值
            return strtr ($string, $trans_tbl);
        }
        $c = unhtmlentities ($a);
        echo $c; //輸出I' ll "walk" the <b>dog</b> now
        ?>

4. nl2br($string)

該函數(shù)的功能是將字符串中的所有換行符轉(zhuǎn)變成<br>換行符,例如:

        <? php
        echo nl2br ("foo isn' t\n bar");
        ?>

將會輸出:

        foo isn' t<br />
         bar

3.6.9 加密

PHP還提供了crypt ()函數(shù)完成加密功能:

        string crypt (string input_string [, string salt])

這一函數(shù)完成被稱作單向加密的功能,也就是說,它可以加密一些明碼,但不能夠?qū)⒚艽a轉(zhuǎn)換為原來的明碼。單向加密的口令一旦落入第三方人的手里,由于不能被還原為明文,因此也沒有什么大用處。在驗證用戶輸入的口令時,用戶輸入采用的也是單向算法,如果輸入與存儲的經(jīng)加密后的口令相匹配,則輸入的口令一定是正確的。

這個函數(shù)的input_string參數(shù)是需要加密的字符串,第二個參數(shù)salt是一個位字串,它能夠影響加密的暗碼,進一步地排除被稱作預(yù)計算攻擊的可能性。默認(rèn)情況下,PHP使用一個2個字符的DES干擾串,如果你的系統(tǒng)使用的是MD5,它會使用一個12個字符的干擾串。

crypt ()支持四種算法,下面是它支持的算法和相應(yīng)的salt參數(shù)的長度:

● CRYPT_STD_DES 2個字符(默認(rèn))

● CRYPT_EXT_DES 9個字符

● CRYPT_MD5 12個字符

● CRYPT_BLOWFISH 16個字符

例如:

        <? php
        $password = crypt ("My1sTpassword"); //加密密碼
        if (crypt ($user_input, $password) == $password) {
          echo "密碼正確!";
        }
        ?>

在默認(rèn)狀態(tài)下使用的crypt ()并不是最安全的,所以如果需要較高的安全性能,就需要其他更好的算法,比如md5(),這一函數(shù)使用MD5散列算法,它將一個字符串轉(zhuǎn)換成一個長32位的唯一的字符串。

        echo md5("apple"); // 將輸出 "1f3870be274f6c49b3e31a0c6728957f"

PHP5.0給md5加了第二個參數(shù),從而使它可以輸出16位的加密后的字符串。

3.6.10 字符串操作函數(shù)

常用的字符串操作函數(shù)如表3-11所示。

表3-11 字符串操作函數(shù)

續(xù)表

續(xù)表

續(xù)表

3.7 小結(jié)

為了回顧本章節(jié)的內(nèi)容,下面來看一個典型的數(shù)組運算例子,里面包含了本章節(jié)的大部分內(nèi)容,請讀者細(xì)心揣摩。

要求:用以下給出的數(shù)組對數(shù)組進行排序,升序降序都可以,但不能用系統(tǒng)附帶的函數(shù)來實現(xiàn)。

PHP : $array = array (' one' =>200, ' three' =>150, ' four' =>100, ' two' =>230);

● 解法一,用do…while解決

        <? php
        $array = array (' one' =>200, ' three' =>150, ' four' =>100,  ' two' =>230);
        $values = array_values ($array);
        do {
              $cur = min ($values);
              #$cur = max ($values);
              $key = array_search ($cur, $array);
              if ($key === false) {
                      break;
              }
              $result[$key] = $cur;
              unset ($array[$key]);
              unset ($values[array_search ($cur, $values)]);
        } while (count ($values)>0);
        print_r ($result);
        ?>

● 解法二

    <? php
    $array = array (' one' =>200, ' three' =>150, ' four' =>100, ' two' =>230);
    $ka=array_keys ($array);
    $count=count ($ka);
    for ($i=0; $i<$count-1; $i++){
          for ($j=0; $j<$count-$i-1; $j++){
                  if ($array[$ka[$j]]>$array[$ka[$j+1]]){
                        $temp=$ka[$j];
                        $ka[$j]=$ka[$j+1];
                        $ka[$j+1]=$temp;
                  }
          }
    }
    for ($i=0; $i<$count; $i++){
          $asort["$ka[$i]"]=$array[$ka[$i]];
    }
    print_r ($asort); ? >

● 解法三

    <?
    //標(biāo)準(zhǔn)的遞歸函數(shù)
    function BubbleSort ($str)
    {
    for ($i=0; $i<count ($str); $i++)
    {
        for ($j=count ($str)-2; $j>=$i; $j--)
        {
              if ($str[$j+1]<$str[$j])
              {
                  $tmp = $str[$j+1];
                  $str[$j+1]=$str[$j];
                  $str[$j]=$tmp;
              }
        }
    }
    return $str;
    }
    $array =array (' one' =>200, ' three' =>150, ' four' =>100,  ' two' =>230);
    //將全部鍵值生成一個數(shù)組
    $val_array=array_values ($array);
    //得到排序后的數(shù)組
    $new_array=BubbleSort ($val_array);
    //替換排序后數(shù)組的鍵名
    foreach ($new_array as $values){
        $key=array_search ($values, $array);
      $final_array[$key]=$values;
  }
  print_r ($final_array);
  ?>

三個解法答案一樣,輸出結(jié)果如圖3-5所示:

圖3-5 運行結(jié)果

主站蜘蛛池模板: 武邑县| 福州市| 临沂市| 綦江县| 绥江县| 长岭县| 团风县| 土默特左旗| 黔西县| 塘沽区| 滦南县| 都江堰市| 温州市| 汤阴县| 勐海县| 海原县| 和龙市| 湘阴县| 昌都县| 惠水县| 贵南县| 河东区| 江津市| 菏泽市| 方城县| 左云县| 招远市| 西城区| 武宁县| 绥滨县| 曲松县| 洞口县| 边坝县| 枣强县| 河曲县| 柘荣县| 阆中市| 舒城县| 邛崃市| 山阳县| 广河县|