跳到主要内容

PHP 数组

本章将详细介绍 PHP 数组的创建、操作和常用函数。

数组概述

PHP 数组是一种有序映射,可以存储多个值。PHP 数组非常灵活,支持索引数组和关联数组。

索引数组

索引数组使用数字作为键:

<?php
// 创建索引数组
$colors = ["红", "绿", "蓝"];
$numbers = [1, 2, 3, 4, 5];

// 使用 array() 函数
$fruits = array("苹果", "香蕉", "橙子");

// 访问元素
echo $colors[0]; // 输出:红
echo $colors[1]; // 输出:绿

// 修改元素
$colors[0] = "红色";

// 添加元素
$colors[] = "黄"; // 添加到末尾
$colors[10] = "紫"; // 指定索引添加
?>

关联数组

关联数组使用字符串作为键:

<?php
// 创建关联数组
$person = [
"name" => "张三",
"age" => 25,
"city" => "北京"
];

// 使用 array() 函数
$user = array(
"username" => "admin",
"email" => "[email protected]"
);

// 访问元素
echo $person["name"]; // 输出:张三
echo $person["age"]; // 输出:25

// 修改元素
$person["age"] = 26;

// 添加元素
$person["job"] = "工程师";
?>

多维数组

数组中的元素可以是另一个数组:

<?php
// 二维数组
$users = [
["name" => "张三", "age" => 25],
["name" => "李四", "age" => 30],
["name" => "王五", "age" => 28]
];

// 访问元素
echo $users[0]["name"]; // 输出:张三
echo $users[1]["age"]; // 输出:30

// 三维数组
$data = [
"users" => [
["name" => "张三", "posts" => ["文章1", "文章2"]],
["name" => "李四", "posts" => ["文章3"]]
]
];

echo $data["users"][0]["posts"][0]; // 输出:文章1
?>

数组操作

添加元素

<?php
$arr = [1, 2, 3];

// 末尾添加
$arr[] = 4; // [1, 2, 3, 4]
array_push($arr, 5, 6); // [1, 2, 3, 4, 5, 6]

// 开头添加
array_unshift($arr, 0); // [0, 1, 2, 3, 4, 5, 6]

// 指定位置添加
array_splice($arr, 2, 0, "新元素");
?>

删除元素

<?php
$arr = [1, 2, 3, 4, 5];

// 删除末尾元素
$last = array_pop($arr); // $last = 5, $arr = [1, 2, 3, 4]

// 删除开头元素
$first = array_shift($arr); // $first = 1, $arr = [2, 3, 4]

// 删除指定元素
unset($arr[1]); // $arr = [0 => 2, 2 => 4](索引不连续)

// 删除指定位置元素
array_splice($arr, 1, 1); // 删除索引 1 开始的 1 个元素
?>

修改元素

<?php
$arr = [1, 2, 3, 4, 5];

// 直接修改
$arr[0] = 10;

// 批量修改
$arr = array_replace($arr, [0 => 100, 1 => 200]);

// 使用 array_splice 替换
array_splice($arr, 1, 2, [20, 30]); // 从索引 1 开始,替换 2 个元素
?>

查找元素

<?php
$arr = ["name" => "张三", "age" => 25, "city" => "北京"];

// 检查键是否存在
var_dump(array_key_exists("name", $arr)); // bool(true)
var_dump(isset($arr["name"])); // bool(true)
var_dump(isset($arr["job"])); // bool(false)

// 检查值是否存在
var_dump(in_array("张三", $arr)); // bool(true)
var_dump(in_array(25, $arr)); // bool(true)
var_dump(in_array("25", $arr)); // bool(true)(松散比较)
var_dump(in_array("25", $arr, true)); // bool(false)(严格比较)

// 查找值的键
$key = array_search(25, $arr); // "age"
$key = array_search("张三", $arr); // "name"

// 查找所有匹配的键
$arr = [1, 2, 3, 2, 4, 2];
$keys = array_keys($arr, 2); // [1, 3, 5]
?>

获取数组信息

<?php
$arr = [1, 2, 3, 4, 5];

// 数组长度
echo count($arr); // 5
echo sizeof($arr); // 5(count 的别名)

// 最大值、最小值、求和
echo max($arr); // 5
echo min($arr); // 1
echo array_sum($arr); // 15

// 获取所有键
$keys = array_keys($arr); // [0, 1, 2, 3, 4]

