类型

标量类型

boolean(布尔型)

TEUE | FALSE 不区分大小写

<?php
    $foo = True; // 设置 $foo 为 TRUE
?>

if("0"){
    echo 'true';
}else{
    echo 'false';  // 输出 false
}


if("0.0"){
    echo 'true';    // 输出 true
}else{
    echo 'false';
}

要将一个值转换成 boolean,用 (bool) 或者 (boolean) 来强制转换。
但是很多情况下不需要用强制转换,因为当运算符,函数或者流程控制结构需要一个 boolean 参数时,PHP 具有类型自动转换。

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

  • 布尔值 FALSE 本身
  • 整型值 0(零)
  • 浮点型值 0.0(零)
  • 空字符串,以及字符串 "0"
  • 不包括任何元素的数组
  • 特殊类型 NULL(包括尚未赋值的变量)
  • 从空标记生成的 SimpleXML 对象

所有其它值都被认为是 TRUE(包括任何资源 和 NAN)。

Warning
-1 和其它非零值(不论正负)一样,被认为是 TRUE!

integer(整型)

PHP 支持 十进制、二进制、八进制、十六进制;

$a = 1234; // 十进制数
$a = -123; // 负数
$a = 0123; // 八进制数 (等于十进制 83)
$a = 0x1A; // 十六进制数 (等于十进制 26)
$a = 0b11111111; // 二进制数字 (等于十进制 255)

整型数的长度和平台有关;
Windows 下 ,PHP 7 以前的版本,都是 32 位版本的PHP。
PHP 不支持无符号的 integer。

Integer 值的占用字节长度可以用常量 PHP_INT_SIZE 来查看;

最大值可以用常量 PHP_INT_MAX 来表示,最小值用常量 PHP_INT_MIN 表示。

32位的范围: -2147483648 ~ 2147483647

64位的范围: -9223372036854775808 ~ 9223372036854775807

超过 Integer 范围的 数,溢出了范围,会被自动转换为 浮点数;待会讲浮点数的时候会具体说明原因
(同样,计算的结果如果溢出了范围,也会被自动转换为浮点数)

在PHP中,进行除法运算会返回浮点数或者整数,如果可以整除则返回整数,如果不能整除则返回小数;

如果想要像其他语言一样,在计算除法的时候,舍弃掉小数部分,可以进行强制转换(int) 强制转换为整数,强制转换为整数的时候会向下取整(砍掉小数)

GMP扩展
如果 内建 Integer 的范围不够使用(特别是32位情况下),可以使用任意长度整数gmp库,需要在php的配置文件中开启;

(GMP库是任意长度整数库,不支持浮点数运算)

函数库使用方法: https://www.php.net/manual/zh...

echo gmp_strval(gmp_add("99999999999999999999999999999999999999999999999","1"));
float(浮点型,也称作 double)
$a = 1.234; 
$b = 1.2e3; 
$c = 7E-10;

和其他语言一样,PHP支持科学记数法,PHP中所有的浮点数对应其他语言的 double ,占用 8字节(64位)。

符号位 阶码 尾数 长度 精度
float 1 8 23 32 有效数字支持6~7位
double 1 11 52 64 有效数字支持14~15位

Tip: 一个浮点数的有效数字是指从左边第一位不是0的数开始计数;
如: 0.00123,有效数字是 123,则有三位有效数字;

PHP 中 浮点数 可以精确表达 有效数字 为 14~ 15的小数,超过14~15位,则无法精确表达,使用科学计数法,粗略表述;

由于浮点数是非精确描述数字,所以范围非常的庞大,整数溢出了范围,则会被自动转换为 浮点数,浮点数粗略表示,所以如果庞大的数字,还是要使用 GMP 库,任意长度整数


浮点数在日常使用过程中,经常会出现一些怪异的情况,这种情况在其他语言都有可能出现,如
0.7+0.1 的结果不是 0.8,而是 0.799999999;
(0.7+0.1) * 10 的结果不是 8,而是 7;
为什么会产生这样的问题? 如何解决? 如果想要了解详细的原理,可以看我另外的文章(浮点数)

这里我们直接说结论,永远不要相信浮点数的计算结果; 可以使用下面两种方式:

  1. 统一使用整数存储;如: 可以讲余额存成整数,单位为“分”,11.31元存成 1131分;
  2. 使用 BCMath 库 (任意精度数学库) 值得信赖的精度计算~

