9.1 数组的分类
在PHP中,更具数组提供下标的不同方式,将数组分为索引数组(indexed)和关联数组(associative)两种。索引数组的索引值是整数,而关联数组是以字符串作为索引值。
9.2 数组的定义
9.2.1 直接赋值的方式声明数组
$数组变量名[下标]=资料内容 //其中索引值(下标)可以是一个字符串或一个整数
例如:
<?php
$contact1[0]=1;
$contact1[1]="高某";
$contact1[2]="A公司";
$contact1[3]="(010)98765432";
$contact1[4]="gao@brophp.com";
?>
或者
<?php
$contact1["Id"]=1;
$contact1["Name"]="高某";
$contact1["Company"]="A公司";
$contact1["Tel"]="(010)98765432";
$contact1["Email"]="gao@brophp.com";
?>
在声明数组变量时,也可以在下标中使用数字和字符串混合。例如:
<?php
$contact1["Id"]=1;
$contact1[0]=1;
$contact1["Name"]="高某";
$contact1[1]="高某";
$contact1["Company"]="A公司";
$contact1[2]="A公司";
?>
声明索引数组时,如果索引值是递增的,可以不在方括号内指定索引值,默认的索引值是从0开始依次增加的。
<?php
$contact1[]=1;
$contact1[]="高某";
$contact1[]="A公司";
$contact1[]="(010)98765432";
$contact1[]="gao@brophp.com";
?>
另外在PHP中,索引数组的下标可以是非连续的值,只要在初始化时指定非连续的下标值即可。(如果指定过则会重新赋值)
<?php
$contact1[]=1;
$contact1[14]="高某";
$contact1[]="A公司";
$contact1[14]="(010)98765432";
$contact1[]="gao@brophp.com";
?>
以上代码混合声明的数组用print_r()
或var_dump()
函数打印结果为:
array (size=4)
0 => int 1
14 => string '(010)98765432' (length=15)
15 => string 'A公司' (length=5)
16 => string 'gao@brophp.com' (length=14)
补充说明:print_r()
和var_dump
函数
var_dump — 打印变量的相关信息
(PHP 4, PHP 5, PHP 7)
void var_dump ( mixed $expression [, mixed $... ] )
此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
In PHP 5 all public, private and protected properties of objects will be returned in the output.
Tip
和直接将结果输出到浏览器一样,可使用输出控制函数来捕获当前函数的输出,然后(例如)保存到一个 string 中。
参数
expression
你要打印的变量。
返回值
没有返回值。
范例
<?php
$a = array(1, 2, array("a", "b", "c"));
var_dump($a);
?>
以上例程会输出:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
}
<?php
$b = 3.1;
$c = true;
var_dump($b, $c);
?>
以上例程会输出:
float(3.1)
bool(true)
print_r — 打印关于变量的易于理解的信息。
(PHP 4, PHP 5, PHP 7)
bool print_r ( mixed $expression [, bool $return ] )
print_r()
显示关于一个变量的易于理解的信息。如果给出的是 string
、integer
或 float
,将打印变量值本身。如果给出的是 array
,将会按照一定格式显示键和元素。object
与数组类似。
记住,print_r()
将把数组的指针移到最后边。使用 reset()
可让指针回到开始处。
范例
<pre>
<?php
$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x','y','z'));
print_r ($a);
?>
</pre>
上边的代码将输出:
<pre>
Array
(
[a] => apple
[b] => banana
[c] => Array
(
[0] => x
[1] => y
[2] => z
)
)
</pre>
如果想捕捉 print_r()
的输出,可使用 return
参数。若此参数设为 TRUE,print_r()
将不打印结果(此为默认动作),而是返回其输出。
<?php
$b = array ('m' => 'monkey', 'foo' => 'bar', 'x' => array ('x', 'y', 'z'));
$results = print_r ($b, true); //$results 包含了 print_r 的输出结果
?>
相关函数:var_export()
9.2.2 使用array()语言结构新建数组
初始化数组的另一种方法是使用array()语言结构来新建一个数组。
$数组变量名=array(key1=>value1,key2=>value2,……keyN=>valueN);
如果不使用“=>”符号指定下标,默认为索引数组。例如:
$contact1=array(1,14=>"高某","A公司","北京市",14=>"(010)98765432","gao@brophp.com");
其结果为
Array ( [0] => 1 [14] => (010)98765432 [15] => A公司 [16] => 北京市 [17] => gao@brophp.com )
如果使用array()语言结构声明关联数组u,就必须使用”=>”运算符指定字符串下标。
9.2.3 多维数组的声明
二维数组的声明和一维数组的声明方式一样,只不过是将数组中的每个元素也声明成一个数组u,也有直接为数组元素赋值和使用array()函数两种声明数组的方法。
<?php
$contact1=array(
array(1,'高某','A公司','北京市','(010)98765432','gm@linux.com'),
array(2,'洛某','B公司','上海市','(021)12345678','lm@apache.com'),
array(3,'峰某','C公司','天津市','(022)2468246','fm@mysql.com'),
);
?>
输出为:
Array (
[0] => Array (
[0] => 1
[1] => 高某
[2] => A公司
[3] => 北京市
[4] => (010)98765432
[5] => gm@linux.com )
[1] => Array (
[0] => 2
[1] => 洛某
[2] => B公司
[3] => 上海市
[4] => (021)12345678
[5] => lm@apache.com )
[2] => Array (
[0] => 3
[1] => 峰某
[2] => C公司
[3] => 天津市
[4] => (022)2468246
[5] => fm@mysql.com )
)
这个数组默认采用了数字索引方式,也可以使用”=>”运算符指定二维数组中每个元素的下标。
<?php
$contact1=array(
"北京联系人"=>array(1,'高某','A公司','北京市 ','(010)98765432','gm@linux.com'),
"上海联系人"=>array(2,'洛某','B公司','上海市','(021)12345678','lm@apache.com'),
"天津联系人"=>array(3,'风某','C公司','天津市','(022)2468246','fm@mysql.com'),
);
?>
访问相应的二维数组:
<?php
echo "第一个联系人的公司:".$contact1[0][2]."<br />";
echo "上海联系人的E-mail:".$contact1["上海联系人"][2]."<br />";
>
9.3 数组的遍历
9.3.1 使用for语句循环遍历数组
由于在PHP中,不仅可以指定非连续的数字索引值,而且还存在以字符串为下标的关联数组,所以在PHP中很少使用for语句循环数组。
<?php
$contact=array(1,'高某','A公司','北京市','(010)98765432','gao@brophp.com');
echo '<table border="1" width="600" align="center">';
echo '<caption><h1>联系人列表</h1></caption>';
echo '<tr bgcolor="#DDDDDD">';
echo '<th>编号</th><th>姓名</th><th>公司</th><th>地址</th><th>电话</th><th>E-mail</th>';
echo '</tr><tr>';
for($i=0;$i<count($contact);$i++)
echo '<td>'.$contact[$i].'</td>';
echo '</tr></table>';
?>
但如果使用for循环嵌套来完成遍历,也必须在每层循环中正确指定索引名称,每层的索引值都必须是顺序的数字索引。
9.3.2 使用foreach语句遍历数组
(PHP 4, PHP 5)
foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:
foreach (array_expression as $value)
statement
foreach (array_expression as $key => $value)
statement
第一种格式遍历给定的 array_expression
数组。每次循环中,当前单元的值被赋给 $value
并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。
第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量 $key
。
还能够自定义遍历对象。
Note:
当
foreach
开始执行时,数组内部的指针会自动指向第一个单元。这意味着不需要在foreach
循环之前调用reset()
。
由于foreach
依赖内部数组指针,在循环中修改其值将可能导致意外的行为。
可以很容易地通过在 $value
之前加上 &
来修改数组的元素。此方法将以引用赋值而不是拷贝一个值。
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // 最后取消掉引用
?>
$value
的引用仅在被遍历的数组可以被引用时才可用(例如是个变量)。以下代码则无法运行:
<?php
foreach (array(1, 2, 3, 4) as &$value) {
$value = $value * 2;
}
?>
Warning
数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。
Note:
foreach 不支持用“@”来抑制错误信息的能力。
用户可能注意到了以下的代码功能完全相同:
<?php
$arr = array("one", "two", "three");
reset($arr);
while (list(, $value) = each($arr)) {
echo "Value: $value<br>\n";
}
foreach ($arr as $value) {
echo "Value: $value<br />\n";
}
?>
以下代码功能也完全相同:
<?php
$arr = array("one", "two", "three");
reset($arr);
while (list($key, $value) = each($arr)) {
echo "Key: $key; Value: $value<br />\n";
}
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br />\n";
}
?>
9.3.3 联合使用list()、each()和while循环遍历数组
*此处主要是PHP官方文档内容,书本知识作为辅助。
1.each()函数
(PHP 4, PHP 5)
each — 返回数组中当前的键/值对并将数组指针向前移动一步
array each ( array &$array )
返回数组中当前的键/值对并将数组指针向前移动一步
在执行 each() 之后,数组指针将停留在数组中的下一个单元或者当碰到数组结尾时停留在最后一个单元。如果要再用 each 遍历数组,必须使用 reset()。
返回值
返回 array 数组中当前指针位置的键/值对并向前移动数组指针。键值对被返回为四个单元的数组,键名为0,1,key和 value。单元 0 和 key 包含有数组单元的键名,1 和 value 包含有数据。
如果内部指针越过了数组的末端,则 each() 返回 FALSE。
范例
<?php
$foo = array("bob", "fred", "jussi", "jouni", "egon", "marliese");
$bar = each($foo);
print_r($bar);
?>
$bar
现在包含有如下的键/值对:
Array
(
[1] => bob
[value] => bob
[0] => 0
[key] => 0
)
<?php
$foo = array("Robert" => "Bob", "Seppo" => "Sepi");
$bar = each($foo);
print_r($bar);
?>
$bar
现在包含有如下的键/值对:
Array
(
[1] => Bob
[value] => Bob
[0] => Robert
[key] => Robert
)
ach() 经常和 list() 结合使用来遍历数组,例如:
<?php
$fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');
reset($fruit);
while (list($key, $val) = each($fruit)) {
echo "$key => $val\n";
}
?>
以上例程会输出:
a => apple
b => banana
c => cranberry
因为将一个数组赋值给另一个数组时会重置原来的数组指针,因此在上边的例子中如果我们在循环内部将 $fruit
赋给了另一个变量的话将会导致无限循环。
2.list()函数
(PHP 5 >= 5.5.0)
PHP 5.5 增添了遍历一个数组的数组的功能并且把嵌套的数组解包到循环变量中,只需将 list()
作为值提供。
例如:
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a, $b)) {
// $a contains the first element of the nested array,
// and $b contains the second element.
echo "A: $a; B: $b\n";
}
?>
以上例程会输出:
A: 1; B: 2
A: 3; B: 4
list()
中的单元可以少于嵌套数组的,此时多出来的数组单元将被忽略:
<?php
$array = [
[1, 2],
[3, 4],
];
foreach ($array as list($a)) {
// Note that there is no $b here.
echo "$a\n";
}
?>
以上例程会输出:
1
3
如果 list() 中列出的单元多于嵌套数组则会发出一条消息级别的错误信息。
list()不是真正的函数,而是PHP的语言结构。list()语句和其他函数在使用上有很大的区别,并不是直接接收一个数组作为参数,而是通过“=”运算符以赋值的方式将数组中每个元素的值对应地赋给list()函数中的每个参数。list()函数又将它中的每个参数转换成直接可以在脚本中使用的变量。
3.while循环遍历数组
(PHP 4, PHP 5)
while 循环是 PHP 中最简单的循环类型。它和 C 语言中的 while 表现地一样。while 语句的基本格式是:
while (expr)
statement
while 语句的含意很简单,它告诉 PHP 只要 while 表达式的值为 TRUE 就重复执行嵌套中的循环语句。表达式的值在每次开始循环时检查,所以即使这个值在循环语句中改变了,语句也不会停止执行,直到本次循环结束。有时候如果 while 表达式的值一开始就是 FALSE,则循环语句一次都不会执行。
和 if 语句一样,可以在 while 循环中用花括号括起一个语句组,或者用替代语法:
while (expr):
statement
...
endwhile;
下面两个例子完全一样,都显示数字 1 到 10:
<?php
/* example 1 */
$i = 1;
while ($i <= 10) {
echo $i++; /* the printed value would be $i before the increment(post-increment) */
}
/* example 2 */
$i = 1;
while ($i <= 10):
print $i;
$i++;
endwhile;
?>
而对于while循环遍历数组书本上还有一个提及的语法格式,就是while和list()与each()相结合:
while(list($key,$value)=each(array_expression))
{
循环体;
}
虽然while遍历数组的结果和foreach语句相同,但是这两种方法是有区别的。在使用while()语句遍历数组之后,each()语句已经将传入的数组参数内部指针指向了数组末端,当再次使用while语句遍历同一数组时,数组指针已经在数组的末端,each()语句直接返回FALSE,while语句不会执行循环。只有在while语句执行前调用一下reset()函数,重新将数组指针指向第一个元素。
而foreach语句会自动重置数组的指针位置,当foreach开始执行时,数组内部的指针会自动指向第一个单元,这意味着不需要在foreach循环前调用reset()函数。
9.3.4 使用数组的内部指针控制函数遍历数组
key() - 从关联数组中取得键名
list() - 把数组中的值赋给一些变量
current() - 返回数组中的当前单元
reset() - 将数组的内部指针指向第一个单元
next() - 将数组中的内部指针向前移动一位
prev() - 将数组的内部指针倒回一位
此处留空待补充
9.2 预定义数组
$_SERVER:变量由Web服务器设定或者直接与当前脚本的执行环境相关联
$_ENV:执行环境提交至脚本的变量
$_GET:经由URL请求提交至脚本的变量
$_POST:经由HTTP POST方法提交至脚本的变量
$_REQUEST:经由GET,POST和COOKIE机制提交至脚本的变量,因此该函数并不值得信任
$_FILES:经由HTTP POST文件上传而提交至脚本的变量
$_COOKIE:经由HTTP Cookies方法提交至脚本的变量
$_SESSION:当前注册给脚本会话的变量
$GLOBALS:包含一个引用指向每个当前脚本的全局范围内有效的变量。该数组的键名为全局变量的名称
9.4.1 服务器变量:$_SERVER
$_SERVER
– $HTTP_SERVER_VARS[已弃用]
— 服务器和执行环境信息
$_SERVER
是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。这也就意味着大量的此类变量都会在» CGI 1.1 规范中说明,所以应该仔细研究一下。
$HTTP_SERVER_VARS
包含着相同的信息,但它不是一个超全局变量。 (注意 $HTTP_SERVER_VARS
与 $_SERVER
是不同的变量,PHP处理它们的方式不同)
说明
在 $_SERVER
中,你也许能够,也许不能够找到下面的这些元素。注意,如果以命令行方式运行 PHP,下面列出的元素几乎没有有效的(或是没有任何实际意义的)。
在下面的示例中使用foreach语句,将当前Web服务器创建的超全局数组$_SERVER
中信息全部遍历出来,供给用户查看。
<?php
foreach($_SERVER as $key=>$value){
echo '$_SERVER['.$key.'] = ' .$value.'<br>';
}
echo '<pre>';
print_r($_SERVER);
echo '</pre>';
echo $_SERVER['REMOTE_ADDR'];
?>
9.4.2 环境变量:$_ENV
$_ENV
– $HTTP_ENV_VARS [已弃用]
— 环境变量
说明
通过环境方式传递给当前脚本的变量的数组。
这些变量被从 PHP 解析器的运行环境导入到 PHP 的全局命名空间。很多是由支持 PHP 运行的 Shell 提供的,并且不同的系统很可能运行着不同种类的 Shell,所以不可能有一份确定的列表。请查看你的 Shell 文档来获取定义的环境变量列表。
其他环境变量包含了 CGI 变量,而不管 PHP 是以服务器模块还是 CGI 处理器的方式运行。
$HTTP_ENV_VARS
包含相同的信息,但它不是一个超全局变量。 (注意$HTTP_ENV_VARS
和 $_ENV
是不同的变量,PHP 处理它们的方式不同)
$_ENV
数组中的内容是在PHP解析器运行时,从PHP所在服务器中的环境变量转变为PHP全局变量的。
<?php
foreach($_ENV as $key=>$value){
echo '$_ENV['.$key.'] = '.$value.'<br />'
}
?>
9.4.3 URL GET变量:$_GET
$_GET
数组是通过URL GET方法传递的变量组成的数组。它属于外部变量,即在服务器页面中通过$_GET
超全局数组获取URL或表单的GET方式传递过来的参数。
例如下面一个URL:
http://www.brophp.com/index.php?action=1&user=lamp&tid=10&page=5
在index.php文件中就可以使用$_GET全局变量数组,获取到客户端通过URL的GET方式传过来的参数。
<?php
echo '参数为action为:'.$_GET["action"].'<br>';
echo '参数为user为:'.$_GET["user"].'<br>';
echo '参数为tid为:'.$_GET["tid"].'<br>';
echo '参数为page为:'.$_GET["page"].'<br>';
echo '<pre>';
print_r($_GET);
echo '</pre>';
?>
上面的代码中使用$_GET
超全局变量数组,取得URL中的4个参数action、user、tid和page在index.php页面中使用。
9.4.4 HTTP POST变量:$_POST
$_POST
数组是通过HTTP POST 方法传递的变量组成的数组。$_POST
和$_GET
数组之一都可以保存表单提交的变量,使用哪一个数组取决于提交表单时,在表单form标记中的method属性使用的方法是POST还是GET。
但使用$_POST
数组只能访问以POST方法提交的表达数据。例如写一个简单的用于添加联系人的表单页面,代码如下:
<html>
<head><title>添加联系人</head></title>
<body>
<form action="add.php" method="post">
编号:<input type="text" name="id"><br>
姓名:<input type="text" name="name"><br>
公司:<input type="text" name="company"><br>
地址:<input type="text" name="address"><br>
电话:<input type="text" name="phone"><br>
Email<input type="text" name="email"><br>
<input type="submit" value="添加联系人">
</form>
</body>
</html>
在上面文件中定义了一个添加联系人信息的表单页面,当用户单击提交时,将所有表单域的内容以POST方式提交到add.php页面中。在服务器端的add.php页面中,可以通过$_POST
数组的下标得到每个表单输入域中的内容。例如使用$_POST["address"]
获取表单中输入的用户地址信息。
<?php
echo "用户添加的联系人信息如下:".'<br>';
foreach($_POST as $key=>$value)
echo $key.':'.$value.'<br>';
?>
9.4.5 request变量:$_REQUEST
次关联数组包含$_GET
,$_POST
和$_COOKIE
中的全部内容。如果表单中有一个输入域的名称为name=”address”,表单是通过POST方法提交的, 则address文本输入框中的数据保存在$_POST["address"]
中。如果表单是通过GET方法提交的,数据将会保存在’$_GET[“address”]’中。但是$_REQUEST
的速度较慢,不推荐使用。
9.4.6 HTTP文件上传变量:$_FILES
使用表单的file输入域上传文件时,必须使用POST提交。但在服务器文件中,并不能通过$_POST
超全局数组获取到表单中file,而$_FILES
超全局变量数组是表单通过POST方法传递的已上传文件项目组成的数组。
9.4.7 HTTP Cookies:$_COOKIE
$_COOKIE
超级全局数组是经由HTTP Cookies方法提交至脚本的变量。当PHP脚本客户浏览器提取了一个cookie后,它将自动地把它转换成变量,可以通过这个$_COOKIE
超全局数组和cookie的名称来存取指定的cookie值。
9.4.8 Session变量:$_SESSION
9.4.9 Global变量:$GLOBALS
$GLOBALS
是由所有已定义的全局变量组成的数组,变量名就是该数组的索引。在函数或对象的方法中不需要使用global关键词访问它。
<?php
$a=1;
$b=2;
function Sum{
$GLOBALS['b']=$GLOBALS['a']+$BLOGALS['b'];
}
Sum();
echo $b;
?>
9.5 数组的相关处理函数
9.5.1 数组的键/值操作函数
1. 函数array_values()
(PHP 4, PHP 5)
array_values — 返回数组中所有的值
array array_values ( array $input )
array_values() 返回 input 数组中所有的值并给其建立数字索引。
参数
input
数组
范例
<?php
$array = array("size" => "XL", "color" => "gold");
print_r(array_values($array));
?>
以上例程会输出:
Array
(
[0] => XL
[1] => gold
)
2. 函数array_keys()
(PHP 4, PHP 5)
array_keys — 返回数组中部分的或所有的键名
array array_keys ( array $array [, mixed $search_value [, bool $strict = false ]] )
array_keys()
返回input
数组中的数字或者字符串的键名。
如果指定了可选参数search_value
,则只返回该值的键名。否则input
数组中的所有键名都会被返回。
参数
input
一个数组,包含了要返回的键。
search_value
如果指定了这个参数,只有包含这些值的键才会返回。
strict
判断在搜索的时候是否该使用严格的比较(===)。
范例
<?php
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
$array = array("blue", "red", "green", "blue", "blue");
print_r(array_keys($array, "blue"));
$array = array("color" => array("blue", "red", "green"),
"size" => array("small", "medium", "large"));
print_r(array_keys($array));
?>
以上例程会输出:
Array
(
[0] => 0
[1] => color
)
Array
(
[0] => 0
[1] => 3
[2] => 4
)
Array
(
[0] => color
[1] => size
)
3. 函数in_array()
(PHP 4, PHP 5)
in_array — 检查数组中是否存在某个值
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
在 haystack 中搜索 needle,如果没有设置 strict 则使用宽松的比较。
参数
needle
待搜索的值。
Note:
如果 needle 是字符串,则比较是区分大小写的。
haystack
这个数组。
strict
如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。
范例
<?php
$os = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $os)) {
echo "Got Irix";
}
if (in_array("mac", $os)) {
echo "Got mac";
}
?>
第二个条件失败,因为 in_array() 是区分大小写的,所以以上程序显示为:
Got Irix
in_array() 严格类型检查例子
<?php
$a = array('1.10', 12.4, 1.13);
if (in_array('12.4', $a, true)) {
echo "'12.4' found with strict check\n";
}
if (in_array(1.13, $a, true)) {
echo "1.13 found with strict check\n";
}
?>
以上例程会输出:
1.13 found with strict check
in_array() 中用数组作为 needle
<?php
$a = array(array('p', 'h'), array('p', 'r'), 'o');
if (in_array(array('p', 'h'), $a)) {
echo "'ph' was found\n";
}
if (in_array(array('f', 'i'), $a)) {
echo "'fi' was found\n";
}
if (in_array('o', $a)) {
echo "'o' was found\n";
}
?>
以上例程会输出:
'ph' was found
'o' was found
4. 函数array_flip()
(PHP 4, PHP 5)
array_flip — 交换数组中的键和值
array array_flip ( array $trans )
array_flip()
返回一个反转后的 array,例如 trans 中的键名变成了值,而trans
中的值成了键名。
注意trans
中的值需要能够作为合法的键名,例如需要是integer
或者string
。如果值的类型不对将发出一个警告,并且有问题的键/值对将不会反转。
如果同一个值出现了多次,则最后一个键名将作为它的值,所有其它的都丢失了。
<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>
现在 $trans 是:
Array
(
[1] => b
[2] => c
)
5. 函数array_reverse()
(PHP 4, PHP 5)
array_reverse — 返回一个单元顺序相反的数组
array array_reverse ( array $array [, bool $preserve_keys = false ] )
array_reverse() 接受数组 array 作为输入并返回一个单元为相反顺序的新数组。
参数
array
输入的数组。
preserve_keys
如果设置为 TRUE 会保留数字的键。 非数字的键则不受这个设置的影响,总是会被保留。
范例
<?php
$input = array("php", 4.0, array("green", "red"));
$result = array_reverse($input);
$result_keyed = array_reverse($input, true);
?>
这将使$result
和$result_keyed
具有相同的单元,但是注意键名的区别。$result
和 $result_keyed
的打印输出显示分别为:
Array
(
[0] => Array
(
[0] => green
[1] => red
)
[1] => 4
[2] => php
)
Array
(
[2] => Array
(
[0] => green
[1] => red
)
[1] => 4
[0] => php
)
9.5.2 统计数组元素的个数和唯一性
1. 函数count()
(PHP 4, PHP 5)
count — 计算数组中的单元数目或对象中的属性个数。
int count ( mixed $var [, int $mode = COUNT_NORMAL ] )
统计一个数组里的所有元素,或者一个对象里的东西。
对于对象,如果安装了 SPL,可以通过实现 Countable
接口来调用 count()
。该接口只有一个方法 Countable::count()
,此方法返回 count()
函数的返回值。
关于 PHP 中如何实现和使用数组可以参考手册中数组章节中的详细描述。
参数
var
数组或者对象。
mode
如果可选的 mode 参数设为 COUNT_RECURSIVE(或 1),count() 将递归地对数组计数。对计算多维数组的所有单元尤其有用。mode 的默认值是 0。count() 识别不了无限递归。
返回值
返回 var 中的单元数目。 如果 var 不是数组类型或者实现了 Countable 接口的对象,将返回 1,有一个例外,如果 var 是 NULL 则结果是 0。
count() 对没有初始化的变量返回 0,但对于空的数组也会返回 0。用 isset() 来测试变量是否已经初始化。
范例
<?php
$a[0] = 1;
$a[1] = 3;
$a[2] = 5;
$result = count($a);
// $result == 3
$b[0] = 7;
$b[5] = 9;
$b[10] = 11;
$result = count($b);
// $result == 3
$result = count(null);
// $result == 0
$result = count(false);
// $result == 1
?>
<?php
$food = array('fruits' => array('orange', 'banana', 'apple'),
'veggie' => array('carrot', 'collard', 'pea'));
// recursive count
echo count($food, COUNT_RECURSIVE); // output 8
// normal count
echo count($food); // output 2
?>
2. 函数array_count_value()
(PHP 4, PHP 5)
array_count_values — 统计数组中所有的值出现的次数
array array_count_values ( array $input )
array_count_values() 返回一个数组,该数组用 input 数组中的值作为键名,该值在 input 数组中出现的次数作为值。
错误/异常
对数组里面的每个不是 string 和 integer 类型的元素抛出一个警告错误(E_WARNING)。
范例
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
以上例程会输出:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)
3. 函数array_unique()
(PHP 4 >= 4.0.1, PHP 5)
array_unique — 移除数组中重复的值
array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )
array_unique()
接受 array 作为输入并返回没有重复值的新数组。
注意键名保留不变。array_unique()
先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。这并不意味着在未排序的 array 中同一个值的第一个出现的键名会被保留。
Note: 当且仅当 (string) $elem1 === (string) $elem2
时两个单元被认为相同。就是说,当字符串的表达一样时。 第一个单元将被保留。
范例
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
以上例程会输出:
Array
(
[a] => green
[0] => red
[1] => blue
)
<?php
$input = array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);
?>
以上例程会输出:
array(2) {
[0] => int(4)
[2] => string(1) "3"
}
9.5.3 使用回调函数处理数组的函数
函数的回调是PHP中的一种特殊机制,这种机制允许在函数的参数列表中传入用户自定义的函数地址作为参数处理或完成一定的操作。
1. 函数array_filter()
(PHP 4 >= 4.0.6, PHP 5)
array_filter — 用回调函数过滤数组中的单元
array array_filter ( array $input [, callable $callback = "" ] )
依次将 input 数组中的每个值传递到 callback 函数。如果 callback 函数返回 TRUE,则 input 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。
<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
function even($var)
{
// returns whether the input integer is even
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>
以上例程会输出:
Odd :
Array
(
[a] => 1
[c] => 3
[e] => 5
)
Even:
Array
(
[0] => 6
[2] => 8
[4] => 10
[6] => 12
)
<?php
$entry = array(
0 => 'foo',
1 => false,
2 => -1,
3 => null,
4 => ''
);
print_r(array_filter($entry));
?>
以上例程会输出:
Array
(
[0] => foo
[2] => -1
)
2. 函数array_walk()
(PHP 4, PHP 5)
array_walk — 使用用户自定义函数对数组中的每个元素做回调处理。
bool array_walk ( array &$array , callable $funcname [, mixed $userdata = NULL ] )
将用户自定义函数funcname
应用到array
数组中的每个单元。
array_walk()
不会受到 array 内部数组指针的影响。array_walk()
会遍历整个数组而不管指针的位置。
错误/异常
如果 funcname 函数需要的参数比给出的多,则每次 array_walk()
调用funcname
时都会产生一个E_WARNING
级的错误。这些警告可以通过在array_walk()
调用前加上 PHP 的错误操作符 @ 来抑制,或者用 error_reporting()
。
范例
<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
function test_alter(&$item1, $key, $prefix)
{
$item1 = "$prefix: $item1";
}
function test_print($item2, $key)
{
echo "$key. $item2<br />\n";
}
echo "Before ...:\n";
array_walk($fruits, 'test_print');
array_walk($fruits, 'test_alter', 'fruit');
echo "... and after:\n";
array_walk($fruits, 'test_print');
?>
以上例程会输出:
Before ...:
d. lemon
a. orange
b. banana
c. apple
... and after:
d. fruit: lemon
a. fruit: orange
b. fruit: banana
c. fruit: apple
3. 函数array_map()
(PHP 4 >= 4.0.6, PHP 5)
array_map — 将回调函数作用到给定数组的单元上。
array array_map ( callable $callback , array $arr1 [, array $... ] )
array_map()
返回一个数组,该数组包含了arr1
中的所有单元经过callback
作用过之后的单元。callback 接受的参数数目应该和传递给array_map()
函数的数组数目一致。
<?php
function myfun1($v){
if($v==="MySQL"){
return "Oracle";
}
return $v;
}
$lamp=array("Linux","Apache","MySQL","PHP");
print_r(array_map("myfun1",$lamp));
function myfun2($v1,$v2){
if($v1===$v2){
return "same";
}
return "different";
}
$a1=array("Linux","PHP","MySQL");
$a2=array("Unix","PHP","Oracle");
print_r(array_map("myfun2",$a1,$a2));
$a1=array("Linux","Apache");
$a2=array("MySQL","PHP");
print_r(array_map(null, $a1,$a2));
?>
9.5.4 数组的排序函数
PHP中常用的数组排序函数
sort():按由小到大的升序对给定数组的值排序
rsort:对数组的元素按照键值进行由大到小的逆向排序
usort():使用用户自定义的回调函数对数组排序
asort():对数组进行由小到大排序并保持索引关系
uasort():使用用户自定义的比较回调函数对数组中的值进行排序并保持索引关联
ksort():按照键名对数组进行由小到大的排序,为数组值保留原来的键
krsort():将数组按照由大到小的键逆向排序,为数组值保留原来的键
uksort():使用用户自定义的比较回调函数对数组中的键名进行排序
natsort():用自然顺序算反对给定数组中的元素排序
natcasesort():用不区分大小写的自然顺序算法对给定数组中的元素进行排序
array_multisort():对多个数组或多维数组进行排序
1. 简单的数组排序函数 sort()和rsort()
本函数对数组进行排序。当本函数结束时数组单元将被从最低到最高重新安排。
bool sort ( array &$array [, int $sort_flags = SORT_REGULAR ] )
可选的第二个参数 sort_flags 可以用以下值改变排序的行为:
排序类型标记:
SORT_REGULAR - 正常比较单元(不改变类型)
SORT_NUMERIC - 单元被作为数字来比较
SORT_STRING - 单元被作为字符串来比较
SORT_LOCALE_STRING - 根据当前的区域(locale)设置来把单元当作字符串比较,可以用 setlocale() 来改变。
SORT_NATURAL - 和 natsort() 类似对每个单元以“自然的顺序”对字符串进行排序。 PHP 5.4.0 中新增的。
SORT_FLAG_CASE - 能够与 SORT_STRING 或 SORT_NATURAL 合并(OR 位运算),不区分大小写排序字符串。
范例
<?php
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
foreach ($fruits as $key => $val) {
echo "fruits[" . $key . "] = " . $val . "\n";
}
?>
以上例程会输出:
fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange
使用不区分大小写自然排序的 sort() 例子
<?php
$fruits = array(
"Orange1", "orange2", "Orange3", "orange20"
);
sort($fruits, SORT_NATURAL | SORT_FLAG_CASE);
foreach ($fruits as $key => $val) {
echo "fruits[" . $key . "] = " . $val . "\n";
}
?>
以上例程会输出:
fruits[0] = Orange1
fruits[1] = orange2
fruits[2] = Orange3
fruits[3] = orange20
fruits 排序得像 natcasesort() 的结果。
Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。
Note: 和大多数 PHP 排序函数一样,sort() 使用了 » Quicksort 实现的。
在对含有混合类型值的数组排序时要小心,因为 sort() 可能会产生不可预知的结果。
本函数对数组进行逆向排序(最高到最低)。
bool rsort ( array &$array [, int $sort_flags = SORT_REGULAR ] )
<?php
$fruits = array("lemon", "orange", "banana", "apple");
rsort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
以上例程输出为:
0 = orange
1 = lemon
2 = banana
3 = apple
fruits 被按照字母顺序逆向排序。
Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。
2. 根据键名对数组排序 ksort()和krsort()
对数组按照键名排序,保留键名到数据的关联。本函数主要用于关联数组。
bool ksort ( array &$array [, int $sort_flags = SORT_REGULAR ] )
<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
以上例程会输出:
a = orange
b = banana
c = apple
d = lemon
对数组按照键名逆向排序,保留键名到数据的关联。主要用于结合数组。
bool krsort ( array &$array [, int $sort_flags = SORT_REGULAR ] )
<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
krsort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
以上例程会输出:
d = lemon
c = apple
b = banana
a = orange
3. 根据元素的值对数组排序 asort()和arsort()
本函数对数组进行排序,数组的索引保持和单元的关联。主要用于对那些单元顺序很重要的结合数组进行排序。
bool asort ( array &$array [, int $sort_flags = SORT_REGULAR ] )
<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
asort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
以上例程会输出:
c = apple
b = banana
d = lemon
a = orange
fruits 被按照字母顺序排序,并且单元的索引关系不变。
本函数对数组进行排序,数组的索引保持和单元的关联。
主要用于对那些单元顺序很重要的结合数组进行排序。
bool arsort ( array &$array [, int $sort_flags = SORT_REGULAR ] )
<?php
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
arsort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
以上例程会输出:
a = orange
d = lemon
b = banana
c = apple
4. 根据“自然排序”法对数组排序 natcasesort()
natcasesort() 是 natsort() 函数的不区分大小写字母的版本。
本函数实现了一个和人们通常对字母数字字符串进行排序的方法一样的排序算法并保持原有键/值的关联,这被称为“自然排序”。
bool natcasesort ( array &$array )
<?php
$array1 = $array2 = array('IMG0.png', 'img12.png', 'img10.png', 'img2.png', 'img1.png', 'IMG3.png');
sort($array1);
echo "Standard sorting\n";
print_r($array1);
natcasesort($array2);
echo "\nNatural order sorting (case-insensitive)\n";
print_r($array2);
?>
以上例程会输出:
Standard sorting
Array
(
[0] => IMG0.png
[1] => IMG3.png
[2] => img1.png
[3] => img10.png
[4] => img12.png
[5] => img2.png
)
Natural order sorting (case-insensitive)
Array
(
[0] => IMG0.png
[4] => img1.png
[3] => img2.png
[5] => IMG3.png
[2] => img10.png
[1] => img12.png
)
5. 根据用户自定的规则对数组排序 usort()、uasort()和uksort()
本函数将用用户自定义的比较函数对一个数组中的值进行排序。如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数。
bool usort ( array &$array , callable $cmp_function )
Note:
如果两个成员比较结果相同,则它们在排序后的数组中的顺序未经定义。
Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。
<?php
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
?>
以上例程会输出:
0: 1
1: 2
2: 3
3: 5
4: 6
Note:
很明显在这个小例子中用 sort() 函数更合适。
<?php
function cmp($a, $b)
{
return strcmp($a["fruit"], $b["fruit"]);
}
$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";
usort($fruits, "cmp");
while (list($key, $value) = each($fruits)) {
echo "$fruits[$key]: " . $value["fruit"] . "\n";
}
?>
当排序多维数组时, a和 b 包含到数组第一个索引的引用。
以上例程会输出:
$fruits[0]: apples
$fruits[1]: grapes
$fruits[2]: lemons
本函数对数组排序并保持索引和单元之间的关联。
主要用于对那些单元顺序很重要的结合数组进行排序。比较函数是用户自定义的。
bool uasort ( array &$array , callable $cmp_function )
<?php
// Comparison function
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
// Array to be sorted
$array = array('a' => 4, 'b' => 8, 'c' => -1, 'd' => -9, 'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4);
print_r($array);
// Sort and print the resulting array
uasort($array, 'cmp');
print_r($array);
?>
以上例程会输出:
Array
(
[a] => 4
[b] => 8
[c] => -1
[d] => -9
[e] => 2
[f] => 5
[g] => 3
[h] => -4
)
Array
(
[d] => -9
[h] => -4
[c] => -1
[e] => 2
[g] => 3
[a] => 4
[f] => 5
[b] => 8
)
uksort() 函数将使用用户提供的比较函数对数组中的键名进行排序。如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数。
bool uksort ( array &$array , callable $cmp_function )
<?php
function cmp($a, $b)
{
$a = preg_replace('@^(a|an|the) @', '', $a);
$b = preg_replace('@^(a|an|the) @', '', $b);
return strcasecmp($a, $b);
}
$a = array("John" => 1, "the Earth" => 2, "an apple" => 3, "a banana" => 4);
uksort($a, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
?>
以上例程会输出:
an apple: 3
a banana: 4
the Earth: 2
John: 1
9.5.5 拆分、合并、分解和接合数组
1. 函数array_slice()
(PHP 4, PHP 5)
array_slice — 从数组中取出一段
array array_slice ( array $array , int $offset [, int $length = NULL [, bool $preserve_keys = false ]] )
array_slice() 返回根据 offset 和 length 参数所指定的 array 数组中的一段序列。
参数
array
输入的数组。
offset
如果 offset 非负,则序列将从 array 中的此偏移量开始。如果 offset 为负,则序列将从 array 中距离末端这么远的地方开始。
length
如果给出了 length 并且为正,则序列中将具有这么多的单元。如果给出了 length 并且为负,则序列将终止在距离数组末端这么远的地方。如果省略,则序列将从 offset 开始一直到 array 的末端。
preserve_keys
注意 array_slice() 默认会重新排序并重置数组的数字索引。你可以通过将 preserve_keys 设为 TRUE 来改变此行为。
范例
<?php
$input = array("a", "b", "c", "d", "e");
$output = array_slice($input, 2); // returns "c", "d", and "e"
$output = array_slice($input, -2, 1); // returns "d"
$output = array_slice($input, 0, 3); // returns "a", "b", and "c"
// note the differences in the array keys
print_r(array_slice($input, 2, -1));
print_r(array_slice($input, 2, -1, true));
?>
以上例程输出为:
Array
(
[0] => c
[1] => d
)
Array
(
[2] => c
[3] => d
)
2. 函数array_splice()
(PHP 4, PHP 5)
array_splice — 把数组中的一部分去掉并用其它值取代。
array array_splice ( array &$input , int $offset [, int $length = 0 [, mixed $replacement ]] )
把 input 数组中由 offset 和 length 指定的单元去掉,如果提供了 replacement 参数,则用其中的单元取代。
注意 input 中的数字键名不被保留。
参数
input
输入的数组。
offset
如果 offset 为正,则从 input 数组中该值指定的偏移量开始移除。如果 offset 为负,则从 input 末尾倒数该值指定的偏移量开始移除。
length
如果省略 length,则移除数组中从 offset 到结尾的所有部分。如果指定了 length 并且为正值,则移除这么多单元。如果指定了 length 并且为负值,则移除从 offset 到数组末尾倒数 length 为止中间所有的单元。小窍门:当给出了 replacement 时要移除从 offset 到数组末尾所有单元时,用 count($input) 作为 length。
replacement
如果给出了 replacement 数组,则被移除的单元被此数组中的单元替代。
如果 offset 和 length 的组合结果是不会移除任何值,则 replacement 数组中的单元将被插入到 offset 指定的位置。 注意替换数组中的键名不保留。
如果用来替换 replacement 只有一个单元,那么不需要给它加上 array(),除非该单元本身就是一个数组、一个对象或者 NULL。
<?php
$input = array("red", "green", "blue", "yellow");
array_splice($input, 2);
// $input is now array("red", "green")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, -1);
// $input is now array("red", "yellow")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 1, count($input), "orange");
// $input is now array("red", "orange")
$input = array("red", "green", "blue", "yellow");
array_splice($input, -1, 1, array("black", "maroon"));
// $input is now array("red", "green",
// "blue", "black", "maroon")
$input = array("red", "green", "blue", "yellow");
array_splice($input, 3, 0, "purple");
// $input is now array("red", "green",
// "blue", "purple", "yellow");
?>
以下表达式以同样方式修改了 $input:
<?php
array_push($input, $x, $y);
array_splice($input, count($input), 0, array($x, $y));
array_pop($input);
array_splice($input, -1);
array_shift($input);
array_splice($input, 0, 1);
array_unshift($input, $x, $y);
array_splice($input, 0, 0, array($x, $y));
$input[$x] = $y; // 对于键名和偏移量等值的数组
array_splice($input, $x, 1, $y);
?>
3. 函数array_combine()
(PHP 5)
array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值。
array array_combine ( array $keys , array $values )
返回一个 array,用来自 keys 数组的值作为键名,来自 values 数组的值作为相应的值。
参数
keys
将被作为新数组的键。非法的值将会被转换为字符串类型(string)。
values
将被作为数组的值。
错误/异常
如果作为keys的数组和作为values的数组的元素个数不一样,将会抛出一个警告错误(E_WARNING)。
<?php
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);
print_r($c);
?>
以上例程会输出:
Array
(
[green] => avocado
[red] => apple
[yellow] => banana
)
4. 函数array_merge()
(PHP 4, PHP 5)
array_merge — 合并一个或多个数组。
array array_merge ( array $array1 [, array $... ] )
array_merge() 将一个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。
如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。
<?php
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>
以上例程会输出:
Array
(
[color] => green
[0] => 2
[1] => 4
[2] => a
[3] => b
[shape] => trapezoid
[4] => 4
)
<?php
$array1 = array();
$array2 = array(1 => "data");
$result = array_merge($array1, $array2);
?>
别忘了数字键名将会被重新编号!
Array
(
[0] => data
)
如果你想完全保留原有数组并只想新的数组附加到后面,用 + 运算符:
<?php
$array1 = array(0 => 'zero_a', 2 => 'two_a', 3 => 'three_a');
$array2 = array(1 => 'one_b', 3 => 'three_b', 4 => 'four_b');
$result = $array1 + $array2;
var_dump($result);
?>
array(5) {
[0]=>
string(6) "zero_a"
[2]=>
string(5) "two_a"
[3]=>
string(7) "three_a"
[1]=>
string(5) "one_b"
[4]=>
string(6) "four_b"
}
5. 函数array_interset()
(PHP 4 >= 4.0.1, PHP 5)
array_intersect — 计算数组的交集
array array_intersect ( array $array1 , array $array2 [, array $ ... ] )
array_intersect() 返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意键名保留不变。
<?php
$array1 = array("a" => "green", "red", "blue");
$array2 = array("b" => "green", "yellow", "red");
$result = array_intersect($array1, $array2);
print_r($result);
?>
以上例程会输出:
Array
(
[a] => green
[0] => red
)
Note: 两个单元仅在 (string) $elem1 === (string) $elem2
时被认为是相同的。也就是说,当字符串的表达是一样的时候。
6. 函数array_diff()
(PHP 4 >= 4.0.1, PHP 5)
array_diff — 计算数组的差集
array array_diff ( array $array1 , array $array2 [, array $... ] )
对比返回在 array1 中但是不在 array2 及任何其它参数数组中的值。
返回值
返回一个数组,该数组包括了所有在 array1 中但是不在任何其它参数数组中的值。注意键名保留不变。
<?php
$array1 = array("a" => "green", "red", "blue", "red");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2);
print_r($result);
?>
在 $array1 中多次出现的值一样处理,输出结果为:
Array
(
[1] => blue
)
Note:
两个单元仅在 (string) $elem1 === (string) $elem2
时被认为是相同的。也就是说,当字符串的表达是一样的时候。
Note:
注意本函数只检查了多维数组中的一维。当然可以用 array_diff($array1[0], $array2[0]);
检查更深的维度。
9.5.6 数组与数据结构
1. 使用数组实现堆栈
堆栈是数据结构的一种实现形式,是一种非常广泛的存储数据的容器,遵循FIFO。在PHP,将数组当作一个栈,使用array_push()
和array_pop()
两个系统函数既可完成数据的进栈和出栈操作。
int array_push ( array &$array , mixed $var [, mixed $... ] )
array_push() 将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。和如下效果相同:
<?php
$array[] = $var;
?>
并对每个 var 重复以上动作。
Note: 如果用 array_push() 来给数组增加一个单元,还不如用 $array[] =
,因为这样没有调用函数的额外负担。
Note: 如果第一个参数不是数组,array_push() 将发出一条警告。这和 $var[]
的行为不同,后者会新建一个数组。
<?php
$stack = array("orange", "banana");
array_push($stack, "apple", "raspberry");
print_r($stack);
?>
以上例程会输出:
Array
(
[0] => orange
[1] => banana
[2] => apple
[3] => raspberry
)
mixed array_pop ( array &$array )
array_pop() 弹出并返回 array 数组的最后一个单元,并将数组 array 的长度减一。如果 array 为空(或者不是数组)将返回 NULL。 此外如果被调用不是一个数则会产生一个 Warning。
Note: 使用此函数后会重置(reset())array 指针。
<?php
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_pop($stack);
print_r($stack);
?>
经过此操作后,$stack
将只有 3 个单元:
Array
(
[0] => orange
[1] => banana
[2] => apple
)
并且 rasberry 将被赋给 $fruit
。
2. 使用数组实现队列
PHP中的数组处理函数还可以使用数组实现队列的操作,遵循LIFO的原则。array_shift()可以实现删除数组中的第一个元素,并返回被删除元素的值。
mixed array_shift ( array &$array )
array_shift() 将 array 的第一个单元移出并作为结果返回,将 array 的长度减一并将所有其它单元向前移动一位。所有的数字键名将改为从零开始计数,文字键名将不变。
Note: 使用此函数后会重置(reset())array 指针。
<?php
$stack = array("orange", "banana", "apple", "raspberry");
$fruit = array_shift($stack);
print_r($stack);
?>
以上例程会输出:
Array
(
[0] => banana
[1] => apple
[2] => raspberry
)
9.5.7 其他有用的数组处理函数
1. 函数array_rand()
从数组中取出一个或多个随机的单元,并返回随机条目的一个或多个键。
mixed array_rand ( array $input [, int $num_req = 1 ] )
返回值
如果你只取出一个,array_rand() 返回一个随机单元的键名,否则就返回一个包含随机键名的数组。这样你就可以随机从数组中取出键名和值。
<?php
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
$rand_keys = array_rand($input, 2);
echo $input[$rand_keys[0]] . "\n";
echo $input[$rand_keys[1]] . "\n";
?>
2. 函数shuffle()
本函数打乱(随机排列单元的顺序)一个数组。
bool shuffle ( array &$array )
<?php
$numbers = range(1, 20);
shuffle($numbers);
foreach ($numbers as $number) {
echo "$number ";
}
?>
3.函数array_sum()
number array_sum ( array $array )
array_sum() 将数组中的所有值的和以整数或浮点数的结果返回。
<?php
$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";
$b = array("a" => 1.2, "b" => 2.3, "c" => 3.4);
echo "sum(b) = " . array_sum($b) . "\n";
?>
以上例程会输出:
sum(a) = 20
sum(b) = 6.9
4. 函数range()
array range ( mixed $start , mixed $limit [, number $step = 1 ] )
建立一个包含指定范围单元的数组。
参数
start
序列的第一个值。
limit
序列结束于 limit 的值。
step
如果给出了 step 的值,它将被作为单元之间的步进值。step 应该为正值。如果未指定,step 则默认为 1。
<?php
// array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
foreach (range(0, 12) as $number) {
echo $number;
}
// The step parameter was introduced in 5.0.0
// array(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
foreach (range(0, 100, 10) as $number) {
echo $number;
}
// Use of character sequences introduced in 4.1.0
// array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
foreach (range('a', 'i') as $letter) {
echo $letter;
}
// array('c', 'b', 'a');
foreach (range('c', 'a') as $letter) {
echo $letter;
}
?>
9.6 操作PHP数组需要注意的一些细节
9.6.1 数组运算符号
和其他计算机编程语言不同,在PHP这种弱类型语言中,数组这种复合类型的数据也可以像整型一样通过一些运算符号就可以进行运算。例如“+”运算符的使用就可以直接合并两个数组,把右边运算元的数组附加到左边运算元的数组后面,但是重复的键值不会被覆盖。
<? php
$a=array("a"=>"Linux","b"=>"Apache");
$b=array("a"=>"PHP","b"=>"MySQL","c"=>"web");
$c=$a+$b;
echo "合并后的 \$a和\$b:\n";
print_r($c);
$c=$b+$a;
echo "合并后的 \$a和\$b:\n";
print_r($c);
?>
以上例子输出为:
合并后的 $a和$b:
Array (
[a] => Linux
[b] => Apache
[c] => web
)
合并后的 $a和$b:
Array (
[a] => PHP
[b] => MySQL
[c] => web
)
和前面介绍的array_merge()函数作用差不多,都是去合并两个数组,但有很大的区别。marray_merge()函数如果键名有重复,后面的覆盖前面的,而“+”运算符合并的两个数组键值相同不会被覆盖。另外,数组中的元素如果具有相同的键名和值,则也可以使用比较运算符号直接进行比较。
具体的数组运算符请详见书本。
9.6.2 删除数组中的元素操作
前面在介绍使用数组模拟队列和栈等数据结构时,用到了array_shift()和array_pop()两个函数,分别用于从数组前面和后面删除一个元素。但如果需要删除数组中任意位置的一个元素,就需要对数组用函数unset()进行操作。
(PHP 4, PHP 5, PHP 7)
unset — 释放给定的变量
void unset ( mixed $var [, mixed $... ] )
unset() 销毁指定的变量。
unset() 在函数中的行为会依赖于想要销毁的变量的类型而有所不同。
如果在函数中 unset() 一个全局变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。
<?php
function destroy_foo() {
global $foo;
unset($foo);
}
$foo = 'bar';
destroy_foo();
echo $foo;
?>
以上例程会输出:
bar
如果您想在函数中 unset() 一个全局变量,可使用 $GLOBALS
数组来实现:
<?php
function foo()
{
unset($GLOBALS['bar']);
}
$bar = "something";
foo();
?>
如果在函数中 unset() 一个通过引用传递的变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。
<?php
function foo(&$bar) {
unset($bar);
$bar = "blah";
}
$bar = 'something';
echo "$bar\n";
foo($bar);
echo "$bar\n";
?>
以上例程会输出:
Before unset: 1, after unset: 23
Before unset: 2, after unset: 23
Before unset: 3, after unset: 23
9.6.3 关于数组下标的注意事项
PHP中数组的类型只有包含整型和字符串型的小标。应该始终在用字符串表示的数组索引上加上引号,例如用$foo['bar']
而不是$foo[bar]
。但是$foo[bar]
错了吗?这样是错的,但可以正常运行。那为什么错了呢?原因是此代码中有一个未定义的常量bar而不是字符串’bar’,而PHP可能会在以后定义此常量。PHP自动将裸字符串转换成一个其值为该裸字符串的正常字符串。例如,如果没有常量定义为bar,PHP将把它替代为’bar’并使用之。
<?php
$array=array(1,2,3,4,5,6,7,8,9);
for($i=0;$i<count($array);$i++){
echo "<br>查看 $i:<br>";
echo "坏的:".$array['$i']."<br>";
echo "好的:".$array[$i]."<br>";
echo "坏的:{$array['$i']}<br>";
echo "好的:{$array[$i]}<br>";
}
?>
如果在数组下标中将变量加上了引号,系统将认为没有定义这个下标,所以不能解析。也就打印不出结果。