字串

string 是一系列字元。在 PHP 中,字元和字節一樣,也就是說,一共有 256 種不同字元的可能性。這也暗示 PHP 對 Unicode 沒有本地支援。

註: 一個字串變得非常巨大也沒有問題,PHP 沒有給字串的大小強加實現範圍,所以完全沒有理由擔心長字串。

語法

字串可以用三種字面上的方法定義。

單引號

指定一個簡單字串的最簡單的方法是用單引號(字元 ')括起來。

要表示一個單引號,需要用反斜線(\)轉義,和很多其它語言一樣。如果在單引號之前或字串結尾需要出現一個反斜線,需要用兩個反斜線表示。注意如果你試圖轉義任何其它字元,反斜線本身也會被顯示出來!所以通常不需要轉義反斜線本身。

註: 在 PHP 3 中,此情況下將發出一個 E_NOTICE 級的警告。

註: 和其他兩種語法不同,單引號字串中出現的變數不會被變數的值替代。

echo 'this is a simple string';
echo 'You can also have embedded newlines in strings,
like this way.';
echo 'Arnold once said: "I\'ll be back"';
// output: ... "I'll be back"
echo 'Are you sure you want to delete C:\\*.*?';
// output: ... delete C:\*.*?
echo 'Are you sure you want to delete C:\*.*?';
// output: ... delete C:\*.*?
echo 'I am trying to include at this point: \n a newline';
// output: ... this point: \n a newline

雙引號

如果用雙引號(")括起字串,PHP 懂得更多特殊字元的轉義序列:

表格 7-1. 轉義字元

序列含義
\n換行(LF 或 ASCII 字元 0x0A(10))
\r回車(CR 或 ASCII 字元 0x0D(13))
\t水平制表符(HT 或 ASCII 字元 0x09(9))
\\反斜線
\$美元符號
\"雙引號
\[0-7]{1,3} 此正則表達式序列匹配一個用八進制符號表示的字元
\x[0-9A-Fa-f]{1,2} 此正則表達式序列匹配一個用十六進制符號表示的字元

此外,如果試圖轉義任何其它字元,反斜線本身也會被顯示出來!

雙引號字串最重要的一點是其中的變數名會被變數值替代。細節參見字串解析

定界符

另一種給字串定界的方法使用定界符語法(“<<<”)。應該在 <<< 之後提供一個標籤,然後是字串,然後是同樣的標籤結束字串。

結束標籤必須從行的第一列開始。同樣,標籤也必須遵循 PHP 中其它任何標簽的命名規則:只能包含字母數字下劃線,而且必須以下劃線或非數字字元開始。

警告

很重要的一點必須指出,結束標籤所在的行不能包含任何其它字元,可能除了一個分號(;)之外。這尤其意味著該標籤不能被縮進,而且在分號之前和之後都不能有任何空格或制表符。

定界符文本表現的就和雙引號字串一樣,只是沒有雙引號。這意味著在定界符文本中不需要轉義引號,不過仍然可以用以上列出來的轉義代碼。變數會被展開,但當在定界符文本中表達複雜變數時和字串一樣同樣也要注意。

例子 7-2. 定界符字串例子

<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* More complex example, with variables. */
class foo
{
    var $foo;
    var $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>

註: 定界符支援是 PHP 4 中加入的。

變數解析

當用雙引號或者定界符指定字串時,其中的變數會被解析。

有兩種語法,一種簡單的和一種複雜的。簡單語法最通用和方便,它提供了解析變數,陣列值,或者對象屬性的方法。

複雜語法是 PHP 4 引進的,可以用大括號括起一個表達式。

簡單語法

如果遇到美元符號($),解析器會盡可能多地取得後面的字元以組成一個合法的變數名。如果你想明示指定名字的結束,用大括號把變數名括起來。

$beer = 'Heineken';
echo "$beer's taste is great"; // works, "'" is an invalid character for varnames
echo "He drank some $beers"; // won't work, 's' is a valid character for varnames
echo "He drank some ${beer}s"; // works

同樣也可以解析陣列索引或者對象屬性。對於陣列索引,右方括號(])標志著索引的結束。對象屬性則和簡單變數適用同樣的規則,儘管對於對象屬性沒有像變數那樣的小技巧。

$fruits = array( 'strawberry' => 'red' , 'banana' => 'yellow' );

// note that this works differently outside string-quotes.
echo "A banana is $fruits[banana].";

echo "This square is $square->width meters broad.";

// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";

對於任何更複雜的情況,應該使用複雜語法。

複雜(大括號)語法

不是因為語法複雜而稱其為複雜,而是因為用此方法可以包含複雜的表達式。

事實上,用此語法你可以在字串中包含任何在名字空間的值。僅僅用和在字串之外同樣的方法寫一個表達式,然後用 { 和 } 把它包含進來。因為不能轉義“{”,此語法僅在 $ 緊跟在 { 後面時被識別(用“{\$”或者“\{$”來得到一個字面上的“{$”)。用一些例子可以更清晰:

$great = 'fantastic';
echo "This is { $great}"; // 不行,輸出為:This is { fantastic}
echo "This is {$great}";  // 可以,輸出為:This is fantastic
echo "This square is {$square->width}00 centimeters broad."; 
echo "This works: {$arr[4][3]}";     

// This is wrong for the same reason
// as $foo[bar] is wrong outside a string. 
echo "This is wrong: {$arr[foo][3]}"; 

echo "You should do it this way: {$arr['foo'][3]}";
echo "You can even write {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";

連接字串中的字元

字串中的字元可以通過在字串之後用大括號指定所要字元從零開始的偏移量來連接。

註: 為了向下相容,仍然可以用方括號。不過此語法在 PHP 4 中不贊成使用。

例子 7-3. 一些字串例子

<?php
/* Assigning a string. */
$str = "This is a string";

/* Appending to it. */
$str = $str . " with some more text";

/* Another way to append, includes an escaped newline. */
$str .= " and a newline at the end.\n";

/* This string will end up being '<p>Number: 9</p>' */
$num = 9;
$str = "<p>Number: $num</p>";

/* This one will be '<p>Number: $num</p>' */
$num = 9;
$str = '<p>Number: $num</p>';

/* Get the first character of a string  */
$str = 'This is a test.';
$first = $str{0};

/* Get the last character of a string. */
$str = 'This is still a test.';
$last = $str{strlen($str)-1};
?>

實用函式

字串可以用“.”(點)運算符連接。注意這裡不能用“+”(加)運算符。更多訊息參見字串運算符

有很多實用函式來改變字串。

普通函式見字串函式庫一節,高級搜索和替換見正則表達式函式(兩種口味:PerlPOSIX 擴展)。

還有 URL 字串函式,以及加密/解密字串的函式(mcryptmhash)。

最後,如果還是找不到你要的函式,參見字元型別函式庫

字串轉換

當一個字串被當作數字來求值時,根據以下規則來決定結果的型別和值。

如果包括“.”,“e”或▽l”其中任何一個字元的話,字串被當作 float 來求值。否則就被當作整數。

該值由字串最前面的部分決定。如果字串以合法的數字資料開始,就用該數字作為其值,否則其值為 0(零)。合法數字資料由可選的正負號開始,後面跟著一個或多個數字(可選地包括十進制分數),後面跟著可選的指數。指數是一個“e”或者▽l”後面跟著一個或多個數字。

$foo = 1 + "10.5";              // $foo is float (11.5)
$foo = 1 + "-1.3e3";            // $foo is float (-1299)
$foo = 1 + "bob-1.3e3";         // $foo is integer (1)
$foo = 1 + "bob3";              // $foo is integer (1)
$foo = 1 + "10 Small Pigs";     // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1;        // $foo is float (11)
$foo = "10.0 pigs " + 1.0;      // $foo is float (11)

此轉換的更多訊息見 Unix 手冊中關於 strtod(3) 的部分。

如果你想測試本節中的任何例子,可以拷貝和粘貼這些例子並且加上下面這一行自己看看會發生什麼:

echo "\$foo==$foo; type is " . gettype ($foo) . "<br />\n";