数据类型转化

简介

PHP 支持 8 种原始数据类型。

四种标量类型:

boolean(布尔型)/ integer(整型) / float(浮点型,也称作 double) / string(字符串)

两种复合类型:

array(数组) / object(对象)

最后是两种特殊类型:

resource(资源) / NULL(无类型)

Boolean 布尔类型

  • 指定一个布尔值,使用关键字 TRUE 或 FALSE。两个都不区分大小写。
  • 将一个值转换成 boolean,用 (bool) 或者 (boolean) 来强制转换。
  • 运算符,函数或者流程控制结构需要一个 boolean 参数时,该值会被自动转换

类型转换:

当转换为 boolean 时,以下值被认为是 FALSE(所有其它值都被认为是 TRUE,包括0和负数)

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

Integer 整型

  • 一个 integer 是集合 ℤ = {..., -2, -1, 0, 1, 2, ...} 中的一个数。
  • 整型值可以使用十进制,十六进制,八进制或二进制表示,前面可以加上可选的符号(- 或者 +)。
  • 二进制表达的 integer 自 PHP 5.4.0 起可用。
  • 要使用八进制表达,数字前必须加上 0(零)。要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b。
  • PHP 不支持无符号整数。
  • Integer 值的字长可以用常量 PHP_INT_SIZE来表示,自 PHP 4.4.0 和 PHP 5.0.5后,最大值可以用常量 PHP_INT_MAX 来表示。
  • 整数溢出,将会被解释为 float。同样如果执行的运算结果超出了 integer 范围,也会返回 float。
  • PHP 中没有整除的运算符。值可以舍弃小数部分强制转换为 integer,或者使用 round() 函数可以更好地进行四舍五入。

转换为整型

  • 要明确地将一个值转换为 integer,用 (int) 或 (integer) 强制转换。
  • 大多数情况下都不需要强制转换,当运算符,函数或流程控制需要一个 integer 参数时,值会自动转换。
  • 通过函数 intval() 来将一个值转换成整型。
  • (布尔值转换)FALSE 将产生出 0(零),TRUE 将产生出 1(壹)。
  • (浮点型转换) 当从浮点数转换成整数时,将向下取整。
  • 如果浮点数超出了整数范围,则结果为未定义,因为没有足够的精度给出一个确切的整数结果。
  • 决不要将未知的分数强制转换为 integer,这样有时会导致不可预料的结果。

Float 浮点型

浮点型(也叫浮点数 float,双精度数 double 或实数 real)

比较浮点数

要测试浮点数是否相等,要使用一个仅比该数值大一丁点的最小误差值。该值也被称为机器极小值(epsilon)或最小单元取整数,是计算中所能接受的最小的差别值。

$a 和 $b 在小数点后五位精度内都是相等的。


NaN

  • 某代表着一个在浮点数运算中未定义或不可表述的值。
  • 任何拿此值与其它任何值进行的松散或严格比较的结果都是 FALSE。
  • 由于 NAN 代表着任何不同值,不应拿 NAN 去和其它值进行比较,包括其自身,应该用 is_nan() 来检查。

String 字符串

  • 一个字符串 string 就是由一系列的字符组成,其中每个字符等同于一个字节。这意味着 PHP 只能支持 256 的字符集,因此不支持 Unicode 。
  • string 最大可以达到 2GB。
  • 一个字符串可以用 4 种方式表达

单引号

  • 要表达一个单引号自身,需在它的前面加个反斜线(\)来转义。
  • 要表达一个反斜线自身,则用两个反斜线(\)。
  • 单引号字符串中的变量和特殊字符的转义序列将不会被替换。

双引号

用双引号定义的字符串最重要的特征是变量会被解析

