[关闭]
@Zjmainstay 2016-07-05T11:02:12.000000Z 字数 4299 阅读 1425

PHP数组

zjblog PHP 数组


本文对数组的使用做引导式分析,并结合案例,让你能够熟练地应用数组。

(1)按类型

> * 索引数组
> * 关联数组 

(2) 按层级

> * 一维数组
> * 多维数组

索引数组,以整数从0到n作为键值,自动递增

关联数组,可以是字符串或整数作为键值

一维数组,值中不包含数组的数组

多维数组,值还是数组的数组,可以嵌套多层

取值,直接键位取值或遍历取值

首先,要熟练使用数组,必须学会查看数组结构。
print_r 和 var_dump 函数都是很好展示数组结构的工具,使用时可能有时候看起来内容比较乱,此时可以在它调用之前加一个 echo '<pre>';,通过HTML的<pre>标签格式化内容,就比较好看了。

示例一:

  1. <?php
  2. $arr = array(1, 2, 3, 4, 5);
  3. print_r($arr);
  4. echo '<br />';
  5. var_dump($arr);
  6. echo '<br />';
  7. echo '<pre>';
  8. print_r($arr);
  9. echo '<br />';
  10. var_dump($arr);
  11. /*
  12. //Result
  13. Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 )
  14. array(5) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) }
  15. Array
  16. (
  17. [0] => 1
  18. [1] => 2
  19. [2] => 3
  20. [3] => 4
  21. [4] => 5
  22. )
  23. array(5) {
  24. [0]=>
  25. int(1)
  26. [1]=>
  27. int(2)
  28. [2]=>
  29. int(3)
  30. [3]=>
  31. int(4)
  32. [4]=>
  33. int(5)
  34. }
  35. */

使用var_dump可以比较清楚的看到数据类型,比如null 和 '' ,在使用print_r打印时,我们看到的结果都是一样的,而var_dump可以区分开来,所以,我建议使用var_dump。

示例二:

  1. <?php
  2. $arr = array(
  3. 'name' => 'Zjmainstay',
  4. 'house' => null,
  5. 'car' => '',
  6. 'job' => true,
  7. );
  8. echo '<pre>';
  9. print_r($arr);
  10. echo '<br />';
  11. var_dump($arr);
  12. /*
  13. //Result
  14. Array
  15. (
  16. [name] => Zjmainstay
  17. [house] =>
  18. [car] =>
  19. [job] => 1
  20. )
  21. array(4) {
  22. ["name"]=>
  23. string(10) "Zjmainstay"
  24. ["house"]=>
  25. NULL
  26. ["car"]=>
  27. string(0) ""
  28. ["job"]=>
  29. bool(true)
  30. }
  31. */

上面举例都是一维数组的,现在我们就来看看这些一维数组的取值。
我们就以

  1. $arr = array(
  2. 'name' => 'Zjmainstay',
  3. 'house' => null,
  4. 'car' => '',
  5. 'job' => true,
  6. );

为例,这里,我要取到name,有2种方式:
1. 直接通过键名取值
直接取值是最合理的取值方式,我们在这里就叫它“所见即所得”,数组取值本来就是通过结构分析,取值,看到什么拿什么。

  1. echo $arr['name'];
  2. //Result: Zjmainstay
  1. 遍历并比较键名取值
    遍历并比较键名取值常常会有一个误区,曾经有好几个新手朋友问过我类似的问题,我也无法确定他们是受哪个文章或者哪本书祸害的,简直是不可理喻。我们这里简单演示一下这段令人发指的代码:

示例三:

  1. <?php
  2. $arr = array(
  3. 'name' => 'Zjmainstay',
  4. 'age' => 24,
  5. 'job' => 'PHP工程师',
  6. );
  7. //期望结果:
  8. //我的名字叫Zjmainstay,24岁,是一名PHP工程师。
  9. foreach($arr as $key => $value) {
  10. if($key == 'name') {
  11. echo "我的名字叫{$value},";
  12. } else if($key == 'age') {
  13. echo "{$value}岁,";
  14. } else if($key == 'job') {
  15. echo "是一名{$value}。";
  16. }
  17. }
  18. //输出结果确实是:
  19. //我的名字叫Zjmainstay,24岁,是一名PHP工程师。
  20. //好像并没有什么问题,但是,这只不过是巧合,假如,我把数组打乱顺序了,再看看,我们得到什么
  21. echo '<br />';
  22. ksort($arr); //按键名顺序排序
  23. var_dump($arr);
  24. echo '<br />';
  25. foreach($arr as $key => $value) {
  26. if($key == 'name') {
  27. echo "我的名字叫{$value},";
  28. } else if($key == 'age') {
  29. echo "{$key}岁,";
  30. } else if($key == 'job') {
  31. echo "是一名{$value}。";
  32. }
  33. }
  34. /*
  35. 正确结果:我的名字叫Zjmainstay,24岁,是一名PHP工程师。
  36. 新排序数组:array(3) { ["age"]=> int(24) ["job"]=> string(12) "PHP工程师" ["name"]=> string(10) "Zjmainstay" }
  37. 新数组结果:24岁,是一名PHP工程师。我的名字叫Zjmainstay,
  38. */