BCMath 使用案例

echo bcadd("0.1232132132132132132121" , "0.12321321321321321323213213213",20); 

// 输出 0.24642642642642642644 

// 参数: 字符串A,字符串B,保留小数位数
// 返回: 字符串计算结果

判断浮点数相等
一般不要简单判断浮点数是否相等,因为这是一个坑!浮点数本身是不精确的,0.7 实际是 0.70000000000001; 可以使用下面这种方法判断相等;

// $a 和 $b 在小数点后五位精度内都是相等的。 则判定相等
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
    echo "true";
}

对于这种下面这种超大极限数情况,上面的比较算法就会出现错误,知道这是为什么吗? ~

$a = 12345678998989899899.129;
$b = 12345678998989899888.123;
$epsilon = 0.00001;

echo  $a  ;
echo  '<br/>';
echo  $b  ;

if(abs($a-$b) < $epsilon) {
    echo "true";  // 还是会输出 true ,其实上面两个数已经是天壤之别
}

小数的比较还是推荐使用: bccomp() 函数来解决

总结:

  1. 小数的计算结果永远不要信任(除非使用高精度函数库)
  2. 有效位数超过13位的,就不精确了,如果想要精确要使用 高精度函数库
  3. 推荐使用高精度函数库来处理小数的计算, 高精度小数的表示与输出;
内建数学函数库 Math

PHP 也提供了 数学函数库 Math ,这些函数是内建的;可以直接使用;

请参照: PHP Math 函数库官方文档

string(字符串)

PHP中有4中方式(2组) 表示字符串;

  1. 单引号
  2. nowdoc
  3. 双引号
  4. hredoc

单引号和 nowdoc 为一组,他们不支持 变量解析 也不支持 转义字符,类似于 raw 字符串;

单引号和 nowdoc 也是有区别的; 单引号常备用作表示一行字符串, nowdoc 被用作表示一段字符串;

单引号表示字符串的时候,可以有部分转义支持(输出单引号和反斜杠);而 nowdoc则没有任何转义支持;

单引号和nowdoc 可以被用作初始化类属性

单引号字符串


// 单引号
echo 'this is a simple string';

// 可以录入多行
echo 'You can also have embedded newlines in 
strings this way as it is
okay to do';

// 输出: Arnold once said: "I'll be back" ; 支持 \' 转义输出 单引号
echo 'Arnold once said: "I\'ll be back"';
// 输出: You deleted C:\*.*? ;
// 支持 \\ 转义输出 1个反斜杠
echo 'You deleted C:\\*.*?';

// 输出: You deleted C:\*.*?
echo 'You deleted C:\*.*?';

// 输出: This will not expand: \n a newline
echo 'This will not expand: \n a newline';

// 输出: Variables do not $expand $either
echo 'Variables do not $expand $either';

nowdoc

以下内容会被原封不动的输出~ 不会有任何的转义

语法上要注意, EOT 要带 单引号,(不带带引号就变成了 heredoc); EOT 是可以自定义的,就是个标记而已; EOT的开头和结尾要一致; EOT 的结尾必须顶行写;

echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
'' 
\\
\'
EOT;

双引号和 heredoc 为一组; 他们支持变量解析和转义字符(\n,\r,\0,\u,\t ..等);

(存在变量解析的 双引号字符串 或 heredoc ,不可以被用作类属性初始化; 没有变量解析的可被用做类属性初始化)

heredoc

$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* 含有变量的更复杂示例 */
class foo
{
    var $foo;
    var $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

// heredoc 中含表达式
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;


// 在参数中使用 heredoc
var_dump(array(<<<EOD
foobar!
EOD
));

双引号和变量解析

简单示例:

$juices = array("apple", "orange", "koolaid1" => "purple");

echo "He drank some $juices[0] juice.".PHP_EOL;
echo "He drank some $juices[1] juice.".PHP_EOL;

// 不工作,因为 和 s 粘在一起了,无法解析
echo "He drank some juice made of $juice[0]s.".PHP_EOL;  

// 正常工作,不需要''来表示字符串key
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;

class people {
    public $john = "John Smith";
    public $jane = "Jane Smith";
    public $robert = "Robert Paulsen";
    
