0%

PHP基础数据类型总结

String 字符串

单引号&双引号

单引号 和 双引号 的区别,单引号字符串中变量和特殊字符的转义序列将不会被替换,而双引号是会被替换。

Heredoc&Nowdoc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Heredoc 结构
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
EOT;
// 输出以下:
// My name is "MyName". I am printing some Foo.
// Now, I am printing some Bar2.


// Nowdoc 结构
echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
EOT;
// 输出以下:
// My name is "$name". I am printing some $foo->foo.
// Now, I am printing some {$foo->bar[1]}.

总结:

  1. heredoc 结构类似于双引号字符串,Nowdoc 结构是类似于单引号字符串的。
  2. 结束标识符不能缩进,分号的前后也不能有任何空白或制表符。

Integer 整型

语法

1
2
3
4
5
6
7
8
$a = "0123"     // 十进制数 123 (区别八进制)
$a = 0123; // 八进制数 (等于十进制 83)

var_dump((int) 010); //Output 8
var_dump((int) "010"); //output 10

var_dump(intval("010")); //output 10
var_dump(intval("010", 8)); //output 8

(int) 和 intval() 两者都是强制转换为整数,默认基数10。不同的是,(int)遇到零开头基数为8,”0x”开头基数为16,”0b”开头基数为2,而intval()允许将不同的基数指定为第二个参数,而直接转换操作则不允许。

总结:

  1. 在数字文字前加零表示“这是八进制”。 但不要混淆:字符串中的前面的零是不认的
  2. (int)是根据前几个字符来确定基数,intval()是根据第二个参数来确认基数

整数溢出

1
2
3
4
5
6
7
<?php
//64 位系统
$large_number = 9223372036854775807;
var_dump($large_number); // int(9223372036854775807)

$large_number = 9223372036854775808;
var_dump($large_number); // float(9.2233720368548E+18)

总结:一个数超出了 integer 的范围,将会被解释为 float。(32位系统范围: ±2147483647, 64位系统范围: ±9223372036854775807)


Float 浮点型

精度

看看下面有意思的情况:

1
2
3
4
<?php
$f = 0.58;
var_dump(intval($f * 100)); //为啥输出57
?>

浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采用偏移码表示。
尾数:表示数据小数点后的有效数字。

这里的关键点就在于, 小数在二进制的表示。详细看 laruence

1
0.58二进制 -> 0010100011110101110000101000111101011100001010001111 -> 0.57999999999999996

总结:绝不要将未知的分数强制转换为 integer,可以选择使用高精度的 bc 函数


Boolean 布尔类型

当转换为 boolean 时,以下值被认为是 false:

  1. 布尔值 false 本身
  2. 整型值 0-0
  3. 浮点型值 0.0 -0.0
  4. 空字符串,以及字符串 “0”
  5. 不包括任何元素的数组
  6. 特殊类型 NULL(包括尚未赋值的变量)
  7. 从空标记生成的 SimpleXML 对象

总结:只要遇到 0 和 null 是都是 false,其他都是 true,包括 -1 和其它非零值(不论正负)一样,被认为是 true!


Array 数组

类型强制与覆盖示例

此外 key 会有如下的强制转换:

  1. 包含有合法整型值的字符串会被转换为整型。例如键名 “8” 实际会被储存为 8。但是 “08” 则不会强制转换,因为其不是一个合法的十进制数值。
  2. 浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
  3. 布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
  4. Null 会被转换为空字符串,即键名 null 实际会被储存为 “”。
  5. 数组和对象不能被用为键名。坚持这么做会导致警告:Illegal offset type。
  6. 如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。
1
2
3
4
5
6
7
8
$array = [
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
];
// 等于 $array = [1 => "d"];
// 验证了以上1,2,3点

仅对部分单元指定键名

1
2
3
4
5
6
7
8
9
<?php
$array = [
"a",
"b",
6 => "c",
"d",
];

//等于 $array = [0 => "a", 1 => "b", 6 => "c", 7 => "d"];

可以看到最后一个值 “d” 被自动赋予了键名 7。这是由于之前最大的整数键名是 6。

用方括号的语法新建/修改

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
// 创建一个简单的数组
$array = array(1, 2, 3, 4, 5);

// 现在删除其中的所有元素,但保持数组本身不变:
foreach ($array as $i => $value) {
unset($array[$i]);
}

// 添加一个单元(注意新的键名是 5,而不是你可能以为的 0)
$array[] = 6;

//等于 $array = [5 => 6];

Iterable 可迭代对象(待更新)


Object 对象(待更新)


Resource 资源类型(待更新)


NULL(待更新)


Callback / Callable 类型(待更新)


类型声明(待更新)


类型转换的判别(待更新)