简介
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 字符