    public $smith = "Smith";
}

$people = new people();

echo "$people->john drank some $juices[0] juice.".PHP_EOL;
echo "$people->john then said hello to $people->jane.".PHP_EOL;
echo "$people->john's wife greeted $people->robert.".PHP_EOL;

// 不会工作,找不到 smiths 的属性
echo "$people->robert greeted the two $people->smiths."; 

复杂示例


$great = 'fantastic';

// 无效,输出: This is { fantastic}
echo "This is { $great}";

// 有效,输出: This is fantastic
echo "This is {$great}";
echo "This is ${great}";

// 有效
echo "This square is {$square->width}00 centimeters broad."; 

// 有效,只有通过花括号语法才能正确解析带引号的键名
echo "This works: {$arr['key']}";

// 有效
echo "This works: {$arr[4][3]}";

// 这是错误的表达式,因为就象 $foo[bar] 的格式在字符串以外也是错的一样。
// 换句话说,只有在 PHP 能找到常量 foo 的前提下才会正常工作;这里会产生一个
// E_NOTICE (undefined constant) 级别的错误。
echo "This is wrong: {$arr[foo][3]}"; 

// 有效,当在字符串中使用多重数组时,一定要用括号将它括起来
echo "This works: {$arr['foo'][3]}";

// 有效
echo "This works: " . $arr['foo'][3];

echo "This works too: {$obj->values[3]->name}";

echo "This is the value of the var named $name: {${$name}}";

echo "This is the value of the var named by the return value of getName(): {${getName()}}";

echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";

// 无效,输出: This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";

也可以在字符串中用此语法通过变量来调用类的属性。

class foo {
    var $bar = 'I am bar.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo "{$foo->$bar}\n";
echo "{$foo->{$baz[1]}}\n";

只有和字符串在同一个命名空间下的 变量,才会被解析;

PHP 字符串的本质

PHP中的字符串是字节数组,字节从哪里来?

PHP解析器会根据 PHP脚本文件的编码,对代码进行解码和解析;

$str = "a你好b"; ,即假设文件编码为 UTF-8,则 str 在内存中的编码则是 UTF-8,UTF-8是可变长度编码,所以 a 占 1个字节,“你好”占6个字节(1个汉子3字节),b占1个字节,总共8个字节;

这和其他语言有很大的不同, 在Java中,Java虚拟机的字符串是由字符组成,而不是字节;字符编码是UTF-16 ;

Class文件在用 java 命令运行的时候,可以指定编码,告诉Java虚拟机,以什么编码解析 Class 中的字符串;如: UTF-8 解析,则用UTF-8编码解析,解码成 unicode 序列,再将unicode序列,编码成UTF-16 序列,形成字符串;

所以,在PHP中, a你好b 的长度是8;在Java中它的长度是4;


然而,PHP 的绝大部分内部字符串处理函数其实都是针对单字节的,比如常见的 strlen(),substr(),strpos(),strcmp()......如果应用这些函数对多字节字符处理,可能会得到预想不到的结果; 如下代码:

$str = "a你好b";
echo $str[0]; // 输出 a
echo $str[1] ; // 输出乱码~ 因为 下标为1的字节,不是一个字符编码,而是 你 字的UTF-8码 的 1/3;

mbstring 扩展

函数文档地址: https://www.php.net/manual/zh...

前文说到,自带的字符串处理函数都是以字节为单位来处理的,在英文国家可能非常好用,但是在中国,一个汉子3个字节的时候,就不好用了;

可以使用 mbstring 扩展,来进行日常的字符串操作:

 $str = "a你好b";
echo mb_substr($str,1,1);  // 输出 你

mbstring 如果没有开启需要在 配置文件中开启; 常见的配置项如下,主要就是配置默认的字符编码;

[mbstring] 
mbstring.language = Chinese
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = On
mbstring.http_input = UTF-8
mbstring.http_output = UTF-8
mbstring.detect_order = UTF-8
mbstring.substitute_character = none

每一个 mbxxx函数的最后一个都是 encoding ,可以指定 解析 字符串(字节数组) 所使用得编码,如果不填则使用配置编码;

编码可以在上述的配置文件中配置,如果没有配置,则默认是使用PHP配置中的

; PHP's default character set is set to UTF-8.
; http://php.net/default-charset
default_charset = "UTF-8"

输出的区别 print、printf、var_dump等

echo 和 print: 都是输出,但是 echo 比 print 快建议用 echo;

print_r函数打印关于变量的易于理解的信息
如果变量是string , integer or float , 将会直接输出其值,如果变量是一个数组,则会输出一个格式化后的数组,便于阅读;
也就是有key和value对应的那种格式。对于object对象类同。

print_r(array('a','b',array('aa','bb','cc'))) ;

输出: Array ( [0] => a [1] => b [2] => Array ( [0] => aa [1] => bb [2] => cc ) );

printf函数 和 stringf