// 获取所有值
$values = array_values($arr); // [1, 2, 3, 4, 5]

// 检查是否为数组
var_dump(is_array($arr)); // bool(true)
?>

数组遍历

foreach 循环

<?php
$arr = ["name" => "张三", "age" => 25, "city" => "北京"];

// 遍历值
foreach ($arr as $value) {
echo "$value\n";
}

// 遍历键值对
foreach ($arr as $key => $value) {
echo "$key: $value\n";
}

// 修改原数组
$numbers = [1, 2, 3, 4, 5];
foreach ($numbers as &$num) {
$num *= 2;
}
unset($num); // 解除引用
print_r($numbers); // [2, 4, 6, 8, 10]
?>

for 循环

<?php
$arr = [1, 2, 3, 4, 5];

for ($i = 0; $i < count($arr); $i++) {
echo $arr[$i] . "\n";
}
?>

while 循环与 each()(已弃用)

<?php
// PHP 7.2 之前的方式(已弃用)
// while (list($key, $value) = each($arr)) {
// echo "$key: $value\n";
// }

// 推荐使用 foreach
?>

数组指针

<?php
$arr = [1, 2, 3, 4, 5];

// 获取当前元素
echo current($arr); // 1

// 移动指针并获取下一个元素
echo next($arr); // 2
echo next($arr); // 3

// 获取当前键
echo key($arr); // 2

// 移动指针到上一个元素
echo prev($arr); // 2

// 移动指针到开头
reset($arr);
echo current($arr); // 1

// 移动指针到末尾
end($arr);
echo current($arr); // 5
?>

数组排序

按值排序

<?php
$arr = [3, 1, 4, 1, 5, 9, 2, 6];

// 升序排序(重新索引)
sort($arr);
print_r($arr); // [1, 1, 2, 3, 4, 5, 6, 9]

// 降序排序(重新索引)
rsort($arr);
print_r($arr); // [9, 6, 5, 4, 3, 2, 1, 1]
?>

按值排序(保持键)

<?php
$arr = ["b" => 2, "a" => 1, "c" => 3];

// 升序排序(保持键)
asort($arr);
print_r($arr); // ["a" => 1, "b" => 2, "c" => 3]

// 降序排序(保持键)
arsort($arr);
print_r($arr); // ["c" => 3, "b" => 2, "a" => 1]
?>

按键排序

<?php
$arr = ["b" => 2, "a" => 1, "c" => 3];

// 按键升序排序
ksort($arr);
print_r($arr); // ["a" => 1, "b" => 2, "c" => 3]

// 按键降序排序
krsort($arr);
print_r($arr); // ["c" => 3, "b" => 2, "a" => 1]
?>

自定义排序

<?php
$users = [
["name" => "张三", "age" => 25],
["name" => "李四", "age" => 20],
["name" => "王五", "age" => 30]
];

// 按年龄升序排序
usort($users, function($a, $b) {
return $a["age"] <=> $b["age"];
});

// PHP 7.4+ 箭头函数
usort($users, fn($a, $b) => $a["age"] <=> $b["age"]);

// 按名字排序
usort($users, fn($a, $b) => strcmp($a["name"], $b["name"]));
?>

自然排序

<?php
$files = ["img1.png", "img10.png", "img2.png", "img20.png"];

// 普通排序
sort($files);
// ["img1.png", "img10.png", "img2.png", "img20.png"]

// 自然排序
natsort($files);
// ["img1.png", "img2.png", "img10.png", "img20.png"]

// 自然排序(不区分大小写)
natcasesort($files);
?>

数组函数

数组合并

<?php
$a = [1, 2, 3];
$b = [4, 5, 6];

// 合并数组
$merged = array_merge($a, $b); // [1, 2, 3, 4, 5, 6]

// 使用 + 运算符(后者不覆盖前者)
$c = $a + $b; // [1, 2, 3]($b 的键已存在,不覆盖)

// 关联数组合并
$x = ["a" => 1, "b" => 2];
$y = ["b" => 3, "c" => 4];
$z = array_merge($x, $y); // ["a" => 1, "b" => 3, "c" => 4]
?>

数组切片

<?php
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 切片(起始位置,长度)
$slice = array_slice($arr, 2, 3); // [3, 4, 5]

// 负数表示从末尾开始
$slice = array_slice($arr, -3); // [8, 9, 10]

