第三章 数组
- 数组是一个可以存储一组或一系列数值的变量
- 一个包含其他数组的数组称为多维数组。
- 关联数组允许使用更有意义的数据作为索引(也就是通常所说的数组下标)
1.数组 - 数组信息的整个集合可以作为一个单元进行移动
- 存储在数组中的值称为数组元素(value)
- 每个数组有一个相关的索引,也成为关键字(key),其实就是平时所称的数组下标;可以用它来访问元素。
- PHP允许间隔性的使用数字或字符串作为数组的索引。可以将数组的索引设置为传统的数字型,也可以将索引设置为任何所希望的索引,这样可以使得索引更有意义和有用。。
2.数字索引数组
- array()实际上是一个语言结构,而不是一个函数。
- range()函数
- 如果需要按升序排列的数字保存在一个数组中,可以使用range()函数自动创建数组。
- ranger()函数具有一个可选的第三个参数,这个参数允许设定 值之间 的步幅
- 想要访问一个变量的内容,可以直接使用其变量名称;如果该变量是一个数组,可以使用变量名称和关键字或索引的组合来访问其内容。
- 当将数组或其他变量嵌入双引号中的字符串时,如果不能正确解释它们,可以将它们放置在双引号之外?
- PHP可以动态调整数组的大小
3.使用不同索引的数组
- 在关联数组中,可以将每个变量值与任何关键字或索引关联起来。通俗来说就是每个变量值都可以给予其专有的数组下标。
- 创建数组的三种方法:
(1)最常见也是使用最广的方法。
$prices=array('Tires'=>100,'Oil'=>10,'Spark Plugs'=>4);
(2)下述代码的意思先创建只有一个元素的数组$prices,然后再向其中添加额外的两个元素。
```
$prices=array('Tires'=>100);
$price['Oil']=10;
$price['Spark Plugs']=4;
(3)该种方法虽然写法不同,但实际功能和上面是一样的
$prices['Tires']=100;
$prices['Oil']=10;
$prices['Spark Plugs']=4;
- 循环语句
- foreach语句
- 该语句是专门用来循环数组的。
- foreach语句
foreach($prices $key=>$value){
echo $key."-".$value."<br />";
}
- 意思是将\$prices数组中的索引(数组下标)保存在\$key中,同时将数组的元素值保存到$value中,然后循环打印。
- each()语句
- 该函数将放回数组的当前元素,并将下一个元素作为当前元素。
```
while($element=each($prices)){
echo $element['key'];
echo "-";
echo $element['value'];
echo "<br />";
}
- \$elemente是一个数组。当使用each()时,它将返回一个带有4个数值和4个指向数组位置的索引的数组;
- 位置key和0包含了当前元素的关键字,而位置value和1包含了当前元素的值。
- 所谓的4个数值和4个指向数组位置的索引如下图所示:
- ![](http://upload-images.jianshu.io/upload_images/4167376-f780d201f34d6bbc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- list()语句
- 函数list()可以用来将一个数组分解为一系列的值。
```
while(list($product,$price)=echo($prices)){
echo "$product-$price<br/>";
}
```
- list函数通常和each函数共同使用,先使用each()函数从\$prices数组中取出当前元素,并将其作为数组返回;然后再使用list()将从each()返回的数组中包含0、1两个元素变为两个名为\$product和\$price的新变量。
- list()函数的最大优点在于可以为新变量命名,使其更容易阅读。
**4.数组操作符**
- ![数组操作符](http://upload-images.jianshu.io/upload_images/4167376-96844b084cb40869.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 联合操作符是将\$b中的元素添加到\$a的末尾。如果\$b中的元素与\$a中的一些元素具有相同的索引(数组下标),他们将不会被添加,也就是说$a中的元素将不会被覆盖。
**5.多维数组**
- 常见的二维数组形式:
`$products=array(array('TIR','Tires',100),array('OIL','Oil',10),array('SPK','Spark Plugs',4));`
- 与一维数组一样,二维数组也可以自己命名列名称来代替一般的索引数字。
- 将所描述的内容保存到用它的名称命名的列中,会比将其保存到所谓的第一列中更容易记住;如上述代码也可以改为:
$products=array(array('Code'=>'TIR,'Description'=>'Tires''Price'=>100),
array('Code'=>'OIL','Description'=>'Oil','Price'=>10),
array('Code'=>'SPK','Description'=>'Spark Plugs', 'Price'=>4));
- 同样的也可以将`array('Code'=>'TIR,'Description'=>'Tires''Price'=>100),`前面的array进行自定义命名,*例如:*
```
$products=array('xxx'=>array('Code'=>'TIR','Description'=>'Tires','Price'=>100),
'yyy'=>array('Code'=>'OIL','Description'=>'Oil','Price'=>10),
'zzz'=>array('Code'=>'SPK','Description'=>'Spark Plugs', 'Price'=>4));
print_r ($products);
echo "<br /><br />".$products['zzz']['Description'];
- ![最后输出效果](http://upload-images.jianshu.io/upload_images/4167376-6627051761bdf3eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 三维数组
- 三维数组具有高、宽、深的概念;每个元素可以通过层、行和列进行引用;例如:
$categories=array(
array(array('CAR_TIR','Tires',100),array('CAR_OIL','Oil',10),array('CAR_SPK','Spark Plugs',4)),
array(array('VAN_TIR','Tires',120),array('VAN_OIL','Oil',12),array('VAN_SPK','Spark Plugs',5)),
array(array('TRK_TIR','Tires',150),array('TRK_OIL','Oil',15),array('TRK_SPK','Spark Plugs',6))
);
- ***大多数的实际问题在逻辑上只需要使用三维或更少维的数组结构就可以了***
**6.*数组排序**
- sort()函数
- 可以将数组按照升序进行排序
- 该函数是区分字母大小写的。所有大写字母都在小写字母前面,也就是说A<Z<a<z。
- 该函数第二个参数可选的;可以通过设定值来改变排序的行为:
- 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 位运算),不区分大小写排序字符串。
- 指定排序类型的功能是非常有用的。
- asort()函数与ksort()函数
- asort()函数就是根据数组的每个元素值(value)来进行排序;
- ksort()函数就是根据关键字(key)排序。
```
$prices=array('Tires'=>100,'Oil'=>10,'Spark Plugs'=>4);
asort($prices);
echo "按照元素值(value)排序:<br/>";
print_r($prices);
echo "<br/><br/>";
ksort($prices);
echo "按照关键字(key)排序:<br/>";
print_r($prices);
- ![](http://upload-images.jianshu.io/upload_images/4167376-6c1d1664e70d82e9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 反向排序
- 和sort()、asort()、ksort()虽然排序标准不同,但都是按照升序来排列;
- 与之相对的rsort()、arsort()、krsort()则是将数组按照降序进行排列。
$prices=array('Tires'=>100,'Oil'=>10,'Spark Plugs'=>4);
arsort($prices);
echo "按照元素值(value)排序:
";
print_r($prices);
echo "
";
krsort($prices);
echo "按照关键字(key)排序:
";
print_r($prices);
- ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/4167376-7e251cf15bd1c336.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**7.多维数组排序**
- *PHP是不能比较两个数组间大小的,因此需要使用函数usort()告诉PHP如何比较各个元素。*
$products=array(array('CIR','Tires',100),
array('AIL','Oil',10),
array('SPK','Spark Plugs',4));
function compare($x , $y){
if($x[1] == $y[1]){
return 0;
}else if( $x[1] < $y[1]){
return -1;
}else {
return 1;
}
}
usort($products,'compare');
print_r($products);
- ![按索引为1的变量:字母排序](http://upload-images.jianshu.io/upload_images/4167376-2f23d5efb4c94ce1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- \$x和\$y分别是\$products数组下的两个子数组,所以\$x[1]是X子数组下的索引为1的元素值,\$y[1]是y子数组下的索引为1的元素值,然后\$x[1]与\$y[1]比大小。
- ***如果想要对数字比较大小,则compare()函数则可以改为:***
$products=array(array('CIR','Tires',100),
array('AIL','Oil',10),
array('SPK','Spark Plugs',4));
function compare($x , $y){
if($x[2] == $y[2]){
return 0;
}else if( $x[2] < $y[2]){
return -1;
}else {
return 1;
}
}
usort($products,'compare');
print_r($products);```
-
- 如果想要按照降序进行排列:
$products=array(array('CIR','Tires',100),
array('AIL','Oil',10),
array('SPK','Spark Plugs',4));
function compare($x , $y){
if($x[2] == $y[2]){
return 0;
}else if( $x[2] < $y[2]){
return 1;
}else {
return -1;
}
}
usort($products,'compare');
print_r($products);
-
- 如果是关联数组,既已经给子数组的索引值进行了自定义命名,则进行排序应该按照定义的命名来输入:
$products=array(array('Code'=>'TIR','Description'=>'Tires','Price'=>100),
array('Code'=>'OIL','Description'=>'Oil','Price'=>10),
array('Code'=>'SPK','Description'=>'Spark Plugs', 'Price'=>4));
function compare($x , $y){
if($x['Price'] == $y['Price']){
return 0;
}else if($x['Price'] < $y['Price']){
return -1;
}else {
return 1;
}
}
usort($products,'compare');
print_r($products);```
-
![按照自定义命名进行排序](http://upload-images.jianshu.io/upload_images/4167376-a0e8d525f1f35e2e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 与一维数组排序一样,多维数组如果需要对索引或值进行排序时:
- 对非数字索引数组的值进行排序时,可以使用uasort()函数;
- 对非数字索引数组的关键字进行排序时,可以使用uksort()函数。
**8.对数组进行重新排序**
- shuffle()函数
- 该函数将数组更元素进行随机排序。
- array_reverse()函数
- 将数组进行逆序排列
- 其所返回的是原数组修改后的副本,可以将其进行覆盖。
- array_push()函数
- 可以使用该函数将新元素添加到数组的末尾。
**9.文件载入数组**
-用PHP分离、格式化并显示内容
![原始txt抓取数据](http://upload-images.jianshu.io/upload_images/4167376-fa77cd081e4a3068.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
<?php
$orders=file("\$DOCUMENT_ROOT\/..\/orders\/orders.txt");
$numOrders=count($orders);
if($numOrders==0){
echo "<p><strong>No order pending.Please try again later.</strong></p>";
}
echo "<table border=\"1\">\r\n";
echo "<tr><th bgcolor=\"#ccccff\">Order Date</th>
<th bgcolor=\"#ccccff\">Tires</th>
<th bgcolor=\"#ccccff\">Oil</th>
<th bgcolor=\"#ccccff\">Spark Plugs</th>
<th bgcolor=\"#ccccff\">Total</th>
<th bgcolor=\"#ccccff\">Address</th>
</tr>";
for($i=0;$i<$numOrders;$i++){
$line=explode("\t",$orders[$i]);
$line[1]=intval($line[1]);
$line[2]=intval($line[2]);
$line[3]=intval($line[3]);
echo "<tr>
<td>".$line[0]."</td>
<td align=\"right\">".$line[1]."</td>
<td align=\"right\">".$line[2]."</td>
<td align=\"right\">".$line[3]."</td>
<td align=\"right\">".$line[4]."</td>
<td>".$line[5]."</td>
</tr>";
}
echo "</table>";
?>
-
![最终效果](http://upload-images.jianshu.io/upload_images/4167376-e4fde4bc3ec141ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- file()函数是把结果发送到一个数组中,文件中的每一行都将作为一个元素保存在该数组中。
- intval()函数可以将一个字符串转化成一个整数。
**10.其他数组操作**
- 浏览数组
- current()调用该数组将返回第一个元素。
- next()调用该函数是将指针迁移,然后再返回新的元素。
- 与each()函数的区别:
- each()函数是会先返回当前元素,然后再将指针前移;
- next()函数则是先将指针前移,然后返回新的元素。
- reset()和end()函数:
- reset()函数:返回指向数组的第一个元素的指针
- end()函数:将指针移到数组末尾。
- reset()和end()函数可以分别返回指向数组的第一个和最后一个元素。
- prev()函数:该函数与next()函数相反,是将当前指针往回移一个位置然后再返回新的当前元素。
- ```
$array=range(1,10,2);
$value = end( $array);
while($value){
echo "$value<br />";
$value = prev($array);
}
- ![逆序排列输出](http://upload-images.jianshu.io/upload_images/4167376-b50782961fb91fd8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- array_walk()函数
- bool array_walk(array arr, string func, [mixed userdata])
- array_walk()函数要求声明一个用户自己的函数。
- 简单来说就是:对数组中的每个元素应用用户自定义函数。
- array_walk()函数的参数:
- 第一个参数是arr,也就是需要处理的数组;
- 第二个参数是func,也就是用户自定义并将作用于数组中每个元素的函数;
- 第三个参数userdata是可选的,如果使用它,它可以作为一个参数传递给用户自己的函数。
- 例子:
$array=range(1,10);
function my_multiply($value,$key,$factor){
$value *= $factor;
print_r($value);
echo "|";
}
array_walk($array,'my_multiply',3);
-
![最终效果图](http://upload-images.jianshu.io/upload_images/4167376-7086ca5846279480.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 统计数组个数
- count()和sizeof()函数
- 两个函数的用途相同,都可以返回数组元素的个数。
- 两个函数都可以得到一个常规标量变量中的元素个数,如果传递给该函数的数组是空数组,则返回的数组元素个数为0。
- array_count_values()函数
- 该函数会统计每个特定的值在数组中出现过的次数。
- 该函数会统计数组(\$array)会返回一个关联数组(\$array1),该关联数组( \$array1 )中的关键字(\$array1的key)就是该数组(\$array)中的值(\$array的value);而该关联数组(\$array1)中关键字(\$array1的key)对应的数值(\$array1的value)则是关键字(\$array1的key)在该数组($array)中出现的次数(频率)。
- ```
$array=array(4,5,1,2,3,4,1,2,3,5,5,2,3,4);
$ac=array_count_values($array);
print_r($ac);
- ![该数组一共有3个4,3个5,2个1,3个2,和3个3](http://upload-images.jianshu.io/upload_images/4167376-f5a60af4e2920186.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- extract()函数
extact(array var_array[, int extract_type][, string prefix]);
- 该函数针对非数字索引数组,将数组转换成标量变量。
- 该函数是创建一系列的标量变量,这些变量的名称必须是数组中关键字的名称,而变量值则是数组中的值。
- $key 对应 $var;$value对应value。
$array=array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
extract($array);`
echo "$key1 | $key2 | $key3;"
-
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/4167376-75aaf0d75c17700d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- extract_type参数
- 该函数将告诉extract()函数如何处理***关键字***冲突。
- EXTR_OVERWRITE:如果有冲突,覆盖已有的变量。
- EXTR_SKIP:如果有冲突,不覆盖已有的变量。
- EXTR_PREFIX_SAME:如果有冲突,创建一个名为$prefix_key的变量。必须提供prefix参数。
- EXTR_PREFIX_ALL:给所有变量名加上前缀 prefix。必须提供prefix参数。
- EXTR_PREFIX_INVALID:使用指定的prefix在可能无效的变量名称钱加上前缀。必须提供prefix参数。
- EXTR_IF_EXISTS:只提取已经存在的变量(换句话说,就是用数组中的值覆盖已有的变量值)。这个参数对于数组到变量的转换石非常有用。
- 举个例子,以下情况非常有用:定义一些有效变量,然后从 $_REQUEST 中仅导入这些已定义的变量。
- EXTR_PREFIX_IF_EXISTS:只在不带前缀的变量已经存在的情况下,创建带有前缀的变量,其它的都不处理。
- EXTR_REFS:将变量作为引用提取。这有力地表明了导入的变量仍然引用了 var_array 参数的值。可以单独使用这个标志或者在 extract_type 中用 OR 与其它任何标志结合使用。
- 如果没有指定 extract_type,则被假定为 EXTR_OVERWRITE。
- ```
$key1="value4";`
$array=array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
extract($array,EXTR_PREFIX_ALL,'my');
echo "$my_key3|$my_key2|$key1|$my_key1";
- ![输出效果](http://upload-images.jianshu.io/upload_images/4167376-6c22c3f9c4b71638.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 以数字开始或包含空格的关键字将被跳过。
相关术语
1.语言结构和函数
(1)相关概念
- 语言结构:就是PHP语言的关键词,语言语法的一部分;它不可以被用户定义或者添加到语言扩展或者库中;它可以有也可以没有变量和返回值。
- 函数:由代码块组成的,可以复用。从源码的角度来说,也就是基于Zend引擎的基础来实现的,ext拓展库中的函数都是这样实现的。
(2)语言结构为什么比函数快
- 原因是在PHP中,函数都要先被PHP解析器(Zend引擎)分解成语言结构,所以有此可见,函数比语言结构多了一层解析器解析。这样就能比较好的理解,什么语言结构比函数快了。
(3)语言结构和函数的不同
语言结构比对应功能的函数快
语言结构在错误处理上比较鲁棒,由于是语言关键词,所以不具备再处理的环节
语言结构不能在配置项(php.ini)中禁用,函数则可以。
语言结构不能被用做回调函数
(4)语言结构列表
echo()
print()
die()
isset()
unset()
include(),注意,include_once()是函数
require(),注意,require_once()是函数
array()
list()
empty()
2.相对引用的位置问题
-
以引用图片为例,如果需要引用的程序和被引用的图片文件夹在平级则相对引用地址为
./images/1.jpg;
-
如果被引用的图片文件夹比引用的程序高一级,则相对引用地址为
../images/1.jpg;