PHP中的数组使用哈希表(hashtable)的形式构成,其功能是非常强大的,在哈希表中,每一个数据项都由两个部分组成,即键(key)和值(value);键就是数据的名称,而值就是真正的数据了。
创建与访问数组
在PHP中,定义数组使用array()语句结构。如下面的代码,我们将创建一个名片类的数组。
$arr = array('name'=>'Tom','age'=>35,'phone'=>'123456');
代码中,我们在数组中定义了三个数据项,分别是name、age和phone,然后,我们可以通过foreach()访问全部成员,如下面的代码。
foreach (arr askey=>value)
{ echokey, ' : ', $value, '<br>';
}
代码在页面中的显示结果如下图。
此外,我们还可以通过数组的键来访问其成员,此时使用[]指定键,如下面的代码。
echo arr['name'], '<br>';
echoarr['age'], '<br>';
echo $arr['phone'], '<br>';
代码执行结果显示如下图。
很多情况下,我们可能需要使用向C或Java风格的数组,也就是从0开始的索引值来表示数组成员,在PHP中,如果我们使用array()结构创建数组时不指定键,则创建的就是这样的数组,如下面的代码。
$arr = array('a','b','c','d','e','f','g');
$count = count($arr);
for($i=0; $i<$count; $i++)
{
echo $arr[$i];
}
当然,这样的数组同样可以使用foreach语句访问,如下面的代码:
$arr = array('a','b','c','d','e','f','g');
foreach($arr as $value)
{
echo $value;
}
这两段代码在页面中会显示abcdefg。也许你还记得代码中的功能可以使用implode()或join()函数来实现,如下面的代码。
$arr = array('a','b','c','d','e','f','g');
$str = implode("",$arr);
echo $str;
如果需要数组的索引值不是从0开始,可以在创建数组时指定,如:
$arr = array(1=>'a','b','c','d','e','f','g');
echo $arr[1]; // 显示a
这样,”a”成员的索值就是是1,其后面的成员索引值也会依次递增。
在开发过程中,如果我们想一次查看数组的全部内容,还可以使用print_r()函数,它用于按规则显示对象的内容,而这在代码调试过程中是很有用的。如下面的代码。
$arr = array('name'=>'Tom','age'=>35,'phone'=>'123456');
print_r($arr);
其显示结果如下图。
如果数组成员是具有相同间隔(步长)的数据内容,我们还可以使用range()函数快速创建这个数组,如下面的代码。
$arr1 = range(1,5); // 默认间隔为1,数组成员为1,2,3,4,5
$arr2 = range(1,5,2); // 指定间隔为2,数组成员为1,3,5
除了数字,range()函数还可以创建字符类的数组,但这似乎并不经常用到,如:
$arr = range('a','d'); // 数组成员为a,b,c,d
修改数组成员
对数组的单个成员修改是很方便的,我们可以通过键或索引值来进行相应的操作,如:
$arr = array('name'=>'Tom','age'=>35,'phone'=>'123456');
$arr['name'] = 'Jerry';
echo $arr['name']; // 显示Jerry
或者是:
$arr = array('a','b','c','d','e','f','g');
$arr[2] = '*'; // 将c修改为*
echo $arr[2]; // 显示*
现在的问题是:如果指定的键或索引值不存在会怎么样呢?如下面的代码。
$arr = array('name'=>'Tom','age'=>35,'phone'=>'123456');
$arr['organization'] = 'XYZ';
echo $arr['organization']; // 显示XYZ
代码中,当我们使用键指定数组中不存在的成员时,会在数组中自动添加由新键和值组成的成员。通过索引值设置数组成员时,也是这样,如下面的代码。
$arr = array('a','b','c');
$arr[5] = '*';
echo $arr[5]; // 显示 *
接下来,我们做个小测试,将成员从1到10的数组成员都添加前缀“No.”,可以使用几种方法。
方法一,如下面的代码:
$arr = range(1,10);
for($i=0; $i<10; $i++)
{
$arr[$i] = 'No.'.$arr[$i];
}
print_r($arr);
也许你还会使用foreach语句的方法来实现,如下面的代码。
$arr = range(1,10);
foreach($arr as $value)
{
$value = 'No.'.$value;
}
print_r($arr);
我们可以看到,在访问数组成员时使用foreach语句的确比for语句清晰很多,但你也会发现,这段代码并没有修改arr数组成员,原因就在于我们使用value变量修改数组成员的值时,实际上是在修改这些成员的副本,如果我们需要在循环结构中修改数组成员的值,就必须在foreach语句中的$value前使用&符号,如下面的代码。
foreach(arr as &value)
这样一来,在foreach结构内的对&value的修改,实际上就是在修改$arr数组成员的值。
此外,在PHP中并没有删除指定数组成员的函数,但是,我们可以使用unset()语句结构来完成这项工作,如:
$arr = range(1, 10);
unset($arr[5]);
数值索引的真相
在PHP中使用数组的一个事实,也是非常重要的一点就是:数组的数值索引实际上是以数值作为键索引的一种形式。
有时候,我们可能想判断数组的第一个成员是否存在,也许你会使用下面的代码。
$arr = array("a"=>"aa", "b"=>"bb");
var_dump(isset($arr[0])); // bool(false)
什么情况?这是因为,在$arr数组中并没有以“0”为键的成员,所以,代码会显示bool(false)。
多维数组
在PHP中,多维数组更像是关于数组的数组,如下面的代码,它模拟了一个二维的数组结构。
$group = array(
array('name'=>'Tom','age'=>29),
array('name'=>'Jerry','age'=>33),
array('name'=>'John','age'=>35)
);
echo $group[1]['name']; // 显示Jerry
我们定义的数组变量$group,它的每一个成员也都是一个数组结构,包括name和age两个数据项,这样,我们就可以通过[][]结构来访问所需要的数据值。
数组函数
以下介绍一些常用的数组处理函数。
count()函数
count()函数用于获取数组的成员数量,在前面我们已经使用过,与其功能相同的还有sizeof()函数。
array_key_exists()函数
array_key_exists()函数用于检查数组的成员中是否存在指定的键。如下面的代码。
$arr = array('name'=>'Tom','age'=>35);
var_dump(array_key_exists('name', $arr)); // 显示 bool(true)
var_dump(array_key_exists('phone', $arr)); // 显示bool(false)
此外,array_key_exists()函数对于数值索引同样适用。
array_keys()函数
array_keys()函数用于返回数组中的键组成的新数组,新数组以数值为索引,以原数组键名称为成员数据。array_keys()函数包括三个参数:
- 参数一,指定原有的数组。
- 参数二,可选,指定搜索的键名,如果指定此参数,则在原数组中存在它们时返回指定键名的数组;如果不指定这个参数,则返回原数组中所有键名。
- 参数三,可选,指定在搜索是否按全等于运算(===),默认为false。
如:
$arr1 = array("a"=>"aa", "b"=>"bb", "c"=>"cc");
$arr2 = array_keys($arr1);
// $arr2等于array("0"=>"a", "1"=>"b", "2"=>"c");
array_splice()函数
用于删除、替换数组的一部分,它定义了四个参数,其中:
- 参数一,需要操作的数组,定义为按引用传递。
- 参数二,开始操作的数组成员位置,使用数值索引,但请注意,这个索引并不是成员的键,而是真正的成员位置索引(由0开始)。
- 参数三,可选。指定操作从参数二位置开始的数组成员数量,默认为0。
- 参数四,可选。指定替换或插入指定位置的元素。
此外,array_splice()函数的返回值将是从原数组中移除的元素组成的数组,如果没有移除内容,而返回空数组。
如下面的代码。
$arr1 = array("a","b","c","d","e");
$arr2 = array_splice($arr1,2,1);
print_r($arr1); // a,b,d,e
$arr3 = array_splice($arr1,2,2,"*"); // 将d,e替换为*
print_r($arr1); // a,b,*
array_values()函数
array_values()函数用于返回指定数组中的所有的值组成的新数组,并且使用数值索引。如:
$arr1 = array("a"=>"aa", "b"=>"bb", "c"=>"cc");
$arr2 = array_values($arr1);
// $arr2等于array("0"=>"aa", "1"=>"bb", "2"=>"cc");
in_array()函数
判断一个值在数据成员中是否存在。如:
$arr = array("a", "b", "c");
var_dump(in_array("a", $arr)); // bool(true)
sort()与rsort()函数
sort()函数用于对数组按成员的值排序,如下面的代码:
$arr1 = array(9,3,8,5,1,6);
sort($arr1);
print_r($arr1);
代码显示如下:
Array ( [0] => 1 [1] => 3 [2] => 5 [3] => 6 [4] => 8 [5] => 9 )
我们可以看到,调用sort()函数后,数组的成员已经按升序进行了重新排列;与sort()相对应的是rsort()函数,它的功能是将数组成员按照降序进行排列。
在sort()函数中,我们还可以使用第二个参数,其功能是指定数组成员在排列时的比较方法,其值由一些常量指定,包括:
- SORT_REGULAR值,这也是默认值,成员将按原始类型进行比较。
- SORT_NUMERIC值,数组成员作为数字进行比较。
- SORT_STRING值,数组成员作为字符串进行比较。
- SORT_LOCALE_STRING值,根据当前的区域(locale)设置,将数组成员作为字符串进行比较。区域设置可以使用setlocale()函数。
- SORT_NATURAL值,数组成员按自然顺序,并作为字符串进行排序。
- SORT_FLAG_CASE值,数组成员按自然顺序,并作为字符串进行排序,而且不区分字母大小写。
asort()与arsort()函数
asort()函数与sort()功能相同,也是按照数组成员的值进行升序排列,而arsort() 函数,则是按照数组成员值进行降序排列。
ksort()与krsort()函数
ksort()函数按照数组成员的键进行升序排列,而krsort()函数则是按照数组成员的键进行降序排列。
shuffle()函数
shuffle()函数用于对数组成员进行随机排序,比如在扑克类游戏中,你可以通过如下的代码非常方便地完成洗牌操作。
$cards = range(1,54);
shuffle($cards);
array_reverse()函数
array_reverse()函数用于对数组成员进行反向排序,并返回排序后的新数组,如:
$arr = range(1,5); // 1,2,3,4,5
$arr_rev = array_reverse($arr);
print_r($arr_rev); // 5,4,3,2,1
array_push()与array_pop()函数
array_push()函数用于将一个成员添加到数组的末尾,而array_pop()函数同是从数组的删除数组末尾的成员,并返回这个成员的数据。如:
$arr = range(1,5); // 1,2,3,4,5
array_push($arr, 6); // 1,2,3,4,5,6
$num = array_pop($arr);
echo $num; // 显示6
array_count_values()函数
array_count_values()函数是一个快捷的数组成员统计工具,它可以方便地计算出一个数组中每一种数据出现了多少次,并返回统计结果;返回结果同样也是一个数组,其中,原数组中的成员数据作为新数组成员的键,其出现次数作为新数组成员的值。如下面的代码。
$arr = array(1,2,1,3,1,2,1,2,3,4);
$result = array_count_values($arr);
print_r($result);
其结果如下:
Array ( [1] => 4 [2] => 3 [3] => 2 [4] => 1 )
即在$arr数组中,1出现了4次,2出现了3次,3出现了2次,而4出现了1次。
extract()函数
extract()函数用于将数组分解成相对应的一系列变量,其中,成员的键作为变量名,成员的值作为变量的值。如下面的代码。
$arr = array('name'=>'Tom','age'=>35,'phone'=>'123456');
extract($arr);
echo $name; //显示Tom
echo $age; //显示35
echo $phone; // 显示123456
<?php
extract(_GET);
print "name=name".'<br>';
print "language=$language";
?>
然后,我们通过“http://localhost:8080/index.php?name=Tom&language=zh-cn”来访问这个页面,我们得到如下图的结果。
如果数组中有相同键的成员,则会使用最后的成员信息创建变量,这是extract()函数的默认处理方式,不过,extract()函数中还可以指定第二和第三个参数来改变这一规则;一般情况下,我们还是建议使用extract()函数的默认规则来处理同名键的问题,这就需要对用户提交的数据进行更加严格的控制,避免同名键数据的出现。不过,在一些特殊情况下,可能还是需要使用extract()函数的更多参数,在日期和时间处理的讨论中,我们可以看到相关的应用。
array_walk()函数
array_walk()函数用于将数组成员进行相同的操作,而这些工作是由另外一个函数来完成的,如下面的例子,我们将实现给每个数组成员添加前缀的工作。
function addPrefix(&value,key, prefix)
{value = prefix.value;
}
arr = range(1,5);
array_walk(arr, 'addPrefix', 'No.');
print_r($arr);
代码运行结果如下:
Array (
[0] => No.1
[1] => No.2
[2] => No.3
[3] => No.4
[4] => No.5
)
首先,我们定义了addPrefix()函数,它包括三个参数: – 参数一,用于表示数组成员值的参数,请注意,需要使用&符号定义为引用参数,只有这样才能在函数中正确的修改数组成员的值。 – 参数二,表示数组成员键名称的参数。 – 参数三,用于指定操作相关数据的参数。
然后,通过调用array_walk()函数,我们将一个1到5的整数数组的每个成员都添加“No.”前缀。在array_walk()过程中同样使用了三个参数:
- 参数一,需要处理的数组变量。
- 参数二,字符串形式的函数名称。
- 参数三,可选,指定用于操作的相关附加数据;这个参数的指定应与被调用函数中第三个参数的定义相匹配,如例子中的addPrefix()函数。下面的代码,我们将完成与前面代码相同的工作,而这一次,array_walk()函数和addPrefix()参数都没有使用第三个参数。
function addPrefix(&value,key)
{
value = "No.".value;
}
arr = range(1,5);
array_walk(arr, 'addPrefix');
print_r($arr);