// 保留键
$slice = array_slice($arr, 2, 3, true); // [2 => 3, 3 => 4, 4 => 5]
?>

数组分割

<?php
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 分割成多个数组
$chunks = array_chunk($arr, 3);
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

// 保留键
$chunks = array_chunk($arr, 3, true);
?>

数组填充

<?php
// 填充数组
$arr = array_fill(0, 5, "hello");
// ["hello", "hello", "hello", "hello", "hello"]

// 填充键值对
$arr = array_fill_keys(["a", "b", "c"], 0);
// ["a" => 0, "b" => 0, "c" => 0]
?>

数组去重

<?php
$arr = [1, 2, 2, 3, 3, 3, 4];

// 去重
$unique = array_unique($arr); // [1, 2, 3, 4]

// 严格模式
$arr = [1, "1", 2, 2.0];
$unique = array_unique($arr, SORT_REGULAR); // [1, 2]
?>

数组交集与差集

<?php
$a = [1, 2, 3, 4, 5];
$b = [3, 4, 5, 6, 7];

// 交集
$intersect = array_intersect($a, $b); // [2 => 3, 3 => 4, 4 => 5]

// 差集(在 $a 但不在 $b)
$diff = array_diff($a, $b); // [0 => 1, 1 => 2]

// 关联数组交集
$x = ["a" => 1, "b" => 2, "c" => 3];
$y = ["a" => 1, "b" => 3, "d" => 4];
$intersect = array_intersect_assoc($x, $y); // ["a" => 1]
?>

数组映射与过滤

<?php
$arr = [1, 2, 3, 4, 5];

// 映射
$squares = array_map(fn($n) => $n * $n, $arr);
// [1, 4, 9, 16, 25]

// 过滤
$evens = array_filter($arr, fn($n) => $n % 2 == 0);
// [1 => 2, 3 => 4]

// 归约
$sum = array_reduce($arr, fn($carry, $n) => $carry + $n, 0);
// 15

// 多数组映射
$a = [1, 2, 3];
$b = [4, 5, 6];
$sums = array_map(fn($x, $y) => $x + $y, $a, $b);
// [5, 7, 9]
?>

数组翻转

<?php
$arr = ["a" => 1, "b" => 2, "c" => 3];

// 键值互换
$flipped = array_flip($arr); // [1 => "a", 2 => "b", 3 => "c"]
?>

数组反转

<?php
$arr = [1, 2, 3, 4, 5];

// 反转(保持键)
$reversed = array_reverse($arr); // [5, 4, 3, 2, 1]

// 反转(重新索引)
$reversed = array_reverse($arr, false); // [5, 4, 3, 2, 1]
?>

数组随机

<?php
$arr = [1, 2, 3, 4, 5];

// 随机获取键
$key = array_rand($arr); // 随机键

// 随机获取多个键
$keys = array_rand($arr, 2); // 随机 2 个键

// 随机打乱
shuffle($arr); // 原地打乱
?>

数组判断

<?php
$arr = [1, 2, 3, 4, 5];

// 判断是否所有元素满足条件
$allPositive = array_every($arr, fn($n) => $n > 0); // PHP 8.4+

// 判断是否有元素满足条件
$hasEven = array_any($arr, fn($n) => $n % 2 == 0); // PHP 8.4+

// PHP 8.4 之前的替代方案
$allPositive = !in_array(false, array_map(fn($n) => $n > 0, $arr));
$hasEven = in_array(true, array_map(fn($n) => $n % 2 == 0, $arr));
?>

数组解构(PHP 7.1+)

<?php
// 索引数组解构
[$a, $b, $c] = [1, 2, 3];
echo $a; // 1
echo $b; // 2
echo $c; // 3

// 跳过元素
[, , $third] = [1, 2, 3];
echo $third; // 3

// 关联数组解构
["name" => $name, "age" => $age] = ["name" => "张三", "age" => 25];
echo $name; // 张三
echo $age; // 25
?>

小结

本章我们学习了:

  1. 数组的创建:索引数组、关联数组、多维数组
  2. 数组操作:添加、删除、修改、查找元素
  3. 数组遍历:foreach、for、数组指针
  4. 数组排序:sort、asort、ksort、usort
  5. 常用数组函数:合并、切片、过滤、映射等

下一章我们将学习字符串处理。