PHP教學 - 資料型態(Data Type) - 上


介紹PHP中的資料型態(型別),包含布林(Boolean)、整數(Integer)、浮點數(Float),型別的判斷與轉型。
1. 簡介
1.1 型別的種類
PHP 有8種基本的資料型態(Data Type)或簡稱型別(Type):
4種數值(scalar)的型別:
    布林(boolean)
    整數(integer)
    浮點數(float或double)
    字串(string)
2種複合(compound)的型別:
    陣列(array)
    物件(object)
另外兩種特別的型別:
    資源(resource)
    空值(NULL)
為了方便閱讀另外也有幾種虛擬的型別:
    混合(mixed)
    數字(number)
    回呼(callback)
1.2 型別的判斷
可 利用get_type()函式取得型別種類或利用is_xxx()函式判斷變數是否為此型別(is_xxx()的xxx替換為要判斷的型別,例 如:is_integer)。比較特別的是is_numeric()函式,當傳入的參數為整數、浮點數或是純數字內容的字串,都回傳TRUE。
<?php
$a_bool = TRUE;                       // boolean
$an_int = 12;                         // integer
$a_float = 1.23;                      // float
$a_string  = "foo";                   // string
$a_array = array();                   // array
$a_object = new stdClass;             // object
$a_resource = fopen("res.txt","w+");  // resource
$a_null = NULL;                       // NULL
 
echo gettype($a_bool);                // 印出:  boolean
echo gettype($an_int);                // 印出:  integer
echo gettype($a_float);               // 印出:  double
echo gettype($a_string);              // 印出:  string
echo gettype($a_array);               // 印出:  array
echo gettype($a_object);              // 印出:  object
echo gettype($a_resource);            // 印出:  resource
echo gettype($a_null);                // 印出:  NULL
 
if (is_bool($a_bool)) echo "會顯示";
if (is_integer($an_int)) echo "會顯示";
if (is_float($a_float)) echo "is_float可以";
if (is_double($a_float)) echo "is_double也可以";
if (is_string($a_bool)) echo "不會顯示";
if (is_array($a_array)) echo "會顯示";
if (is_object($a_object)) echo "會顯示";
if (is_resource($a_resource)) echo "會顯示";
if (is_null($a_null)) echo "會顯示";
 
$a_string  = "169.99cm";
$a_string2  = "178";
 
if (is_numeric($a_bool)) echo "不會顯示";
if (is_numeric($an_int)) echo "會顯示";
if (is_numeric($a_float)) echo "會顯示";
if (is_numeric($a_string)) echo "不會顯示";
if (is_numeric($a_string2)) echo "會顯示";
 
fclose($a_resource);
?>
另外可以利用var_dump()函式列出變數完整的內容與型別以便debug。
2. 布林(Boolean)
2.1 語法
布林的值只有兩種,TRUE或FALSE,不分大小寫。
<?php
$flag = FaLsE;
var_dump($flag == fAlSe); // bool(true)
?>
2.2 轉型
要轉型為布林可利用以下方式
    利用(bool)或(boolean)的強制轉型(Cast)。
    利用settype()傳入引數"bool"或"boolean"轉型。("bool"為PHP 4.2.0之後新增)
要注意的是,settype()必須傳入變數,而執行之後將會直接修改變數的內容。
<?php
$num = 10;
var_dump((bool) $num);     // bool(true)
var_dump($num);            // int(10), $num不會被修改
settype($num, "boolean");
var_dump($num);            // bool(true), $num被修改
?>
以下情況轉型為布林時,結果為FALSE:
    boolean型別值為FALSE之變數
    integer型別值為0之變數
    float型別值為0.0之變數
    string為空字串或值為"0"之變數
    空陣列array之變數
    NULL
    無成員之object型別之變數(PHP 4之前,PHP4之後object轉型永遠為TRUE)
<?php
var_dump((bool) 0);             // bool(false)
var_dump((bool) -1);            // bool(true), 注意這裡可能會搞錯
var_dump((bool) 0.0);           // bool(false)
var_dump((bool) 169.99);        // bool(true)
var_dump((bool) "");            // bool(false)
var_dump((bool) "0");           // bool(false)
var_dump((bool) "false");       // bool(true), 注意這裡可能會搞錯
var_dump((bool) array());       // bool(false)
var_dump((bool) array(false));  // bool(true)
var_dump((bool) new stdClass);  // bool(true), PHP 4之前: bool(false)
 
$fp = fopen("res.txt","w+");
var_dump((bool) $fp);           // bool(true)
fclose($fp);
 
var_dump((bool) NULL);          // bool(false)
?>
3. 整數(Integer)
3.1 語法
整數型別顧名思義就是只能存整數,以數學表示的話為Z = {..., -2, -1, 0, 1, 2, ...},整數有三種宣告方式:
    十進位制。
    十六進位制,以0x開頭。
    八進位制,以0開頭。
<?php
$num = 123;   // 十進位寫法
$num = +0x7B; // 十六進位寫法(等於十進位123),以0x開頭
$num = -0173; // 八進位寫法(等於十進位-123),以0開頭
?>
以正規表示法表示的話為
decimal     : [1-9][0-9]*
            | 0

hexadecimal : 0[xX][0-9a-fA-F]+

octal       : 0[0-7]+

integer     : [+-]?decimal
            | [+-]?hexadecimal
            | [+-]?octal