  • %% – 返回百分比符号
  • %b – 二进制数
  • %c – 依照 ASCII 值的字符
  • %d – 带符号十进制数
  • %e – 可续计数法(比如 1.5e+3)
  • %u – 无符号十进制数
  • %f – 浮点数(local settings aware)
  • %F – 浮点数(not local settings aware)
  • %o – 八进制数
  • %s – 字符串
  • %x – 十六进制数(小写字母)
  • %X – 十六进制数(大写字母)

C语言形式的格式化输出

var_dump 和 var_export

echo var_export(array('a','b',array('aa','bb','cc'))) ;
echo '</br>';
var_dump(array('a','b',array('aa','bb','cc'))) ;

输出

array ( 0 => 'a', 1 => 'b', 2 => array ( 0 => 'aa', 1 => 'bb', 2 => 'cc', ), )
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> array(3) { [0]=> string(2) "aa" [1]=> string(2) "bb" [2]=> string(2) "cc" } }

var_dump 是输出调试信息;

var_export 输出 代码形式的信息,这种代码可以直接拷贝使用,就是原生代码

复合类型

array(数组)

注意!!!! PHP中的数组是值拷贝,默认情况下是数组整体拷贝,和其他语言有很大不同

PHP 中的数组是 k,v 类型; 如果没有指定 key 则从 0 开始排列;

$arr = array('a','b','c');
var_export($arr); // array ( 0 => 'a', 1 => 'b', 2 => 'c', )

也可以使用短语法来定义 array

// 自 PHP 5.4 起
$arr = [
        'a',
        'b',
        'c'
    ];

var_export($arr); // array ( 0 => 'a', 1 => 'b', 2 => 'c', )

也可以直接使用数组,如果数组不存在则自动定义;

$arr['name'] = 'zhangsan';
var_dump($arr);  // 自动创建一个 数组,并且 填入 name = zhangsan

$arr2['stu']['name'] = 'zhangsan';
$arr2['stu']['age'] = '17';
var_dump($arr2); // 自动创建一个二维数组; 并且填入相关信息

可以使用 [] 符号,给数组新增 k,v; 相当于 push;

 $arr[] = 'zhangsan';
var_dump($arr);  //  给数组新增一个k,v;

$arr2[]['name'] = 'zhangsan';
$arr2[]['age'] = '17';
var_dump($arr2);  // 二维数组

key 可以是 integer 或 string ; 如果 key 已存在,则会覆盖;

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

  • 包含有合法整型值的字符串会被转换为整型。例如键名 "8" 实际会被储存为 8。但是 "08" 则不会强制转换,因为其不是一个合法的十进制数值。
  • 浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
  • 布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
  • Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
  • 如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。
$array = array(
    1    => "a",
    "1"  => "b",  // 会被转换成 1=> 'b'
    1.5  => "c",  //  会被转换成 1=> 'c' 
    true => "d", //  会被转换成 1=> 'd'
);
var_dump($array); // 输出 1 => 'd';

PHP 数组的key,可以支持 自增 key 和 自定义 key 混合使用;

自增key 规则: 若数组中已存在 数字key ,在最大的 数字key 且要>=0 的基础上 +1 ,如果没有则从0开始;

  $arr=[
       -9=>'-9', // 数字key, 但它小于0
       -2, // 0=>-2,按照规则找数组中最大的 数字key  (>=0) ,并没有,所以从0 开始;
       'zhangsan',  // 没有key,所以在最大key的基础上+1,则是 : 1 => zhangsan
       3=> '0',
       2=>'-1',
       'ermazi' // 4=>ermazi
    ];

   var_export($arr);
   // 输出 array ( -9 => '-9', 0 => -2, 1 => 'zhangsan', 3 => '0', 2 => '-1', 4 => 'ermazi', ) 
   