Heredoc 结构

  • heredoc 句法结构:<<<。在该运算符之后要提供一个标识符,然后换行。接下来是字符串 string 本身,最后要用前面定义的标识符作为结束标志。结束时所引用的标识符必须在该行的第一列,而且,标识符的命名也要像其它标签一样遵守 PHP 的规则:只能包含字母、数字和下划线,并且必须以字母和下划线作为开头。
  • 结束标识符这行除了可能有一个分号(;)外,绝对不能包含其它字符。不能缩进,分号的前后也不能有任何空白或制表符。
  • 结束标识符的前面必须是个被本地操作系统认可的换行,比如在 UNIX 和 Mac OS X 系统中是 \n,而结束定界符(可能其后有个分号)之后也必须紧跟一个换行。
  • 如果在文件结束前也没有找到一个正确的结束标识符,PHP 将会在最后一行产生一个解析错误。
  • Heredocs 结构不能用来初始化类的属性。自 PHP 5.3 起,此限制仅对 heredoc 包含变量时有效。

Heredoc 结构就象是没有使用双引号的双引号字符串(heredoc 结构中)单引号不用被转义,转移字符。变量将被替换)。

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

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

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

Heredoc 结构用在函数参数中来传递数据


在 PHP 5.3.0 以后,也可以用 Heredoc 结构来初始化静态变量和类的属性和常量


自 PHP 5.3.0 起还可以在 Heredoc 结构中用双引号来声明标识符:


Nowdoc 结构

  • Nowdoc 结构是类似于单引号字符串的,不进行解析操作。适合用于嵌入 PHP 代码或其它大段文本而无需对其中的特殊字符进行转义。
  • Nowdoc 结构是在 PHP 5.3.0 中加入的

标记 <<<, 但是跟在后面的标识符要用单引号括起来,即 <<<'EOT'。Heredoc 结构的所有规则也同样适用于 nowdoc 结构,尤其是结束标识符的规则。

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

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

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;
?>

nowdoc 结构可以用在任意的静态数据环境中


变量解析

  • 当字符串用双引号或 heredoc 结构定义时,其中的变量将会被解析。
  • 两种语法规则:一种简单规则,一种复杂规则。简单的语法规则是最常用和最方便的,它可以用最少的代码在一个 string 中嵌入一个变量,一个 array 的值,或一个 object 的属性。

简单语法

当 PHP 解析器遇到一个美元符号($)时,它会和其它很多解析器一样,去组合尽量多的标识以形成一个合法的变量名。可以用花括号来明确变量名的界线。


一个 array 索引或一个 object 属性也可被解析。数组索引要用方括号(])来表示索引结束的边际,对象属性则是和上述的变量规则相同。

  "purple");

echo "He drank some $juices[0] juice.".PHP_EOL;
echo "He drank some $juices[1] juice.".PHP_EOL;
echo "He drank some juice made of $juice[0]s.".PHP_EOL; // Won't work
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;
echo "$people->robert greeted the two $people->smiths."; // Won't work
?>

复杂(花括号)语法

任何具有 string 表达的标量变量,数组单元或对象属性都可使用此语法。