八進位中出現無效的數字8或9時,會忽略該數字之後的部份
<?php
$num = 01891234; // 結果為01
?>
3.2 數值範圍與溢位
整數的數值範圍會與使用平台有關,例如32位元的平台整數使用4 byte存放,可使用PHP常數PHP_INT_SIZE取得該平台的int佔用的大小,另外可用PHP_INT_MAX取得整數的最大值。
當變數的數值超過平台int容許範圍時也就是所謂的溢位(Overflow),將會自動轉為float型別,另外進行除法而除不盡時也會轉型為float
<?php
$num = PHP_INT_MAX;
var_dump($num);  // int(2147483647)
$num++;
var_dump($num);  // float(2147483648)
var_dump(28/7);  // int(4)
var_dump(25/7);  // float(3.5714285714286)
?>
3.3 轉型
要轉型為整數可利用以下方式
    利用(int)或(integer)的強制轉型。
    利用intval()函式轉型。
    利用settype()傳入引數"int"或"integer"轉型。("int"為PHP 4.2.0之後新增)
<?php
var_dump((int) false);         // int(0)
var_dump((int) true);          // int(1)
var_dump((int) 169.99);        // int(169)
var_dump((int) "9527");        // int(9527)
var_dump((int) "");            // int(0)
var_dump((int) "one");         // int(0)
var_dump((int) "30cm");        // int(30)
var_dump((int) array());       // int(0)
var_dump((int) array(55, 66)); // int(1)
var_dump((int) new stdClass);  // int(1)
 
$fp = fopen("res.txt","w+");
var_dump((int) $fp);           // int(3), 3為resource的編號
fclose($fp);
 
var_dump((int) NULL);          // int(0)
?>
字串轉型為整數(或之後的浮點數)時,類似八進位數字,會忽略出現無效的字元之後的部份。
轉型為整數時,若有小數點則無條件捨去,但是注意,若該數字超出整數範圍時,會出現不如預期的結果,如果你是想做『取整數』的動作的話,可以使用floor()函式來處理。另外,若要四捨五入的話可使用round()函式
<!--p
$num = 201012312359.99;
var_dump((int) $num);  // int(-851150553)
var_dump(floor($num)); // float(201012312359)
var_dump(round($num)); // float(201012312360)
-->
4. 浮點數(Float)
4.1 語法
浮點數英文Floating point number簡稱float或double,有兩種寫法:
    一般數字。
    科學記號表示法,使用e表示10的幾次方,e不分大小寫。
<?php
var_dump(169.99);  // float(169.99)
var_dump(9.527e3); // float(9527)
var_dump(1E-3);    // float(0.001)
?>
以正規表示法表示的話為
LNUM          [0-9]+
DNUM          ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM})
4.2 轉型
要轉型為浮點數可利用以下方式
    利用(float)或(double)的強制轉型。
    利用floatval()或doubleval()函式轉型。(floatval()為PHP 4.2.0之後新增)
    利用settype()傳入引數"float"或"double"轉型。("float"為PHP 4.2.0之後新增)
<?php
var_dump((float) false);         // float(0)
var_dump((float) true);          // float(1)
var_dump((float) 178);           // float(178)
var_dump((float) "");            // float(0)
var_dump((float) "169.99cm");    // float(169.99)
var_dump((float) array());       // float(0)
var_dump((float) array(55, 66)); // float(1)
var_dump((float) new stdClass);  // float(1)
 
$fp = fopen("res.txt","w+");
var_dump((float) $fp);           // float(3), 3為resource的編號
fclose($fp);
 
var_dump((float) NULL);          // float(0)
?>
4.3 常見問題
4.3-1 取小數點位數
如果我們想要只顯示到小數點第二位,可以用幾種方式處理:
    使用round()函式,前面也曾使用過,只要再進一步指定第二個參數,就可以拿來取小數點位數。
    使用number_format()函式,第二個參數表示到小數點第幾位。
    使用sprintf()函數,%f表示輸出浮點數,%.2f表示小數點第二位。
<?php
$num = 98.765;
// 參數二的對照範例
// ...  0  9 8 . 7 6 5 ...
// ... -2 -1 0   1 2 3 ...
var_dump(round($num, 2));         // float(98.77) 取小數點第二位
var_dump(round($num, -2));        // float(100)   取到百位
var_dump(number_format($num, 2)); // string(5) "98.77"
var_dump(sprintf("%.2f", $num));  // string(5) "98.77"
// 亦可用來保留0的顯示
$num = 10.00;
echo $num;                        // 10
$num = sprintf("%.2f", $num);
echo $num;                        // 10.00 保留00
?>
4.3-2 近似值
 在電腦世界中的浮點數其實只是近似值,浮點數中的整數可能只是精確度到達一定程度而已,所以可能會在某些情況下造成判斷錯誤,下面有些例子與一個變通的方法:
<?php
$num = 169.99999999999;
var_dump($num);                     // float(169.99999999999)
$num = 169.999999999999;
var_dump($num);                     // float(170)
$num = 8.0;
$num2 = (0.1+0.7) * 10;
var_dump((int) $num2);              // int(7) !!
var_dump($num == $num2);            // bool(false) !!
var_dump(floatEqual($num, $num2));  // bool(true)
 
// 誤差值小於 $precision 視為相等
function floatEqual($num, $num2, $precision=0.0001)
{
    return (abs($num - $num2) < $precision);
}
?>
4.3-3 取餘數
當變數為超過整數型別容許範圍的浮點數時,進行取餘數(modulo)動作可能會得到錯誤的結果,以下為範例與一個解決方案:
<?php
$num = 6887129853;
var_dump($num % 10);  // % 10 取表示除以10之後的除數, 結果錯誤: int(-9)
var_dump(floatMod($num, 10)); // float(3)
 
// 餘數 = 被除數 - 商數 * 除數
function floatMod($num, $divisor)
{
    return $num - floor($num / $divisor) * $divisor;
}
?>

留言

這個網誌中的熱門文章

c語言-關於#define用法

CMD常用網管指令

PHP 與 JavaScript 之間傳值利用 json