   $arr[] = 'lisi';  // 相当于 push  , 5=>lish
   var_export($arr); 

数组实用函数

count() 可以来获得数组的数量;

list($a,$b,$c) 可以将数组拆分成变量;

$info = array('coffee', 'brown', 'caffeine');

// 列出所有变量
list($drink, $color, $power) = $info;
echo "$drink is $color and $power makes it special.\n";

// 列出他们的其中一个
list($drink, , $power) = $info;
echo "$drink has $power.\n";

// 或者让我们跳到仅第三个
list( , , $power) = $info;
echo "I need $power!\n";

// list() 不能对字符串起作用
list($bar) = "abcde";
var_dump($bar); // NULL

判断key是否存在

echo array_key_exists(3,$arr);

echo  isset($arr[3]); //  使用这种速度更快

其他的请见: 数组函数


数组与 循环

// 方式1,KV
foreach ($arr as $item => $value){
   echo  $item . ' - ' .$value;
   echo  '<br/>';
}

echo  '<br/>';

// 方式2,只有V
foreach ($arr as $value){
    echo $value;
    echo  '<br/>';
}

// 循环中改变数组值 (常规方式)
foreach ($arr as $item => $value){
    echo $arr[$item] = 'newvalue';
    echo  '<br/>';
}

// 循环中改变数组值 (引用方式)
foreach ($arr as &$value){  // & 相当于循环把每一个数组元素的 引用给 $value ;
    echo $value = 'newvalue2'; // 通过引用改变值
    echo  '<br/>';
}
var_export($arr);

删除数组元素

unset($arr[0]);  // 清理数组某个元素
unset($arr); // 清理整个数组

多维数组

$fruits = array ( "fruits"  => array ( "a" => "orange",
                                       "b" => "banana",
                                       "c" => "apple"
                                     ),
                  "numbers" => array ( 1,
                                       2,
                                       3,
                                       4,
                                       5,
                                       6
                                     ),
                  "holes"   => array (      "first",
                                       5 => "second",
                                            "third"
                                     )
                );

// Some examples to address values in the array above 
echo $fruits["holes"][5];    // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]);  // remove "first"

// Create a new multi-dimensional array
$juices["apple"]["green"] = "good"; 

数组的比较

可以用 array_diff()和数组运算符来比较数组。

$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");

$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);

$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);

$a += $b; // Union of $a += $b is $a and $b
echo "Union of \$a += \$b: \n";
var_dump($a);

输出

Union of $a and $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}
Union of $b and $a:
array(3) {
  ["a"]=>
  string(4) "pear"
  ["b"]=>
  string(10) "strawberry"
  ["c"]=>
  string(6) "cherry"
}
Union of $a += $b:
array(3) {
  'a' =>
  string(5) "apple"
  'b' =>
  string(6) "banana"
  'c' =>
  string(6) "cherry"
}

注意!!!! PHP中的数组是值拷贝,默认情况下是数组整体拷贝,和其他语言有很大不同

object(对象)

PHP 支持面向对象,也就是说可以自定义 class;

callable(可调用)

特殊类型

resource(资源)

资源 resource 是一种特殊变量,保存了到外部资源的一个引用(ID)。资源是通过专门的函数来建立和使用的。如打开文件、打开数据库等函数,反回的就是资源类型; 从其他类型转换为资源没有实际意义;

get_resource_type()
此函数返回一个字符串,用于表示传递给它的 resource 的类型。如果参数不是合法的 resource,将产生错误。

$c = mysql_connect();
echo get_resource_type($c)."\n";
// 打印:mysql link

$fp = fopen("foo","w");
echo get_resource_type($fp)."\n";
// 打印:file

$doc = new_xmldoc("1.0");
echo get_resource_type($doc->doc)."\n";
// 打印:domxml document

释放资源
引用计数系统是 Zend 引擎的一部分,可以自动检测到一个资源不再被引用了(和 Java 一样)。这种情况下此资源使用的所有外部资源都会被垃圾回收系统释放。因此,很少需要手工释放内存。 如果外部资源有 close 等回收函数,还是需要手动回收一下确保回收资源;

Note: 持久数据库连接比较特殊,它们不会被垃圾回收系统销毁。需要手动 close; 参见数据库永久连接一章。

NULL(无类型)

特殊的 NULL 值表示一个变量没有值。NULL 类型唯一可能的值就是 NULL。

在下列情况下一个变量被认为是 NULL:

  • 被赋值为 NULL。
  • 尚未被赋值。
  • 被 unset()。

文档类型

