章 14. 表達式

表達式是 PHP 最重要的基石。在 PHP 中,幾乎所寫的任何東西都是一個表達式。簡單但卻最精確的定義一個表達式的模式就是「任何有值的東西」。

最基本的表達式形式是常量和變量。當鍵入「$a = 5」,即將值「5」配置給變量 $a。「5」,很明顯,其值為 5,換句話說「5」是一個值為 5 的表達式(在這裡,「5」是一個整型常量)。

賦值之後,所期待情況是 $a 的值為 5,因而若果寫下 $b = $a,期望的是它猶如 $b = 5 一樣。換句話說,$a 是一個值也為 5 的表達式。若果一切運行正確,那這正是將要發生的正確結果。

稍微複雜的表達式例子就是函數。例如,考慮下面的函數:

<?php
function foo ()
{
    return 
5;
}
?>

假定已經熟悉了函數的概念(若果不是的話,請看一下函數的關聯章節),那麼鍵入 $c = foo() 從本質上來說就如寫下 $c = 5,這沒錯。函數也是表達式,表達式的值即為它們的返回值。既然 foo() 返回 5,表達式「foo()」的值也是 5。通常函數不會僅僅返回一個靜態值,而可能會計算一些東西。

當然,PHP 中的值常常並非是整型的。PHP 支援四種標量值(標量值不能分割為更小的單元,例如和陣列不同)類型:整型值(integer),浮點數值(float),字串值(string)和布林值(boolean)。PHP 也支援兩種復合類型:陣列和對象。這兩種類型具可以賦值給變量或是從函數返回。

PHP 和其它語系一樣在表達式的道路上發展,但推進得更深遠。PHP 是一種面向表達式的語系,從這一方面來講幾乎一切都是表達式。考慮剛才已經研究過的例子,「$a = 5」。很顯然這裡涉及到兩個值,整型常量 5 的值以及而且變量 $a 的值,它也被更新為 5。但是事實是這裡還涉及到一個額外的值,即附值語句本身的值。賦值語句本身求值為被賦的值,即 5。實際上這意味著「$a = 5」,不必管它是做什麼的,是一個值為 5 的表達式。因而,這樣寫「$b = ($a = 5)」和這樣寫「$a =5; $b=5」(分號標誌著語句的結束)是一樣的。因為賦值動作的順序是由右到左的,也可以這麼寫「$b = $a =5」。

另外一個很好的面向表達式的例子就是前、後遞增和遞減。PHP 和多數其它語系的會員應該比較熟悉變量 ++ 和變量 -- 符號。即遞增和遞減運算符。在 PHP/FI 2 中,語句「$a++」沒有值(不是表達式),這樣的話你便不能為其賦值或是以任何其它模式來使用它。PHP 通過將其變為了表達式,類似 C 語系,增強了遞增/遞減的能力。在 PHP 和 C 語系 中,有兩種類型的遞增前遞增和後遞增,本質上來講,前遞增和後遞增均增加了變量的值,並且對於變量的影響是相同的。不同的是遞增表達式的值。前遞增,寫做「++$variable」,求增加後的值(PHP 在讀取變量的值之前,增加變量的值,因而稱之為「前遞增」)。後遞增,寫做「$variable++」,求變量未遞增之前的原始值(PHP 在讀取變量的值之後,增加變量的值,因而叫做「後遞增」)。

一個常用到表達式類型是比較表達式。這些表達式求值 FALSETRUE。PHP 支援 >(大於),>=(大於等於),==(等於),!=(不等於),<(小於),<= (小於等於)。PHP 還支援全等運算符 ===(值和類型均相同)和非全等運算符 !==(值或是類型不同)。這些表達式都是在條件判斷語句,比如,if 語句中最常用的。

這裡,將要研究的最後一個例子是組合的運算賦值表達式。已經知道若果想要為變量 $a 加1,可以簡單的寫「$a++」或是「++$a」。但是若果想為變量增加大於 1 的值,比如 3,該怎麼做?可以多次寫「$a++」,但這樣明顯不是一種高效舒適的方法,一個更加通用的做法是「$a = $a + 3」。「$a + 3」計算 $a 加上 3 的值,並且得到的值重新賦予變量 $a,於是 $a 的值增加了3。在 PHP 及其它幾種類似 C 的語系中,可以以一種更加簡短的形式完成上述功能,因而也更加清楚快捷。為 $a 的現用的值加 3,可以這樣寫:「$a += 3」。這裡的意思是「取變量 $a 的值,加 3,得到的結果再次配置給變量 $a」。除了更簡略和清楚外,也可以更快的運行。「$a += 3」的值,如同一個標準賦值動作的值,是賦值後的值。注意它不是 3,而是 $a 的值加上3 之後的值(此值將被賦給 $a)。任何二元運算符都可以用運算賦值模式,例如「$a -= 5」(從變量 $a 的值中減去 5),「$b *= 7」(變量 $b 乘以 7),等等。

還有一個表達式,若果沒有在別的語系中看到過的話,可能看上去很奇怪,即三元條件運算符:

$first ? $second : $third

若果第一個子表達式的值是 TRUE(非零),那麼計算第二個子表達式的值,其值即為整個表達式的值。否則,將是第三個子表達式的值。

下面的例子一般來說應該有助於理解前、後遞增和表達式:

<?php
function double($i)
{
    return 
$i*2;
}
$b $a 5;        /* assign the value five into the variable $a and $b */
$c $a++;          /* post-increment, assign original value of $a
                       (5) to $c */
$e $d = ++$b;     /* pre-increment, assign the incremented value of
                       $b (6) to $d and $e */

/* at this point, both $d and $e are equal to 6 */

$f double($d++);  /* assign twice the value of $d before
                       the increment, 2*6 = 12 to $f */
$g double(++$e);  /* assign twice the value of $e after
                       the increment, 2*7 = 14 to $g */
$h $g += 10;      /* first, $g is incremented by 10 and ends with the
                       value of 24. the value of the assignment (24) is
                       then assigned into $h, and $h ends with the value
                       of 24 as well. */
?>

一些表達式可以被當成語句。這時,一條語句的形式是 'expr' ';',即一個表達式加一個分號結尾。在「$b=$a=5;」中,$a=5 是一個有效的表達式,但它本身不是一條語句。「$b=$a=5;」是一條有效的語句。

最後一件值得提起的事情就是表達式的真值。在許多事件中,大體上主要是在條件執行和迴圈中,不要專注於表達式中明確的值,反而要注意表達式的值是否是 TRUE 或是 FALSE。常量 TRUEFALSE(大小寫無關)是兩種可能的 Boolean 值。若果有必要,一個表達式將自動轉換為 Boolean。參見類型強制轉換一節。

PHP 提供了一套完整強大的表達式,而為它提供完整的檔案資料已經超出了本手冊的範圍。上面的例子應該為你提供了一個好的關於什麼是表達式和怎樣構建一個有用的表達式的概念。在本手冊的其餘部分,我們將始終使用 expr 來表示一個有效的 PHP 表達式。