5.1 案例介绍
模拟无限分类,无限分类是我们在开发中经常用到的功能。我们可以使用它来制作网站的栏目分类
5.2 分析案例
我们通过使用数组模拟无限分类存储在数据库中的形式,初始化数组,然后结合前面学过的自定义函数和递归的方法来解决问题。
5.3 核心知识
数组初始化,数组遍历,数组操作,数组函数的应用,自定义函数,递归
5.4 知识讲解
5.4.1基础知识
数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,这个编号叫做下标,我们可以通过下标来区别这些元素。数组元素的个数有时也称之为数组的长度。
一般情况下,数组的元素类型必须相同,可以是前面讲过的各种基本数据类型。但当数组类型被指定为变体型时,它的各个元素就可以是不同的类型。
数组是一个可以存储一组或一系列数值的变量。
数组是一种基本的数据类型。
PHP中提供了丰富的数组处理函数和方法。
数组函数还可以实现堆栈和队列等数据结构
所谓的数组下标可以视为资料内容在此数组中的识别名称,通常被称为数组下标。当索引为数值时,也代表此资料内容在数组中的储存位置。数组中有几个索引值就被称为几维数组。
在PHP中有两种数组:索引数组和关联数组。
索引(indexed)数组的索引值是整数,以0开始。当通过位置来标识东西时用索引数组。
关联(associative)数组以字符串做为索引值,关联数组更像操作表。索引值为列名,用于访问列的数据。
5.4.2数组常用的赋值方式
由于 PHP 是属于弱类型数据,因此源代码中的数组并不需要经过特别的声明操作,直接将一组数值指定给某一数组元素即可。
一般情况下数组的赋值有两种方式:
直接赋值方式如:
$a[0]=‘spam@126.com’;
$a[1]=‘abuse@sohu.com’;
使用array函数 如:
$a=array(“spam@126.com “,”abuse@sohu.com”);
一维数组
数组中索引值(下标)只有一个的数组称为一维数组。在数组中这是最简单的,也是最常用的了。
直接赋值格式:
$数组变量名[索引值]=资料内容
其中索引值(下标)可以是一个字符串或一个整数。等价于整数(不以0开头)的字符串值被当作整数对待。因此,数组$array[3]与$array[‘3’]是引用相同的元素。但是$array[‘03’]引用的另外不同的元素。
实例1:
<?php
$a[0]=1;
$a[1]=2;
$a[2]=3;
$b[]=1;
$b[]=2;
$b[]=3;
$b[6]=4;
$b[]=5;
?>
实例2:
<?php
$a["name"]="zhang";
$a["sex"]="man";
$a["age"]=23;
$b["name"]="lisi";
$b[]="woman";
$b["age"]=28;
$b[8]=4;
$b[]=5;
?>
二维数组的声明
多维数组的声明方式及规则,与一维数组相同,例如:下面二维数组的声明片段:
这时数组中的资料内容如下:
如果以 array 语法声明,则如下程序片段:
5.4.3 foreach循环结构
foreach仅用于数组,有以下两种语法:
1.foreach (array_exp as $value)
…..statement
2.foreach (array_exp as $key => $value)
…..statement
第一种格式遍历给定的array_exp数组。每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步。第二种格式做同样的事,只除了当前单元的键值也会在每次循环中被赋给变量$key。
注意:当foreach开始执行时,数组内部的指针会自动指向第一个单元。此外注意foreach 所操作的是指定数组的一个拷贝,而不是该数组本身。
<?php
$a=array(10,20,30,40,50,60);
foreach($a as $k=>$v)
{
echo "$k => $v <br>";
}
?>
5.4.4使用list( ) 、each( )和reset()
array each (array array)
返回array数组中当前指针位置的键/值对并向前移动数组指针。键值对被返回为四个单元的数组,键名为 0,1,key 和 value。单元 0 和 key 包含有数组单元的键名,1 和 value 包含有数据。如果内部指针越过了数组的末端,则 each() 返回 FALSE。
each()经常和list( ) 结合使用来遍历数组。
void list (mixed ...)
它不是真正的函数,而是语言结构。list() 用一步操作给一组变量进行赋值。
注: list() 仅能用于数字索引的数组并假定数字索引从 0 开始。
在执行 each() 之后,数组指针将停留在数组中的下一个单元或者当碰到数组结尾时停留在最后一个单元。如果要再用 each 遍历数组,必须使用reset( )。
mixed reset(array array)
reset() 将 array 的内部指针倒回到第一个单元并返回第一个数组单元的值。
while(list($k,$v) = each($array))
{
if(is_array($v))
{
$x += add_weight1($v);
}
else
{
$x += $v;
}
}
5.4.5预定义数组
服务器变量:$_SERVER
环境变量:$_ENV
HTTP GET变量:$_GET
HTTP POST变量:$_POST
Request变量:$_REQUEST
HTTP文件上传变量:$_FILES
HTTP Cookies:$_COOKIE
Session变量:$_SESSION
Global变量:$GLOBALS
5.4.6数组的相关处理函数
对于数组指针的控制与相关运算处理操作,PHP 也提供了不少的内建函数可以利用。在本节之中仅就几个比较重要的常用函数,来作简单地介绍、说明。
count( )
用来计算数组中的所有元素个数,也就是说使用 count()函数会传回目标数组的长度值。
语法格式:count(数组名称);
<?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
?>
array_change_key_case( )
此函数仅支持 PHP4.2.0 之后版本,会将目标数组索引值中所有字符串索引的英文字母,转换为全大写或小写样式
语法格式:array_change_key_case(目标数组,型态常数)
其中型态常数值共有「CASE_UPPER」(转换为大写)与「CASE_LOWER」(转换为小写)两种
array_chunk()
此函数仅支持 PHP4.2.0 之后版本,会将目标数组的资料内容,以使用者指定的索引个数,分解为数个小型数组,并包含于原数组之中
语法格式:array_chunk(目标数组,索引个数,boolean preserve_key)
语法格式中的布尔参数 preserve_key 预设值为 false,通常予以省略。
例如下面的程序片段:
<?php$input_array = array(‘a’, ’b’, ’c’, ’d’, ’e’);print_r(array_chunk($input_array, 2));print_r(array_chunk($input_array, 2, true));
?>
array_count_values( )
用来计算目标数组中各值的出现次数
语法格式:array_count_values(目标数组)
此函数所传回的结果值,会以原数组的内容资料作为索引,以数组型态方式表现。
例如下面的程序片段:
<?php$array = array(1, "hello", 1, "world", "hello");print_r(array_count_values ($array));
?>
array_fill( )
此函数仅支持 PHP4.2.0 以后版本,让使用者可以用自定数值,填满目标数组中的指定索引区段。
语法格式:array_fill(起始索引位置, 区段大小, 指定字元)
其中起始索引位置与区段大小必须为 integer 型态数值,且区段大小指定不得为 0,否则 PHP 核心程序将传回错误讯息。
<?php$a = array_fill(5, 6, ’banana’);print_r($a);
?>
array_filter( )
仅支持 PHP4.0.6 之后版本,会利用使用者自定义的函数来过滤目标数组中的资料内容。如果自定义函数的传回数值为 TRUE,则保留该索引位置数值;反之传回数值为 FALSE 时,去除该位置数值。最后 array_filter 函数的执行结果,会以数组型态传回,并且不会影响原先的数组资料。
语法格式:array_filter(目标数组, 使用者自定义函数)
其它的回调函数:array_walk (), array_map()
<?phpfunction odd($var){ return($var % 2 == 1);}function even($var){ return($var % 2 == 0);}$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"));
?>
array_flip( )
仅支持 PHP4 之后版本,此函数的作用在于将目标数组中的索引与内容值,作反相的处理操作。也就是说反相后的数组会以原内容值作为索引,而索引作为资料内容。
语法格式:array_flip(目标数组)
<?php$trans = array_flip($trans);$original = strtr($str, $trans);
?>
5.4.7数组指针的控制函数
由于数组是由多个资料集合而成,所以当程序需要运算处理其中某个索引位置的资料内容时,会由数组之中内定的指针,指向目标资料,以提供程序作正确的读取。下面针对数组指针控制的相关函数,做简单的说明介绍:
next()、prev()、end()及 reset()这四个函数可以控制目前数组中的指针位置。
next()负责将指针向后移动;
prev()负责将指针向前移动;
end()会将指针指向数组中最后一个元素;
reset()函数会将目前指针无条件移至第一个索引位置。
语法格式:
——next(数组名称);
——prev(数组名称);
——end(数组名称);
——reset(数组名称);
key( )与 current( )
key()函数用来读取目前指针所指向资料的索引值,而current()则是取得目前指针位置的内容资料。
语法格式:
key(数组名称 );
current(数组名称 );
<?php$array = array( ’fruit1’ => ’apple’, ’fruit2’ => ’orange’, ’fruit3’ => ’grape’, ’fruit4’ => ’apple’, ’fruit5’ => ’apple’);// this cycle echoes all associative array// key where value equals "apple"while ($fruit_name = current($array)) { if ($fruit_name == ’apple’) { echo key($array).’<br />‘; } next($array);}
?>
<?php$transport = array(‘foot’, ’bike’, ’car’, ’plane’);$mode = current($transport); // $mode = ’foot’;$mode = next($transport); // $mode = ’bike’;$mode = current($transport); // $mode = ’bike’;$mode = prev($transport); // $mode = ’foot’;$mode = end($transport); // $mode = ’plane’;$mode = current($transport); // $mode = ’plane’;
?>
5.4.8获取数组的键名和值
array_values() :返回数组中的所有值。
该函数将忽略原始的键名,使用顺序的数字对数组重新索引。
array_keys():返回一个数组的所有键。
该函数返回一个包含数字或字符串的键名数组。
5.4.9数组的检索
对数组的检索,主要指对数组的键名或者元素值进行判断,从而确定某个数组元素的存在与否。
bool in_array(mixed $needle, array $haystack[, bool $strict]);
该函数应至少给定两个参数:要检索的元素$needle, 以及$haystack数组本身,可选的参数$strict指定是否严格按照数据类型进行判断,默认值为false. 返回值为布尔true或者false。
与其功能相同的还有函数array_search
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] );
参数全部相同,唯一的区别在这两个函数的返回值上,后者如果找到了needle则返回它的键,否则返回 FALSE。
5.4.10数组和变量之间的转换
PHP中提供了extract()函数进行数组和变量之间的转换。转换后,数组元素的键名与变量名,以及元素的值与变量的值保持着对应的关系。
从数组中提取变量:extract()函数用于将变量从数组中导入到当前的符号表中。
<?php
$info = array(
"user_id"=>2006001,
"user_name"=>"佟香玉",
"position"=>"项目经理"
);
extract($info);
//转换为下列变量:
$user_id = 2006001;
$user_name = "佟香玉";
$position = "项目经理";
?>
5.4.11数组与栈
数组也可以作为栈(数组栈)使用。栈底指向数组的第一个元素,栈顶指向数组中的最后一个元素。对栈的主要操作有两种:即入栈和出栈
在PHP中提供了array_push()和array_pop函数实现数组栈元素的压入和弹出。
array_push()函数
将一个或多个元素压入数组栈的末尾(入栈),返回入栈元素的个数。
array_pop()
函数将数组栈的最后一个元素弹出(出栈),并将该元素返回。
<?php
$stack = array("apple ", "banana");
$num = array_push($stack, "orange", "pear"); //入栈操作,返回2
//现在$stack的值为array("apple ", "banana", "orange", "pear");
$last = array_pop($stack); //出栈操作,返回“pear”
//现在$stack的值为array("apple ", "banana", "orange");
?>
5.4.12数组与队列
队列也可以以数组的形式表现。数组中的第一个元素作为队头,最后一个元素作为队尾在队列数组的队尾插入元素。
<?php
$queue = array("Tom", "Jack", "Kitty");
$queue[] = "Olivia"; //直接用初始化数组的方法
array_push($queue, "Alice"); //使用堆栈的手段
?>
array_shift()
从队列数组队头删除数据
该函数将数组的第一个元互移出并作为结果返回,同时,数组长度减1,并且其他元素向前移动一位。所有的数字键名将改为从零开始计数,文字键名将不改变。
<?php
$username = array ("Bad Boy", "Tom", "Jack", "Kitty", "Olivia");
$title = array_shift ($username); //返回“Bad Boy”
/*现在$username的值为
array(0=>"Tom",
1=>"Jack",
2=>"Kitty",
3=>"Olivia"
);
*/
?>
array_unshift()
在队列数组的开头插入一个或多个元素
该函数将返回成功插入的元素个数
<?php
$queue = array("x", "y");
array_unshift($queue, "a", array(1,2));
//现在$queue的值为:array("a", array(1,2), "x", "y");
?>
5.4.13数组的排序
通过元素的值对数组排序:
忽略键名的数组排序sort(), rsort(), usort()
保留键名的数组排序asort(), arsort(), uasort()
通过键名对数组排序:ksort(), krsort(), uksort()
自然排序法排序:natsort(), natcasesort()
5.4.14数组的计算
PHP中,对数组的计算是比较方便的。最简单的计算是求数组内部的所有元素之和。也可以把数组作为一个集合处理,对两个或多个数组进行合并,计算数组间的差集或交集等。
数组元素的求和:Array_sum() ;
仅支持 PHP4.0.4 之后版本,用来计算数组中所有元素值的总和。
语法格式: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";
?>
数组的合并:
Array_merge()和“+”(区别);
5.4.15其它数组函数
移除数组中重复的值:array_unique();
逆序返回数组:array_reverse();
5.5 知识运用
无限分类还存在于各种领域,其中最为常见的就是目录树,我们可以通过无限分类的方法来遍历计算机上真实存在的目录。