数据类型之三种复合类型
在关于变量的章节中,我们已经知道 PHP 支持 9 种原始数据类型,在这里我们再次复习一下:
四种标量类型
- Boolean:布尔值。仅有两个值,
TRUE
或FALSE
- Integer:整数型
- Float:浮点数,也称作
double
,表示带小数点的小数,例如66.66
- String:字符串
三种复合类型
- Array:数组
- Object:对象
- Callable:可调用类型
两种特殊类型
- Resource:资源类型,保存了到外部资源的一个引用
- NULL:表示一个变量没有值,只有唯一的可能值
NULL
复习完毕,上一节我们了解了数据类型的四种标量类型,现在我们来了解三种复合类型。
Array:数组
数组是可存储一系列值的单个变量数据类型,实际上是一组“键-值”对的有序映射(将值关联到键)。其中键(key
)只能是整型或者字符串类型,值(value
)可以是任意类型。请看下方示例代码:
<?php
// 定义一个数组
$arr = array();
var_dump($arr);
/* 输出:
array(0) {
}
*/
$arr = [];// 方括号定义
var_dump($arr);
/* 输出:
array(0) {
}
*/
$arr = [
'key'=>'value',
'键'=>'值',
6=>'整型键名',
7.8=>'浮点型键名会被强制类型转换为整型',
'key'=>'同名键只使用最后一个,之前的会被覆盖',
null=>'NULL类型键名会被转化为空字符串',
true=>'布尔值true键名会被转化为1,false则是0'
];
print_r($arr);
/* 输出:
Array
(
[key] => 同名键只使用最后一个,之前的会被覆盖
[键] => 值
[6] => 整型键名
[7] => 浮点型键名会被强制类型转换为整型
[] => NULL类型键名会被转化为空字符串
[1] => 布尔值true键名会被转化为1,false则是0
)
*/
var_dump(count($arr));// count()是检测数组元素个数的函数。输出:int(6)
// var_dump($arr[4]);// 提示:该键名不存在,无法访问
var_dump($arr['']);// 通过键名访问特定元素。输出:string(43) "NULL类型键名会被转化为空字符串"
示例代码中的数组中,每个元素都拥有键名,这种数组被称为“关联数组”,意为值与键相关联,通常用于键名有一定含义的情况;
若是未定义键名的数组,则该数组会自动转化为“数字索引数组”,可以通过元素的位置进行访问,数字索引数组的起始索引为0
。例如:
<?php
$arr = [
'极速数据',
'https://www.jisuapi.com/',
'PHP教程'
];
var_dump($arr[2]);// 访问数组$arr的第三个元素。输出:string(9) "PHP教程"
以上代码中只出现了一维数组,一维数组指的是一个数组中不包含其他数组,在现实世界我们可以将之看为一个只有行的列表。而数组的值可以是任意类型。如果数组元素嵌套另一个数组,形如下方代码,二维数组可以看做具有行和列(多于 1 列)的表格,三维数组可看做现实世界的魔方,每个格子代表一个元素:
<?php
// 二维数组
$arr = [
[1, 2, 3],// 该数组是数组$arr的一个元素
[4, 5, 6],
[7, 8, 9],
];
// 三维数组
$arr = [
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
],// 该数组是数组$arr的一个元素,该数组中又包含一个数组
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
],
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
],
];
常用函数
PHP 中有许多操作数组的函数,在开发时经常会用到的比如计算数组中元素的个数(函数count()
)、将一维数组转为字符串(函数implode()
)、检测值是否为数组(函数is_array()
)等。后续我们将根据需求来详细讲解这些函数。
Object:对象
对象是描述客观世界中的一个实体。这个实体具备的特征与功能定义了其对象。例如一本书,它拥有出版社、作者、定价等特征,它可以被查看、借阅。这些则定义了“书”这个对象。
定义一个对象就是定义一个类,使用关键字class
开头,其后跟着类名,然后是花括号,花括号内包含类的属性和方法的定义。定义对象暂且略过不提,这里主要讲对象的使用。
创建一个对象
要创建一个对象,需要使用new
关键字实例化一个类
,后跟类名和用小括号包裹的参数列表(根据类定义)
<?php
// 预先定义一个类Book
class Book
{
// 类属性
// 类方法
}
// 实例化一个类
$book = new Book();
其他类型转化为对象
其他类型转化为对象将会创建一个内置的staClass
实例。请看示例代码:
<?php
// 其他类型转化为对象:非数组类型转化为对象将会自动包含成员变量名 scalar
$boolean = true;
$obj = (object)$boolean;
var_dump($obj);
/* 输出:
object(stdClass)#1 (1) {
["scalar"]=>
bool(true)
}
*/
$int = 10;
$obj = (object)$int;
var_dump($obj);
/* 输出:
object(stdClass)#1 (1) {
["scalar"]=>
int(10)
}
*/
$float = 7.8;
$obj = (object)$float;
var_dump($obj);
/* 输出:
object(stdClass)#1 (1) {
["scalar"]=>
float(7.8)
}
*/
$str = '一个字符串对象';
$obj = (object)$str;
var_dump($obj);
/* 输出:
object(stdClass)#1 (1) {
["scalar"]=>
string(21) "一个字符串对象"
}
*/
// 数组类型转化为对象
$arr = [
'key'=>'value',
'键'=>'值',
6=>'整型键名',
7.8=>'浮点型键名会被强制类型转换为整型',
'key'=>'同名键只使用最后一个,之前的会被覆盖',
null=>'NULL类型键名会被转化为空字符串',
true=>'布尔值true键名会被转化为1,false则是0'
];
$obj = (object)$arr;
var_dump($obj);
/* 输出:
object(stdClass)#1 (6) {
["key"]=>
string(54) "同名键只使用最后一个,之前的会被覆盖"
["键"]=>
string(3) "值"
["6"]=>
string(12) "整型键名"
["7"]=>
string(48) "浮点型键名会被强制类型转换为整型"
[""]=>
string(43) "NULL类型键名会被转化为空字符串"
["1"]=>
string(50) "布尔值true键名会被转化为1,false则是0"
}
*/
不同的对象与它们之间的联系共同构建了客观世界。我们可以根据某一些特征与行为来定义某一类对象。 在之后的面向对象程序设计中,我们将感受到对象的强大。
Callable:可调用类型
自 PHP 5.4 起,PHP 支持接受用户自定义的函数作为参数传入另一个函数中使用,函数作为值使用,简洁了代码,增强了可读性,也更加灵活,此时传入的函数就是可调用类型。
参数传递方式
PHP传递函数时以string
类型的函数名作为参数传递的,可使用任何内置或者用户自定义的函数,除了语言结构:array()
、echo
、empty()
、eval()
、exit()
、isset()
、list()
、print
和unset()
。例如:
<?php
function callFunc($a, $b, $callback) {
$callback();// 调用传入$callback的函数
// callback();// 调用名为 callback() 的函数
return $a + $b;
}
function callback() {
echo '调用方法名:',__METHOD__;
echo PHP_EOL;
}
function callback2() {
echo '调用方法名:',__METHOD__;
echo PHP_EOL;
}
callFunc(1, 2, 'callback');
// 输出:调用方法名:callback
callFunc(1, 2, 'callback2');
// 输出:调用方法名:callback2
可使用callable
来指定回调类型callback
,callable
类型可接受普通函数和匿名函数,closure
类型只接受匿名函数。如下方代码:
<?php
function callFunc2(callable $callback) {
$callback();
}
function callFunc3(Closure $callback) {
$callback();
}
callFunc2('callback');// 输出:调用方法名:callback
// callFunc3('callback');// 出错:传入参数必须是一个匿名函数
$closure = function() {
echo '这是一个匿名函数', __METHOD__;
};
callFunc3($closure);// 输出:这是一个匿名函数{closure}
回调函数不仅可以是简单函数,也可以是对象的方法,包括静态类方法。如下:
<?php
// 回调类静态方法
class Jisu
{
public static function myMethod() {
echo '调用了一个类中的静态方法';
echo PHP_EOL;
}
}
call_user_func(array('Jisu', 'myMethod'));// 输出:调用了一个类中的静态方法
class API extends Jisu
{
public static function myMethod()
{
echo '继承了父类的静态方法,在子类中重写了';
echo PHP_EOL;
}
}
call_user_func(array('API', 'myMethod'));// 调用类API的myMethod()方法。输出:继承了父类的静态方法,在子类中重写了
call_user_func(array('API', 'parent::myMethod'));// 调用了子类API的父类的myMethod()方法。输出:调用了一个类中的静态方法
上方代码使用了call_user_func()
函数,它将第一个参数作为回调函数调用,其余参数为回调函数的参数。类似的方法还有call_user_func_array()
。
可调用类型在PHP初级编程中涉及不多,这里不作深入讲解。
好的,关于数据类型的三种复合类型就讲到这里,之后我们将讲解两种特殊类型!