介紹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 語法

布林的值只有兩種,TRUEFALSE,不分大小寫。

<?php
$flag = FaLsE;
var_dump($flag == fAlSe); // bool(true)
?>

2.2 轉型

要轉型為布林可利用以下方式

  1. 利用(bool)(boolean)的強制轉型(Cast)。
  2. 利用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:

  1. boolean型別值為FALSE之變數
  2. integer型別值為0之變數
  3. float型別值為0.0之變數
  4. string為空字串或值為"0"之變數
  5. 空陣列array之變數
  6. NULL
  7. 無成員之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, ...},整數有三種宣告方式:

  1. 十進位制。
  2. 十六進位制,以0x開頭。
  3. 八進位制,以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 轉型

要轉型為整數可利用以下方式

  1. 利用(int)(integer)的強制轉型。
  2. 利用intval()函式轉型。
  3. 利用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()函式


4. 浮點數(Float)

4.1 語法

浮點數英文Floating point number簡稱float或double,有兩種寫法:

  1. 一般數字。
  2. 科學記號表示法,使用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 轉型

要轉型為浮點數可利用以下方式

  1. 利用(float)(double)的強制轉型。
  2. 利用floatval()doubleval()函式轉型。(floatval()為PHP 4.2.0之後新增)
  3. 利用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 取小數點位數

如果我們想要只顯示到小數點第二位,可以用幾種方式處理:

  1. 使用round()函式,前面也曾使用過,只要再進一步指定第二個參數,就可以拿來取小數點位數。
  2. 使用number_format()函式,第二個參數表示到小數點第幾位。
  3. 使用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;
}
?>

延伸閱讀

上一篇 PHP教學 - 基本語法(Syntax)

下一篇 PHP教學 - 資料型態(Data Type) - 下

文章標籤
創作者介紹

小殘的程式光廊

emn178 發表在 痞客邦 PIXNET 留言(0) 人氣()