PHP 數據類型
PHP 支持八種原始類型(type)。
四種標量類型:
1.string(字符串)
2.integer(整型)
3.float(浮點型,也作 double )
4.boolean(布爾型)
兩種復合類型:
1.array(數組)
2.object(對象)
兩種特殊類型:
1.resource(資源)
2.NULL(空)
查看變量類型
通過 gettype() 函數可以方便的查看某個變量的類型:
<?php
$bool = TRUE; // 布爾型
$str = "foo"; // 字符串
$int = 12; // 整型
echo gettype($bool); // 輸出 boolean
echo gettype($str); // 輸出 string
echo gettype($int); // 輸出 integer
?>
判斷變量類型
如果想通過判斷變量類型來可以使用 is_type 函數:
<?php
$var_int = 12;
// 如果 $var_int 是 int 類型,這進行加法
if (is_int($var_int)) {
$var_int = $var_int+4;
}
echo $var_int; // 輸出 16
?>
以上基本就是PHP數據類型的基本內容,大家如果想了解具體每個數據類型的用法,可以查閱PHP手冊,裡面有詳細的說明。
數據類型轉換
PHP數據類型有三種轉換方式:
•在要轉換的變量之前加上用括號括起來的目標類型
•使用3個具體類型的轉換函數,intval()、floatval()、strval()
•使用通用類型轉換函數settype(mixed var,string type)
第一種轉換方式: (int) (bool) (float) (string) (array) (object)
•<?php
•$num1=3.14;
•$num2=(int)$num1;
•var_dump($num1); //輸出float(3.14)
•var_dump($num2); //輸出int(3)
•?>
第二種轉換方式: intval() floatval() strval()
•<?php
•$str="123.9abc";
•$int=intval($str); //轉換後數值:123
•$float=floatval($str); //轉換後數值:123.9
•$str=strval($float); //轉換後字符串:"123.9"
•?>
第三種轉換方式: settype();
•<?php
•$num4=12.8;
•$flg=settype($num4,"int");
•var_dump($flg); //輸出bool(true)
•var_dump($num4); //輸出int(12)
•?>
PHP數據類型隱性轉換的陷阱
我這裡說的是php5+上跑的,php4的請飄過。
先把錯誤報告打開,以防看不到錯誤信息
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
?>
根據php manual 中 http://www.php.net/manual/zh/language.operators.comparison.php
“Comparison Operators” 一章的說明可知,number 和string進行比較的時候,會先將string類
型首先轉化為number,然後再進行比較操作。
1.類型自動轉換為數組
當我們把一個非數組的變量當做數組來調用的時候,該變量在調用時數據類型臨時自動轉換成數組。
例如如下代碼:
<?php
$str = 'string';
var_dump($str['aaa']); // string(1) "s"
var_dump($str); // string(6) "string"
if($str['aaa'] === $str[0]) {
print "===";
}
?>
如下例子可以明顯的看出下標類型自動轉換在發生。
<?php
$link = '<a href="http://yulans.cn">yulans</a>';
$key = '1-10';
echo "$link[$key]n"; // 同 $link[1]
echo "{$link[$key]}n"; // 同 $link[1]
//echo "$link['$key']n"; // 報錯
echo "{$link['$key']}n"; // 同 $link[0]
?>
這裡字符串在 var_dump($str['aaa']) 被臨時轉換成了數組 array('s','t','r','i', 'n','g'),而用關聯數組方式
$str['aaa']讀取索引數組的值,關聯數組的下標'aaa'將被轉換成整形下標,
因而在這裡的$str['aaa']全等於$str[0]。
其他數據類型隱性轉換成數組也隱藏有陷阱,一般都不是報出undefined index錯誤。舉例如下代碼:
<?php
/**
* 測試變量隱性轉換成數組
*
* @param mixed $param
*/
function test2Arr($param) {
var_dump($param['abc']);
}
test2Arr(false); // NULL
test2Arr(123); // NULL
test2Arr(123.456); // NULL
test2Arr('string'); // string(1) "s"
test2Arr(array('abc'=>'text')); // string(4) text
test2Arr(new ArrayObject()); // Notice: undefined index: abc
?>
解決辦法:
函數參數數據類型是數組的時候,防止用戶輸入字符串導致錯誤
如下例子,當添加用戶的時候,我們要求用戶必須輸入用戶名。沒有哪個SB把要求是數組的參數傳入
字符串,但是防人之心不可無,說不定我連續工作超過十幾個小時後一不小心就成那個SB了,又或許
某人想繞過代碼執行操作。
<?php
/**
* 添加用戶(錯誤的寫法)
*
* @param array $user
*/
function addUser($user) {
if(empty($user['name'])) { // 這裡當輸入類型是不為空的字符串的時候會出錯,
echo "用戶名必填n";
return false;
}
// do sth.
echo "測試n";
return true;
}
/**
* 添加用戶(正確的寫法)
*
* @param array $user
*/
function addUser2($user) {
if(!is_array($user) || empty($user['name'])) {
echo "用戶名必填n";
return false;
}
// do sth.
echo "測試n";
return true;
}
$user = 'xiaoxiao';
addUser($user);
addUser2($user);
?>
2.純數字字符串比較時自動轉換成整形超過范圍時發生溢出
<?php
$x1 = '111111111111111111';
$x2 = '111111111111111112';
echo ($x1 === $x2) ? "true" : "false"; // false 如我們所願,這兩個字符串確實不一樣。
echo ($x1 == $x2) ? "true" : "false"; // true 這裡被偷偷的轉換類型了,
// 成了 echo (intval($x1) == intval($x2)) ? "true" : "false"; 整形溢出
?>
3、整形和字符串比較時數據類型隱性轉換有可能發生問題
<?php
$number = 0;
$string = 'text';
if($number == $string) {
print "true";
} else {
print "false";
}
?>
很遺憾這裡輸出的是 true
我們知道 $number === $string 肯定是false,手冊上說 === 是比較值&&數據類型,而用 == 只是比較值,
$number == $string 這裡不是比較值嗎? '0' 和 'text' 明顯不一樣啊。小心了,這裡的$string是
先被秘密轉成和$number一樣的整形再比較的,$number == (int)$string的確是true
4. in_array 小陷阱
<?php
var_dump(in_array(0, array('s'))); // true
?>
因為in_array會將0 和's' 進行比較,0是number類型,'s'是string類型, 's'轉化為number的結果為0,
而0 == 0 的結果是true,所以in_array(0, array('s', 'ss'))的結果也是true
如果把in_array 的第三個參數strict設置為 true,比較的時候 就會判斷值和類型是否都相當。
如果都相當的話,才會返回true,否則返回false.