« 9. 如何初始化陣列(array)? | (回到Blog入口) | 11. 在 PHP 裡如何生成物件? »

10. 什麼是 Type Juggling( 型態間的戰爭)?

jollen 發表於 October 27, 2006 1:17 PM

因為 PHP 並沒有精確的精型機制,而是當我們指定什麼樣型別的值給變數,該變數就是什麼樣的型別,例如:

<?php $a = 5; //$a 為 integer $a = "5"; //$a 為 string ?>

變數在做運算時,例如使用 "+",當 expression 包含各種不同的型態時,就會有 Type Juggling 的動作發生,例如:

<?php $foo = "0"; // $foo 為 string "0" (ASCII 48) $foo++; // $foo 為 string "1" (ASCII 49) $foo += 1; // $foo 變成 integer (2) $foo = $foo + 1.1; // $foo 變成 double (3.1) $foo = 5 + "15 Persons"; // $foo 的運算結果為 integer (20) $foo = 5 + "10 Big Pigs"; // $foo 的運算結果為 integer (15) ?>

又如:

$a = 5; // $a 的型別為 integer $a[0] = "Hi!"; // $a 的型別變成 array

這種型別的改變即稱為 "Type Juggling"。

但是,在 PHP 3 裡,這種 type juggling 的機制還有一個值得討論的問題,就是當 type juggling 發生在字串轉換成陣列時,會發生底下這個問題:

$a = "Go"; // $a 為 string $a[0] = "N"; // $a 是否被轉型別 array ?

聰明的您應該可以馬上看出,$a[0] 並不一定被轉型成 array,因為 $a[0] 也可能代表 $a 字串的第一個字元,也就是:

$a[0] = "G"; $a[1] = "o";

當 $a[0] = "N" 發生時,可能變成:

$a = "No"; // $a 仍為 string

或是:

$a[0] = "N"; // $a 轉型成 array

這是因為,PHP 3 支援字串的字元索引的方法和陣列元素的索引方式一樣,這是在 PHP 3 的版本裡才需要特別提出的一個問題。PHP 3 的使用者如果要將 string 型別轉換成 array,可利用 type casting 的方式來解這樣的問題:

<?php $a = "Go"; $a = (array)$a; echo $a[0]; // 輸出 'Go' $a[0] = "N"; echo $a[0]; // 輸出 'N' ?>

type juggling 還有一個常被忽略的重點就是,++ 與 -- 運算子所做的運算是 ASCII 與算術運算,而 + 運算子只做算術運算,看個例子就可以了解是什麼意思了:

<html> <head> <title>test</title> </head>
<body> <pre><blockquote><em><?php $foo = "01"; echo "<p>\$foo => $foo</p>"; $foo++; echo "<p>\$foo++ => $foo</p>";
$foo = $foo+1; echo "<p>\$foo = \$foo+1 => $foo</p>"; </em></blockquote></pre>?> </body> </html>

注意 $foo = $foo+1 的計算結果為 3,而不是 "03",這就是筆者所要特別強調的地方,+ 運算子只做算術運算,這點在其它語言如 Perl 也有類似情況。

--jollen

版權聲明

請參閱頁面底部的 CC 授權條款。此外,Jollen's PHP 專欄禁止引用、修改與轉貼,如果您想與朋友分享的話,我們只允許網站連結(hyperlink)的形式。

發表一個評論

(如果你此前從未在此 Blog 上發表過評論,則你的評論必須在 Blog 主人驗證後才能顯示,請你耐心等候。)

| Top | Jollen's Forum |
Jollen's PHP 專欄採用 Attribution-NonCommercial-NoDerivs 2.5 授權條款
Copyright(c) 2001-2007,2010 www.jollen.org