看到新数组的结果,是否瞬间凌乱?问题出在哪里?

foreach遍历的时候,从第一个到最后一个,然后新数组第一个是age,那它在if判断中就会匹配到$key == 'age'的分支,然后,输出了相应的结果,所以,结果就错了。

因此,这里,正确的做法就是,直接,所见即所得,直接输出:

  1. echo "我的名字叫{$arr['name']},{$arr['age']}岁,是一名{$arr['job']}。";

那么,是不是不能用遍历比较键名了?
答案是否定的。
只有在不考虑排序的情况下,才能使用遍历比较键名的方式做处理,否则可能会因为排序错乱而导致不可预知的结果。

示例四:

  1. <?php
  2. $arr = array(
  3. 'name' => 'Zjmainstay',
  4. 'age' => 24,
  5. 'job' => 'PHP工程师',
  6. );
  7. //我需要输出键值对,并且把工作的PHP改成小写显示
  8. foreach($arr as $key => $value) {
  9. if($key == 'job') {
  10. $value = strtolower($value);
  11. }
  12. echo "{$key} : {$value} <br />";
  13. }
  14. /*
  15. //Result
  16. name : Zjmainstay
  17. age : 24
  18. job : php工程师
  19. */

总结

对于一维数组,特别是关联数组,单一的值直接通过键值取值就行了。
遍历是对数组的一个顺序取值,循环一遍一个个取出来。


多维数组的取值其实跟一维数组一样,只不过它的值又是一个数组,需要再遍历一遍而已。我们可以通过打印结构,一层层观察定位到我们需要找的值。
示例五:

  1. <?php
  2. //常见配置文件格式
  3. $arr = array(
  4. 'mysql' => array(
  5. 'host' => 'localhost',
  6. 'user' => 'root',
  7. 'password' => 'root',
  8. 'port' => 3306,
  9. 'database' => 'test',
  10. ),
  11. 'site' => array(
  12. 'title' => 'Zjmainstay学习笔记',
  13. 'desc' => 'PHP,技术交流,技术积累,技术分享',
  14. ),
  15. );
  16. //我们要取站点标题和描述
  17. //只需要一层层取就行了
  18. echo "Title: {$arr['site']['title']} <br />";
  19. echo "Desc: {$arr['site']['desc']}";
  20. /*
  21. //Result
  22. Title: Zjmainstay学习笔记
  23. Desc: PHP,技术交流,技术积累,技术分享
  24. */

再有就是需要遍历输出数据的
示例六:

  1. <?php
  2. //常见数据结构
  3. $items = array(
  4. array(
  5. 'title' => 'Text1',
  6. 'url' => 'url1',
  7. 'pic' => array(
  8. 'pic_1_1.jpg',
  9. 'pic_1_2.jpg',
  10. 'pic_1_3.jpg',
  11. ),
  12. ),
  13. array(
  14. 'title' => 'Text2',
  15. 'url' => 'url2',
  16. 'pic' => array(
  17. 'pic_2_1.jpg',
  18. 'pic_2_2.jpg',
  19. 'pic_2_3.jpg',
  20. ),
  21. ),
  22. array(
  23. 'title' => 'Text3',
  24. 'url' => 'url3',
  25. 'pic' => array(
  26. 'pic_3_1.jpg',
  27. 'pic_3_2.jpg',
  28. 'pic_3_3.jpg',
  29. ),
  30. ),
  31. );
  32. foreach($items as $item) {
  33. echo "<div>\n";
  34. echo "Title: {$item['title']}\n";
  35. echo "Link: <a href='{$item['url']}' title='{$item['title']}'>{$item['title']}</a>\n";
  36. foreach($item['pic'] as $index => $pic) {
  37. echo "Pic{$index}: <img src='{$pic}' />\n";
  38. }
  39. echo "</div>\n";
  40. }
  41. /*
  42. //Result
  43. <div>
  44. Title: Text1
  45. Link: <a href='url1' title='Text1'>Text1</a>
  46. Pic0: <img src='pic_1_1.jpg' />
  47. Pic1: <img src='pic_1_2.jpg' />
  48. Pic2: <img src='pic_1_3.jpg' />
  49. </div>
  50. <div>
  51. Title: Text2
  52. Link: <a href='url2' title='Text2'>Text2</a>
  53. Pic0: <img src='pic_2_1.jpg' />
  54. Pic1: <img src='pic_2_2.jpg' />
  55. Pic2: <img src='pic_2_3.jpg' />
  56. </div>
  57. <div>
  58. Title: Text3
  59. Link: <a href='url3' title='Text3'>Text3</a>
  60. Pic0: <img src='pic_3_1.jpg' />
  61. Pic1: <img src='pic_3_2.jpg' />
  62. Pic2: <img src='pic_3_3.jpg' />
  63. </div>
  64. */

总结

数组并不复杂,当发现理不清的时候,借助var_dump函数查看结构,然后再取值即可。

总之,看懂数组结构,是能够正确取值的根本。

附:

数组有一系列的 array_ 前缀函数,还有一些排序之类函数,读者需逐个阅读一遍用法,尽可能熟悉每个函数,同时需要学习几个循环结构(for/foreach/while/do-while)。

PHP手册数组系列:http://php.net/manual/zh/book.array.php

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注