PHP 是個非常有彈性的語言,這件事情充分體現在 echo 敘述上面。
但也因為這個「彈性」,實際上卻會造成維護和理解上的困難。
PHP 的 string concatenation operator 是 “.”
不使用 + 的主要原因是 PHP 乃弱型別語言,採用 + 的時候,很容易發生問題:
1 2 3 4 5 6 7 8 9 10 11 12 |
$a = "1"; $b = "2"; $c = $a . $b; $d = $a + $b; echo $c; // 12 echo $d; // 3, 會自動轉型成 int 然後相加 |
廢話結束,接下來介紹印出變數的方法,:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$a = 'Hello'; $b = ' '; $c = 'Kitty'; echo "$a$b$c"; /* 解析變數,把三個變數 concat 起來,然後印出變數內容 */ // Hello Kitty echo '$a$b$c'; /* 不解析變數,也不會有 concat 的動作,直接印出 '' 內的內容 */ // $a$b$c echo $a . $b . $c; /* 同範例一,但沒有解析變數的動作,直接把變數 concat 起來,然後印出 */ // Hello Kitty echo $a , $b , $c; /* 既然有 . 了,那為什麼用 , 放在變數之間也能動? */ // Hello Kitty |
對!為什麼這邊使用 , (逗號) 也行呢?
其實這又是一個 PHP 的奇怪設計!
在 PHP 的世界裡面, echo 並不是一個 function ,而是語法的一部分 (language construct),但他又允許把字串當成參數傳入,詳見下方定義:
void echo ( string $arg1 [, string $... ] )
ref: PHP: echo
所以在使用 , (逗號) 的時候,效率會比使用 . 來得高一點點。因為少了 concat 的動作, echo 直接分別把每一個變數印出。但是這個「優點」卻容易造成語法的混淆,所以我不是很喜歡。
另外,如果要印出 class member, array 或是 map 也是一件令人頭痛的事情,太多方法可以達成,卻又充滿了詭異:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php class test { public $k = 'hello kitty'; } $c = new test(); $c = new test; /* 這樣也行.. WTF? */ echo $c->k; // hello kitty echo $c->{'k'}; /* 用 { } 多此一舉,要帶變數直接寫成 $c->$v 即可, 除非是想要 $c->{'K' . $var}...但為什麼要搞成這樣 */ // hello kitty echo "{$c->k}"; /* 唯一好處是避免 k 後面緊鄰可以當變數的字元" */ // hello kitty $hellowtf = 'wtfhello'; echo ${'hello' . 'wtf'}; /* 意思是印出 $hellowtf 的內容,既不直覺又難看 */ // wtfhello $a = array('hello'=> 'kitty', 'test' => array('dear' => 'daniel')); echo "$a['hello']"; /* 好吧,我接受 */ // syntax error echo "${a['hello']}"; // kitty echo $a['hello']; // kitty echo "{$a['hello']}"; // kitty echo $a['test']['dear']; // daniel echo "{$a['test']['dear']}"; /* 印到兩層的時候...是沒有問題的 */ // daniel echo "${a['test']['dear']}"; /* 可是這樣印到兩層的時候...就炸裂了 */ // syntax error |
看完了這些亂七八糟的東西…
我只能說這在視覺上真的是件非常痛苦的事情.. orz