用花括号 { 和 } 把表达式括起来即可。由于 { 无法被转义,只有 $ 紧挨着 { 时才会被识别。可以用 {$ 来表达 {$。

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()}";
?>

存取和修改字符串中的字符

  • string 中的字符可以通过下标,用类似 array 结构中的方括号包含对应的数字来访问和修改,可以把 string 当成字符组成的 array。
  • 也可用花括号访问,比如 $str{42}

用超出字符串长度的下标写入将会拉长该字符串并以空格填充。非整数类型下标会被转换成整数。非法下标类型会产生一个 E_NOTICE 级别错误。用负数下标写入字符串时会产生一个 E_NOTICE 级别错误,用负数下标读取字符串时返回空字符串。写入时只用到了赋值字符串的第一个字符。用空字符串赋值则赋给的值是 NULL 字符。

PHP 的字符串在内部是字节组成的数组。因此用花括号访问或修改字符串对多字节字符集很不安全。


PHP 5.4 起字符串下标必须为整数或可转换为整数的字符串,否则会发出警告。

用 [] 或 {} 访问任何其它类型(不包括数组或具有相应接口的对象实现)的变量只会无声地返回 NULL。

有用的函数和运算符

字符串可以用 '.'(点)运算符连接起来

转换成字符串

  • 值前面加上 (string) 或用 strval() 函数来转变成字符串
  • 在需要字符串的表达式中,会自动转换为 string(在使用函数 echo 或 print 时和在一个变量或者一个变量和一个 string 进行比较时)
  • 也可使用函数 settype()
  • 一个布尔值 boolean 的 TRUE 被转换成 string 的 "1"。
  • Boolean 的 FALSE 被转换成 ""(空字符串)。
  • 一个整数 integer 或浮点数 float 被转换为数字的字面样式的 string(包括 float 中的指数部分)。使用指数计数法的浮点数(4.1E+6)也可转换。
  • 数组 array 总是转换成字符串 "Array",因此,echo 和 print 无法显示出该数组的内容。
  • PHP 4 中对象 object 总是被转换成字符串 "Object"。为了得到对象的类的名称,可以用 get_class() 函数。自 PHP 5 起,适当时可以用 __toString 方法。
  • 资源 resource 总会被转变成 "Resource id #1" 这种结构的字符串,其中的 1 是 PHP 在运行时分配给该 resource 的唯一值。要得到一个 resource 的类型,可以用函数 get_resource_type()。
  • NULL 总是被转变成空字符串。
  • 大部分的 PHP 值可以转变成 string 来永久保存,这被称作串行化,可以用函数 serialize() 来实现。如果 PHP 引擎设定支持 WDDX,PHP 值也可被串行化为格式良好的 XML 文本。

字符串转换为数值

  • 如果该字符串没有包含 '.','e' 或 'E' 并且其数字值在整型的范围之内(由 PHP_INT_MAX 所定义),该字符串将被当成 integer 来取值。
  • 该字符串的开始部分决定了它的值。如果该字符串以合法的数值开始,则使用该数值。否则其值为 0(零)。
  • 合法数值由可选的正负号,后面跟着一个或多个数字(可能有小数点),再跟着可选的指数部分。指数部分由 'e' 或 'E' 后面跟着一个或多个数字构成。

  • 通过将一个字符转换成整数以得到其代码。使用函数 ord() 和 chr() 实现 ASCII 码和字符间的转换。

字符串类型详解

  • string 是一个由字节组成的数组再加上一个整数指明缓冲区长度。
  • 字符串类型的此特性解释了为什么 PHP 中没有单独的“byte”类型 - 已经用字符串来代替了。返回非文本值的函数 - 例如从网络套接字读取的任意数据 - 仍会返回字符串。

字符串会被按照该脚本文件相同的编码方式来编码。不过这并不适用于激活了 Zend Multibyte 时(如果激活了 Zend Multibyte 则是其内部编码)- 这意味着此编码应该是 ASCII 的兼容超集,

  • 某些函数假定字符串是以单字节编码的。例如 substr(),strpos(),strlen() 和 strcmp()。理解这些函数的另一种方法是它们作用于内存缓冲区,即按照字节和字节下标操作。
  • 某些函数被传递入了字符串的编码方式,也可能会假定默认无此信息。例如 htmlentities() 和 mbstring 扩展中的大部分函数。
  • 其它函数使用了当前区域(见 setlocale()),但是逐字节操作。例如 strcasecmp(),strtoupper() 和 ucfirst()。这意味着这些函数只能用于单字节编码,而且编码要与区域匹配。例如 strtoupper("á") 在区域设定正确并且 á 是单字节编码时会返回 "Á"。如果是用 UTF-8 编码则不会返回正确结果,其结果根据当前区域有可能返回损坏的值。
  • 一些函数会假定字符串是使用某特定编码的,通常是 UTF-8。intl 扩展和 PCRE(上例中仅在使用了 u 修饰符时)扩展中的大部分函数都是这样。尽管这是由于其特殊用途,utf8_decode() 会假定 UTF-8 编码而 utf8_encode() 会假定 ISO-8859-1 编码。

Array 数组

PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集合,栈,队列以及更多可能性。由于数组元素的值也可以是另一个数组,树形结构和多维数组也是允许的。

  • 可以用 array() 语言结构来新建一个数组。它接受任意数量用逗号分隔的 键(key) => 值(value)对。
array(  key =>  value
     , ...
     )
// 键(key)可是是一个整数 integer 或字符串 string
// 值(value)可以是任意类型的值
  • 自 5.4 起可以使用短数组定义语法,用 [] 替代 array()。
 "bar",
    "bar" => "foo",
);

// 自 PHP 5.4 起
$array = [
    "foo" => "bar",
    "bar" => "foo",
];
?>

key 可以是 integer 或者 string。value 可以是任意类型。

  • 包含有合法整型值的字符串会被转换为整型。例如键名 "8" 实际会被储存为 8。但是 "08" 则不会强制转换,因为其不是一个合法的十进制数值。
  • 浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
  • 布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
  • Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
  • 数组和对象不能被用为键名。坚持这么做会导致警告:Illegal offset type。

如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。

 "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
?>

key 为可选项。如果未指定,PHP 将自动使用之前用过的最大 integer 键名加上 1 作为新的键名。

可以只对某些单元指定键名而对其它的空置。

用方括号语法访问数组单元

数组单元可以通过 array[key] 语法来访问。
方括号和花括号可以互换使用来访问数组单元。

自 PHP 5.4 起可以用数组间接引用函数或方法调用的结果。之前只能通过一个临时变量。
自 PHP 5.5 起可以用数组间接引用一个数组原型。
试图访问一个未定义的数组键名与访问任何未定义变量一样:会导致 E_NOTICE 级别错误信息,其结果为 NULL。


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

如果 $arr 还不存在,将会新建一个,这也是另一种新建数组的方法。 [] 实际上代表着字符串访问运算符。

$arr[key] = value;
$arr[] = value;
// key 可以是 integer 或 string
// value 可以是任意类型的值

要修改某个值,通过其键名给该单元赋一个新值。要删除某键值对,对其调用 unset() 函数。
如果给出方括号但没有指定键名,则取当前最大整数索引值,新的键名将是该值加上 1(但是最小为 0)。如果当前还没有整数索引,则键名将为 0。


 1, 12 => 2);

$arr[] = 56;    // This is the same as $arr[13] = 56;
                // at this point of the script

$arr["x"] = 42; // This adds a new element to
                // the array with key "x"
                
unset($arr[5]); // This removes the element from the array

unset($arr);    // This deletes the whole array
?>

最大整数键名不一定当前就在数组中。它只要在上次数组重新生成索引后曾经存在过就行了。

 $value) {
    unset($array[$i]);
}
print_r($array);

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