文档类型并不是实际的PHP语言类型无法在代码中使用, 文档类型指的是为了我们方便读懂 PHP的文档所在文档中使用得一些类型;

mixed
mixed 说明一个参数可以接受多种不同的(但不一定是所有的)类型。

例如 gettype() 可以接受所有的 PHP 类型,str_replace() 可以接受字符串和数组。

number
number 说明一个参数可以是 integer 或者 float。

callback
本文档中在 PHP 5.4 引入 callable 类型之前使用 了 callback 伪类型。二者含义完全相同。

array|object
array|object 意思是参数既可以是 array 也可以是 object。

void
void 作为返回类型意味着函数的返回值是无用的。void 作为参数列表意味着函数不接受任何参数。

...
在函数原型中,$... 表示等等的意思。当一个函数可以接受任意个参数时使用此变量名。

image.png

类型转换

转BOOL

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

  • 布尔值 FALSE 本身
  • 整型值 0(零)
  • 浮点型值 0.0(零)
  • 空字符串,以及字符串 "0"
  • 不包括任何元素的数组
  • 特殊类型 NULL(包括尚未赋值的变量)
  • 从空标记生成的 SimpleXML 对象
  • 所有其它值都被认为是 TRUE(包括任何资源 和 NAN)。

Warning
-1 和其它非零值(不论正负)一样,被认为是 TRUE!
'\0'不是FALSE;

转换为数字(整数和浮点数)

BOOL值,TRUE: 1, FALSE 为0;

从字符串转换为数值:

$foo = 1 + "10.5";                // $foo is float (11.5)
$foo = 1 + "-1.3e3";              // $foo is float (-1299)
$foo = 1 + "bob-1.3e3";           // $foo is integer (1)
$foo = 1 + "bob3";                // $foo is integer (1)
$foo = 1 + "10 Small Pigs";       // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1;          // $foo is float (11)
$foo = "10.0 pigs " + 1.0;        // $foo is float (11)  
转换为数组

对于任意 integer,float,string,boolean 和 resource 类型,如果将一个值转换为数组,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。换句话说,(array)$scalarValue 与 array($scalarValue) 完全一样。

如果一个 object 类型转换为 array,则结果为一个 K,V数组,键名将为成员变量名;
不过有几点例外:私有变量前会加上类名作前缀;保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 空 字符。这会导致一些不可预知的行为:

<?php

class A {
    private $A = '1';  // This will become "\0A\0A"
}

class B extends A {
    private $A = '2'; // This will become "\0B\0A"
    public $AA = '3'; // This will become "AA"
    protected $CC = '4'; // This will become "\0*\0CC";
}
$arr = (array) new B() ;
var_dump($arr);

echo  $arr["AA"];  // 输出3
echo  $arr["\0B\0A"];  // 输出  2
echo  $arr["\0A\0A"];  // 输出 1 
echo  $arr["\0*\0CC"];  // 输出 4
?>

将 NULL 转换为 array 会得到一个空的数组。

\0
\0 在C语言中表示表示一个字符串的结尾符号;但是在PHP里面就是一个空字符,通过 trim 可以去掉 开头和结尾的空字符; 空字符没有实际意义,输出的时候也无法通过观察字符串内容看到空字符,但它确实是存在的; 在使用得时候要注意一下; (\0 不是NULL,它的 strlen 是1);

转换为对象

如果将一个对象转换成对象,它将不会有任何变化。

如果其它任何类型的值被转换成对象,将会创建一个内置类 stdClass 的实例。
如果该值为 NULL,则新的实例为空。

array 转换成 object 将使键名成为属性名并具有相对应的值。

<?php
$obj = (object) array('1' => 'foo');
var_dump(isset($obj->{'1'})); // PHP 7.2.0 后输出 'bool(true)',之前版本会输出 'bool(false)' 
var_dump(key($obj)); // PHP 7.2.0 后输出 'string(1) "1"',之前版本输出  'int(1)' 
?>

对于其他值,会包含进成员变量名 scalar。

<?php
$obj = (object) 'ciao';
echo $obj->scalar;  // outputs 'ciao'
?>
使用 settype 类型转换
$foo = "5bar"; // string
$bar = true;   // boolean

settype($foo, "integer"); // $foo 现在是 5   (integer)
settype($bar, "string");  // $bar 现在是 "1" (string)

引用


吴士岭
4 声望1 粉丝