// 重新索引:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>

实用函数

unset() 函数允许删除数组中的某个键。但不会重建索引。如果需要删除后重建索引,可以用 array_values() 函数。
foreach 控制结构是专门用于数组的。它提供了一个简单的方法来遍历数组。

 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* will produce an array that would have been defined as
   $a = array(1 => 'one', 3 => 'three');
   and NOT
   $a = array(1 => 'one', 2 =>'three');
*/

$b = array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>

数组做什么和不做什么

应该始终在用字符串表示的数组索引上加上引号。
不要再键名为常量或变量的加上引号,否则会使 PHP 不能解析它们。


这样是错的,但可以正常运行。那么为什么错了呢?

原因是:

此代码中有一个未定义的常量(bar)而不是字符串('bar'-注意引号),而 PHP 可能会在以后定义此常量,不幸的是你的代码中有同样的名字。它能运行,是因为 PHP 自动将裸字符串(没有引号的字符串且不对应于任何已知符号)转换成一个其值为该裸字符串的正常字符串。例如,如果没有常量定义为 bar,PHP 将把它替代为 'bar' 并使用之。

打开 error_reporting 来显示 E_NOTICE 级别的错误(将其设为 E_ALL)时将看到这些错误。默认情况下 error_reporting 被关闭。

用函数返回值作为数组索引的例子。PHP 也可以用已知常量,




两者是一样的


不建议使用php保留字

转换为数组

  • 对于任意 integer,float,string,boolean 和 resource 类型,如果将一个值转换为数组:

    将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。 (array)$scalarValue 与 array($scalarValue)

  • 如果一个 object 类型转换为 array:

    结果为一个数组
    其单元为该对象的属性
    键名将为成员变量名
    整数属性不可访问
    私有变量前会加上类名作前缀
    保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 NULL 字符


你可能感兴趣的:(数据类型转化)