常用数组函数
PHP提供了丰富的内置数组函数,这些函数可以大大简化数组操作,提高开发效率。掌握这些数组函数对于高效编写PHP代码至关重要。本章将介绍最常用和实用的数组函数,并通过实际示例展示它们的应用。
函数分类概览
PHP的数组函数可以分为以下几个主要类别:
- 数组创建和填充函数 - 创建和初始化数组
- 数组信息获取函数 - 获取数组的基本信息
- 数组搜索和过滤函数 - 查找和筛选数组元素
- 数组排序函数 - 对数组进行排序
- 数组合并和拆分函数 - 组合和分解数组
- 数组计算函数 - 进行数学计算
- 数组转换函数 - 改变数组的结构或类型
- 数组比较函数 - 比较数组的差异
数组创建和填充函数
1. range() - 创建包含指定范围元素的数组
// 创建数字序列
$numbers1 = range(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
$numbers2 = range(0, 100, 10); // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
$numbers3 = range(10, 1); // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
// 创建字母序列
$letters = range('a', 'z'); // ['a', 'b', 'c', ..., 'z']
$uppercase = range('A', 'Z'); // ['A', 'B', 'C', ..., 'Z']
// 实际应用:生成考试座位表
function generateSeatingChart($rows, $cols) {
$chart = [];
for ($i = 0; $i < $rows; $i++) {
$chart[$i] = range($i * $cols + 1, ($i + 1) * $cols);
}
return $chart;
}
$seatingChart = generateSeatingChart(3, 4);
print_r($seatingChart);
// [
// [0] => [1, 2, 3, 4],
// [1] => [5, 6, 7, 8],
// [2] => [9, 10, 11, 12]
// ]
2. array_fill() - 用值填充数组
// 填充索引数组
$zeros = array_fill(0, 5, 0); // [0, 0, 0, 0, 0]
$placeholders = array_fill(2, 3, 'X'); // [2 => 'X', 3 => 'X', 4 => 'X']
// 填充关联数组
$keys = ['name', 'age', 'email'];
$values = ['未知', 0, ''];
$userTemplate = array_fill_keys($keys, 'default');
// ['name' => 'default', 'age' => 'default', 'email' => 'default']
// 实际应用:初始化配置数组
function initConfig($sections) {
$config = [];
foreach ($sections as $section) {
$config[$section] = array_fill_keys([
'enabled', 'debug', 'timeout', 'retry_count'
], false);
}
return $config;
}
$config = initConfig(['database', 'cache', 'api']);
3. compact() - 从变量创建关联数组
$name = "张三";
$age = 25;
$email = "zhangsan@example.com";
// 从变量创建数组
$userInfo = compact("name", "age", "email");
// ['name' => '张三', 'age' => 25, 'email' => 'zhangsan@example.com']
// 动态创建
$variables = ['name', 'age', 'email'];
$userInfo = compact($variables);
// 实际应用:构建响应数据
function buildApiResponse($success, $message, $data = null) {
$response = compact('success', 'message');
if ($data !== null) {
$response['data'] = $data;
}
$response['timestamp'] = time();
return $response;
}
$response = buildApiResponse(true, "操作成功", ["id" => 1, "name" => "测试"]);
数组信息获取函数
1. count() / sizeof() - 计算数组元素数量
$fruits = ["apple", "banana", "orange", "grape"];
$count = count($fruits); // 4
// 多维数组计数
$matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
$totalElements = count($matrix, COUNT_RECURSIVE); // 9(递归计数)
$firstLevel = count($matrix); // 3(只计算第一级)
// 实际应用:验证表单数据
function validateRequiredFields($data, $requiredFields) {
$missing = [];
foreach ($requiredFields as $field) {
if (!isset($data[$field]) || empty($data[$field])) {
$missing[] = $field;
}
}
return $missing;
}
$data = ["name" => "张三", "email" => ""];
$missing = validateRequiredFields($data, ["name", "email", "age"]);
// 返回:["email", "age"]
2. array_key_exists() - 检查键是否存在
$user = ["name" => "张三", "age" => 25];
$hasName = array_key_exists("name", $user); // true
$hasEmail = array_key_exists("email", $user); // false
// 与isset()的区别
$user = ["name" => null];
$hasName = array_key_exists("name", $user); // true(键存在)
$isSetName = isset($user["name"]); // false(值为null)
// 实际应用:安全获取配置值
function getConfig($config, $key, $default = null) {
if (array_key_exists($key, $config)) {
return $config[$key];
}
return $default;
}
$config = ["host" => "localhost", "port" => 3306];
$host = getConfig($config, "host", "default_host");
$timeout = getConfig($config, "timeout", 30); // 使用默认值
3. in_array() - 检查值是否在数组中
$fruits = ["apple", "banana", "orange"];
$hasApple = in_array("apple", $fruits); // true
$hasGrape = in_array("grape", $fruits); // false
// 严格比较(类型也要匹配)
$numbers = [1, 2, 3];
$hasString1 = in_array("1", $numbers); // true(非严格比较)
$hasString1Strict = in_array("1", $numbers, true); // false(严格比较)
// 实际应用:权限检查
function hasPermission($userRole, $requiredRoles) {
return in_array($userRole, $requiredRoles);
}
$role = "editor";
$allowedRoles = ["admin", "editor", "moderator"];
if (hasPermission($role, $allowedRoles)) {
echo "有权限访问";
}
4. array_search() - 搜索值并返回键
$users = ["张三", "李四", "王五", "李四"];
$key = array_search("李四", $users); // 1(第一个匹配的键)
$key = array_search("赵六", $users); // false(未找到)
// 严格比较
$numbers = [1, "1", 2];
$key = array_search("1", $numbers, true); // 1(字符串"1"的键)
// 实际应用:查找用户ID
function findUserId($users, $username) {
foreach ($users as $id => $user) {
if ($user['username'] === $username) {
return $id;
}
}
return false;
}
$users = [
1 => ["username" => "admin", "name" => "管理员"],
2 => ["username" => "user", "name" => "用户"]
];
$userId = findUserId($users, "admin"); // 返回 1
数组搜索和过滤函数
1. array_filter() - 用回调函数过滤数组
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 过滤偶数
$evens = array_filter($numbers, function($num) {
return $num % 2 == 0;
});
// [2, 4, 6, 8, 10]
// 过滤关联数组
$users = [
["name" => "张三", "age" => 25, "status" => "active"],
["name" => "李四", "age" => 30, "status" => "inactive"],
["name" => "王五", "age" => 22, "status" => "active"]
];
$activeUsers = array_filter($users, function($user) {
return $user["status"] === "active";
});
// 实际应用:获取符合条件的记录
function getProductsByCategory($products, $category) {
return array_filter($products, function($product) use ($category) {
return $product["category"] === $category;
});
}
$products = [
["name" => "iPhone", "category" => "手机", "price" => 5999],
["name" => "MacBook", "category" => "笔记本", "price" => 14999],
["name" => "iPad", "category" => "平板", "price" => 3999]
];
$phones = getProductsByCategory($products, "手机");
2. array_map() - 对数组元素应用回调函数
$numbers = [1, 2, 3, 4, 5];
// 每个元素平方
$squared = array_map(function($num) {
return $num * $num;
}, $numbers);
// [1, 4, 9, 16, 25]
// 同时处理多个数组
$names = ["张三", "李四", "王五"];
$ages = [25, 30, 22];
$result = array_map(function($name, $age) {
return ["name" => $name, "age" => $age, "age_group" => $age < 30 ? "青年" : "中年"];
}, $names, $ages);
// 实际应用:数据格式化
function formatProducts($products) {
return array_map(function($product) {
return [
"name" => strtoupper($product["name"]),
"price" => "¥" . number_format($product["price"], 2),
"in_stock" => $product["stock"] > 0 ? "有货" : "缺货"
];
}, $products);
}
$products = [
["name" => "iPhone", "price" => 5999.5, "stock" => 50],
["name" => "MacBook", "price" => 14999.99, "stock" => 0]
];
$formatted = formatProducts($products);
3. array_reduce() - 用回调函数将数组缩减为单一值
$numbers = [1, 2, 3, 4, 5];
// 计算总和
$sum = array_reduce($numbers, function($carry, $item) {
return $carry + $item;
}, 0); // 15
// 计算乘积
$product = array_reduce($numbers, function($carry, $item) {
return $carry * $item;
}, 1); // 120
// 实际应用:统计计算
function calculateStats($records, $field) {
return array_reduce($records, function($carry, $record) use ($field) {
$carry['sum'] += $record[$field];
$carry['count']++;
$carry['max'] = max($carry['max'], $record[$field]);
$carry['min'] = min($carry['min'], $record[$field]);
return $carry;
}, ['sum' => 0, 'count' => 0, 'max' => PHP_INT_MIN, 'min' => PHP_INT_MAX]);
}
$sales = [
["amount" => 1000, "date" => "2023-01-01"],
["amount" => 1500, "date" => "2023-01-02"],
["amount" => 800, "date" => "2023-01-03"]
];
$stats = calculateStats($sales, "amount");
$average = $stats['sum'] / $stats['count'];
4. array_column() - 获取数组中指定列的值
$users = [
["id" => 1, "name" => "张三", "email" => "zhangsan@example.com"],
["id" => 2, "name" => "李四", "email" => "lisi@example.com"],
["id" => 3, "name" => "王五", "email" => "wangwu@example.com"]
];
// 提取name列
$names = array_column($users, "name");
// ["张三", "李四", "王五"]
// 提取name列,以id为键
$namesById = array_column($users, "name", "id");
// [1 => "张三", 2 => "李四", 3 => "王五"]
// 从对象数组中提取
$objects = [
(object)["id" => 1, "name" => "张三"],
(object)["id" => 2, "name" => "李四"]
];
$names = array_column($objects, "name", "id");
// 实际应用:数据提取和转换
function extractProductOptions($products) {
return array_column($products, "name", "id");
}
function calculateTotalByCategory($products) {
$categoryTotals = [];
foreach ($products as $product) {
$category = $product['category'];
if (!isset($categoryTotals[$category])) {
$categoryTotals[$category] = 0;
}
$categoryTotals[$category] += $product['price'];
}
return $categoryTotals;
}
数组排序函数
1. sort() / rsort() - 升序/降序排序索引数组
$numbers = [3, 1, 4, 1, 5, 9, 2, 6];
sort($numbers); // [1, 1, 2, 3, 4, 5, 6, 9] 升序
rsort($numbers); // [9, 6, 5, 4, 3, 2, 1, 1] 降序
// 字符串排序
$fruits = ["orange", "apple", "banana", "grape"];
sort($fruits); // ["apple", "banana", "grape", "orange"]
// 自然排序
$fileNames = ["file1.txt", "file10.txt", "file2.txt"];
sort($fileNames); // 标准排序:file1.txt, file10.txt, file2.txt
natsort($fileNames); // 自然排序:file1.txt, file2.txt, file10.txt
2. asort() / arsort() - 保持键值关联的排序
$scores = [
"张三" => 85,
"李四" => 92,
"王五" => 78,
"赵六" => 95
];
asort($scores); // 按值升序,保持键
// ["王五" => 78, "张三" => 85, "李四" => 92, "赵六" => 95]
arsort($scores); // 按值降序,保持键
// ["赵六" => 95, "李四" => 92, "张三" => 85, "王五" => 78]
// 实际应用:排行榜
function getRanking($scores, $order = 'desc') {
if ($order === 'desc') {
arsort($scores);
} else {
asort($scores);
}
return $scores;
}
$studentScores = ["张三" => 85, "李四" => 92, "王五" => 78];
$ranking = getRanking($studentScores);
3. ksort() / krsort() - 按键排序
$userData = [
"age" => 25,
"name" => "张三",
"email" => "zhangsan@example.com",
"phone" => "13800138000"
];
ksort($userData); // 按键升序
krsort($userData); // 按键降序
// 实际应用:配置排序
function sortConfigByKeys($config, $keyOrder) {
$sorted = [];
foreach ($keyOrder as $key) {
if (array_key_exists($key, $config)) {
$sorted[$key] = $config[$key];
}
}
// 添加剩余的键
foreach ($config as $key => $value) {
if (!array_key_exists($key, $sorted)) {
$sorted[$key] = $value;
}
}
return $sorted;
}
$config = ["host" => "localhost", "port" => 3306, "database" => "test", "timeout" => 30];
$keyOrder = ["host", "port", "database", "timeout"];
$sortedConfig = sortConfigByKeys($config, $keyOrder);
4. usort() - 使用自定义函数排序
$users = [
["name" => "张三", "age" => 25, "score" => 85],
["name" => "李四", "age" => 30, "score" => 92],
["name" => "王五", "age" => 22, "score" => 78],
["name" => "赵六", "age" => 28, "score" => 88]
];
// 按年龄排序
usort($users, function($a, $b) {
return $a["age"] - $b["age"];
});
// 按分数降序,年龄升序
usort($users, function($a, $b) {
if ($a["score"] === $b["score"]) {
return $a["age"] - $b["age"]; // 分数相同按年龄
}
return $b["score"] - $a["score"]; // 按分数降序
});
// 实际应用:复杂排序
function sortProducts($products, $criteria) {
usort($products, function($a, $b) use ($criteria) {
foreach ($criteria as $field => $order) {
$comparison = $a[$field] <=> $b[$field];
if ($comparison !== 0) {
return $order === 'desc' ? -$comparison : $comparison;
}
}
return 0;
});
return $products;
}
$products = [
["name" => "A", "price" => 100, "stock" => 10],
["name" => "B", "price" => 100, "stock" => 5],
["name" => "C", "price" => 80, "stock" => 15]
];
$sorted = sortProducts($products, ["price" => "desc", "stock" => "asc"]);
5. array_multisort() - 多维数组排序
$data = [
["name" => "张三", "score" => 85, "age" => 25],
["name" => "李四", "score" => 92, "age" => 30],
["name" => "王五", "score" => 78, "age" => 22],
["name" => "赵六", "score" => 85, "age" => 28]
];
// 提取排序列
$scores = array_column($data, "score");
$ages = array_column($data, "age");
// 先按分数降序,再按年龄升序
array_multisort($scores, SORT_DESC, $ages, SORT_ASC, $data);
// 实际应用:数据报表排序
function sortReportData($data, $sortColumns) {
$sortArrays = [];
foreach ($sortColumns as $column => $order) {
$sortArrays[] = array_column($data, $column);
$sortArrays[] = $order === 'desc' ? SORT_DESC : SORT_ASC;
}
$sortArrays[] = &$data;
array_multisort(...$sortArrays);
return $data;
}
$sales = [
["region" => "北京", "amount" => 1000, "date" => "2023-01-01"],
["region" => "上海", "amount" => 1500, "date" => "2023-01-02"],
["region" => "北京", "amount" => 1200, "date" => "2023-01-03"]
];
$sorted = sortReportData($sales, ["region" => "asc", "amount" => "desc"]);
数组合并和拆分函数
1. array_merge() - 合并数组
$array1 = [1, 2, 3];
$array2 = [4, 5, 6];
$merged = array_merge($array1, $array2); // [1, 2, 3, 4, 5, 6]
// 关联数组合并
$config1 = ["host" => "localhost", "port" => 3306];
$config2 = ["database" => "test", "timeout" => 30];
$config = array_merge($config1, $config2);
// ["host" => "localhost", "port" => 3306, "database" => "test", "timeout" => 30]
// 相同键的处理
$user1 = ["name" => "张三", "age" => 25];
$user2 = ["name" => "李四", "email" => "lisi@example.com"];
$merged = array_merge($user1, $user2);
// ["name" => "李四", "age" => 25, "email" => "lisi@example.com"](后面的覆盖前面的)
// 实际应用:配置合并
function mergeConfig($defaultConfig, $userConfig) {
return array_merge($defaultConfig, $userConfig);
}
$default = ["debug" => false, "timeout" => 30, "retry" => 3];
$user = ["debug" => true, "retry" => 5];
$config = mergeConfig($default, $user);
// ["debug" => true, "timeout" => 30, "retry" => 5]
2. array_slice() - 截取数组的一部分
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 获取前5个元素
$firstFive = array_slice($numbers, 0, 5); // [1, 2, 3, 4, 5]
// 获取第3到第6个元素
$middle = array_slice($numbers, 2, 4); // [3, 4, 5, 6]
// 最后3个元素
$lastThree = array_slice($numbers, -3); // [8, 9, 10]
// 保持键的关联
$assoc = ["a" => 1, "b" => 2, "c" => 3, "d" => 4];
$slice = array_slice($assoc, 1, 2, true); // ["b" => 2, "c" => 3]
// 实际应用:分页功能
function paginate($data, $page, $perPage) {
$offset = ($page - 1) * $perPage;
return array_slice($data, $offset, $perPage);
}
$items = range(1, 100);
$page1 = paginate($items, 1, 10); // [1-10]
$page2 = paginate($items, 2, 10); // [11-20]
3. array_splice() - 移除并替换数组的一部分
$numbers = [1, 2, 3, 4, 5, 6, 7, 8];
// 移除元素
$removed = array_splice($numbers, 2, 3); // 从索引2开始移除3个元素
// $numbers 变为 [1, 2, 6, 7, 8]
// $removed 为 [3, 4, 5]
// 替换元素
array_splice($numbers, 1, 2, [9, 10, 11]);
// $numbers 变为 [1, 9, 10, 11, 6, 7, 8]
// 实际应用:数组元素操作
function insertAfter(&$array, $search, $insert) {
$index = array_search($search, $array);
if ($index !== false) {
array_splice($array, $index + 1, 0, $insert);
return true;
}
return false;
}
$list = ["苹果", "香蕉", "橙子"];
insertAfter($list, "香蕉", ["葡萄", "草莓"]);
// ["苹果", "香蕉", "葡萄", "草莓", "橙子"]
4. array_chunk() - 将数组分割成块
$numbers = range(1, 10);
// 每个块3个元素
$chunks = array_chunk($numbers, 3);
// [
// [0] => [1, 2, 3],
// [1] => [4, 5, 6],
// [2] => [7, 8, 9],
// [3] => [10]
// ]
// 保持键的关联
$assoc = ["a" => 1, "b" => 2, "c" => 3, "d" => 4];
$chunks = array_chunk($assoc, 2, true);
// [
// [0] => ["a" => 1, "b" => 2],
// [1] => ["c" => 3, "d" => 4]
// ]
// 实际应用:批量处理
function processInBatches($items, $batchSize, $callback) {
$batches = array_chunk($items, $batchSize);
$results = [];
foreach ($batches as $batch) {
$results[] = $callback($batch);
}
return $results;
}
$emails = ["user1@test.com", "user2@test.com", /*...*/];
$results = processInBatches($emails, 100, function($batch) {
// 批量发送邮件
return sendEmails($batch);
});
数组计算函数
1. array_sum() - 计算数组元素和
$numbers = [1, 2, 3, 4, 5];
$sum = array_sum($numbers); // 15
// 计算特定字段的总和
$products = [
["name" => "A", "price" => 100, "quantity" => 2],
["name" => "B", "price" => 50, "quantity" => 3],
["name" => "C", "price" => 75, "quantity" => 1]
];
$totalValue = array_sum(array_column($products, "price")) * array_sum(array_column($products, "quantity"));
2. array_product() - 计算数组元素乘积
$numbers = [1, 2, 3, 4];
$product = array_product($numbers); // 24
// 计算阶乘
function factorial($n) {
return array_product(range(1, $n));
}
echo factorial(5); // 120
3. max() / min() - 找出最大值和最小值
$numbers = [3, 1, 4, 1, 5, 9, 2, 6];
$max = max($numbers); // 9
$min = min($numbers); // 1
// 关联数组
$scores = ["张三" => 85, "李四" => 92, "王五" => 78];
$highestScore = max($scores); // 92
$lowestScore = min($scores); // 78
数组转换函数
1. array_keys() / array_values() - 获取键和值
$user = ["name" => "张三", "age" => 25, "email" => "zhangsan@example.com"];
$keys = array_keys($user); // ["name", "age", "email"]
$values = array_values($user); // ["张三", 25, "zhangsan@example.com"]
// 获取特定值的键
$users = [
["id" => 1, "name" => "张三"],
["id" => 2, "name" => "李四"],
["id" => 3, "name" => "王五"]
];
$ids = array_column($users, "id"); // [1, 2, 3]
2. array_flip() - 交换键和值
$mapping = ["red" => "#FF0000", "green" => "#00FF00", "blue" => "#0000FF"];
$flipped = array_flip($mapping);
// ["#FF0000" => "red", "#00FF00" => "green", "#0000FF" => "blue"]
// 创建快速查找表
$statusMap = [1 => "待处理", 2 => "处理中", 3 => "已完成"];
$statusToId = array_flip($statusMap);
// ["待处理" => 1, "处理中" => 2, "已完成" => 3]
3. array_unique() - 移除重复值
$numbers = [1, 2, 2, 3, 3, 3, 4];
$unique = array_unique($numbers); // [1, 2, 3, 4]
// 关联数组去重
$users = [
["id" => 1, "email" => "test@test.com"],
["id" => 2, "email" => "test@test.com"], // 重复邮箱
["id" => 3, "email" => "another@test.com"]
];
$emails = array_unique(array_column($users, "email"));
数组比较函数
1. array_diff() - 计算数组的差集
$array1 = [1, 2, 3, 4, 5];
$array2 = [3, 4, 5, 6, 7];
$diff = array_diff($array1, $array2); // [1, 2](在array1中但不在array2中)
// 关联数组差集
$config1 = ["debug" => true, "timeout" => 30, "retry" => 3];
$config2 = ["debug" => false, "timeout" => 30];
$diff = array_diff_assoc($config1, $config2);
// ["debug" => true, "retry" => 3]
2. array_intersect() - 计算数组的交集
$array1 = [1, 2, 3, 4, 5];
$array2 = [3, 4, 5, 6, 7];
$intersect = array_intersect($array1, $array2); // [3, 4, 5]
// 实际应用:标签匹配
function findCommonTags($userTags, $requiredTags) {
return array_intersect($userTags, $requiredTags);
}
$userTags = ["php", "javascript", "mysql", "redis"];
$requiredTags = ["php", "mysql", "docker"];
$matched = findCommonTags($userTags, $requiredTags); // ["php", "mysql"]
实际应用示例
1. 完整的数据处理管道
<?php
class DataProcessor {
private $data = [];
public function loadData(array $data) {
$this->data = $data;
return $this;
}
// 过滤数据
public function filter(callable $callback) {
$this->data = array_filter($this->data, $callback);
return $this;
}
// 转换数据
public function map(callable $callback) {
$this->data = array_map($callback, $this->data);
return $this;
}
// 排序数据
public function sort(callable $callback) {
usort($this->data, $callback);
return $this;
}
// 分组数据
public function groupBy($key) {
$grouped = [];
foreach ($this->data as $item) {
$groupKey = is_callable($key) ? $key($item) : $item[$key];
$grouped[$groupKey][] = $item;
}
$this->data = $grouped;
return $this;
}
// 获取结果
public function get() {
return $this->data;
}
// 获取统计信息
public function getStats() {
return [
'count' => count($this->data),
'sum' => array_sum(array_column($this->data, 'amount')),
'avg' => $this->getAverage(),
'max' => max(array_column($this->data, 'amount')),
'min' => min(array_column($this->data, 'amount'))
];
}
private function getAverage() {
$amounts = array_column($this->data, 'amount');
return count($amounts) > 0 ? array_sum($amounts) / count($amounts) : 0;
}
}
// 使用示例
$sales = [
['id' => 1, 'product' => 'A', 'amount' => 100, 'region' => '北京'],
['id' => 2, 'product' => 'B', 'amount' => 150, 'region' => '上海'],
['id' => 3, 'product' => 'A', 'amount' => 80, 'region' => '北京'],
['id' => 4, 'product' => 'C', 'amount' => 200, 'region' => '广州'],
['id' => 5, 'product' => 'B', 'amount' => 120, 'region' => '上海']
];
// 数据处理管道
$result = (new DataProcessor())
->loadData($sales)
->filter(function($item) {
return $item['amount'] > 90; // 过滤金额大于90的记录
})
->map(function($item) {
return array_merge($item, [
'amount_with_tax' => $item['amount'] * 1.1,
'category' => $item['amount'] > 150 ? '高价值' : '中等价值'
]);
})
->sort(function($a, $b) {
return $b['amount'] - $a['amount']; // 按金额降序
})
->groupBy('region') // 按地区分组
->get();
echo "按地区分组的结果:\n";
print_r($result);
// 原始数据统计
$stats = (new DataProcessor())
->loadData($sales)
->getStats();
echo "\n销售统计:\n";
print_r($stats);
?>
2. 数组工具类
<?php
class ArrayHelper {
/**
* 深度合并数组
*/
public static function mergeDeep($array1, $array2) {
$merged = $array1;
foreach ($array2 as $key => $value) {
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
$merged[$key] = self::mergeDeep($merged[$key], $value);
} else {
$merged[$key] = $value;
}
}
return $merged;
}
/**
* 获取嵌套数组值
*/
public static function get($array, $key, $default = null) {
if (is_null($key)) {
return $array;
}
if (isset($array[$key])) {
return $array[$key];
}
foreach (explode('.', $key) as $segment) {
if (!is_array($array) || !array_key_exists($segment, $array)) {
return $default;
}
$array = $array[$segment];
}
return $array;
}
/**
* 设置嵌套数组值
*/
public static function set(&$array, $key, $value) {
$keys = explode('.', $key);
$current = &$array;
foreach ($keys as $i => $k) {
if (!isset($current[$k]) || !is_array($current[$k])) {
$current[$k] = [];
}
$current = &$current[$k];
}
$current = $value;
}
/**
* 多维数组排序
*/
public static function multiSort(&$array, $keys, $order = SORT_ASC) {
if (!is_array($array) || empty($array)) {
return;
}
$args = [];
foreach ($keys as $key) {
$args[] = array_column($array, $key);
}
$args[] = $order;
$args[] = &$array;
call_user_func_array('array_multisort', $args);
}
/**
* 数组分页
*/
public static function paginate($array, $page, $perPage) {
$total = count($array);
$offset = ($page - 1) * $perPage;
$items = array_slice($array, $offset, $perPage);
return [
'data' => $items,
'total' => $total,
'per_page' => $perPage,
'current_page' => $page,
'last_page' => ceil($total / $perPage)
];
}
/**
* 树形数组转换
*/
public static function toTree($array, $idKey = 'id', $parentKey = 'parent_id', $childrenKey = 'children') {
$tree = [];
$references = [];
// 第一遍:创建引用
foreach ($array as $item) {
$id = $item[$idKey];
$references[$id] = $item;
$references[$id][$childrenKey] = [];
}
// 第二遍:构建树
foreach ($array as $item) {
$id = $item[$idKey];
$parentId = $item[$parentKey] ?? null;
if ($parentId === null) {
$tree[$id] = &$references[$id];
} else {
if (isset($references[$parentId])) {
$references[$parentId][$childrenKey][$id] = &$references[$id];
}
}
}
return array_values($tree);
}
/**
* 验证数组键是否存在
*/
public static function hasAllKeys($array, $keys) {
foreach ($keys as $key) {
if (!array_key_exists($key, $array)) {
return false;
}
}
return true;
}
/**
* 获取数组中的随机元素
*/
public static function random($array, $count = 1) {
$shuffled = $array;
shuffle($shuffled);
if ($count === 1) {
return $shuffled[0] ?? null;
}
return array_slice($shuffled, 0, min($count, count($shuffled)));
}
}
// 使用示例
// 深度合并配置
$defaultConfig = [
'database' => [
'host' => 'localhost',
'port' => 3306,
'options' => [
'charset' => 'utf8'
]
],
'cache' => [
'enabled' => false
]
];
$userConfig = [
'database' => [
'host' => 'remote-host',
'options' => [
'timeout' => 30
]
],
'cache' => [
'enabled' => true,
'driver' => 'redis'
]
];
$mergedConfig = ArrayHelper::mergeDeep($defaultConfig, $userConfig);
// 获取嵌套值
$dbHost = ArrayHelper::get($mergedConfig, 'database.host'); // remote-host
$dbTimeout = ArrayHelper::get($mergedConfig, 'database.options.timeout', 10); // 30
// 构建树形结构
$categories = [
['id' => 1, 'parent_id' => null, 'name' => '电子产品'],
['id' => 2, 'parent_id' => 1, 'name' => '手机'],
['id' => 3, 'parent_id' => 1, 'name' => '电脑'],
['id' => 4, 'parent_id' => null, 'name' => '服装'],
['id' => 5, 'parent_id' => 4, 'name' => '男装'],
['id' => 6, 'parent_id' => 4, 'name' => '女装']
];
$tree = ArrayHelper::toTree($categories);
?>
常见错误和解决方案
1. 使用错误的函数类型
// 错误:对关联数组使用sort()
$user = ["name" => "张三", "age" => 25];
sort($user); // 会丢失键值关联
// 正确:使用asort()保持键值关联
asort($user); // ["age" => 25, "name" => "张三"]
2. 函数参数顺序错误
// 错误:array_slice参数顺序
$result = array_slice(5, $array, 2); // 错误
// 正确:array_slice(数组, 起始位置, 长度)
$result = array_slice($array, 5, 2);
3. 忘记重新索引
$array = [1, 2, 3, 4, 5];
unset($array[2]); // [1, 2, 4, 5],索引不连续
// 重新索引
$array = array_values($array); // [1, 2, 4, 5],索引连续
性能优化建议
1. 选择合适的函数
// 检查元素是否存在
// 对于大数组,isset()比in_array()更快
if (isset($array[$key])) { // O(1)
// ...
}
if (in_array($value, $array)) { // O(n)
// ...
}
2. 避免不必要的循环
// 不好的做法:多次循环
$ids = [];
foreach ($users as $user) {
$ids[] = $user['id'];
}
$emails = [];
foreach ($users as $user) {
$emails[] = $user['email'];
}
// 好的做法:一次循环获取多个字段
$ids = $emails = [];
foreach ($users as $user) {
$ids[] = $user['id'];
$emails[] = $user['email'];
}
// 更好的做法:使用array_column()
$ids = array_column($users, 'id');
$emails = array_column($users, 'email');
3. 使用引用避免复制
// 处理大数组时使用引用
foreach ($largeArray as &$item) {
$item['processed'] = true; // 直接修改原数组
}
unset($item); // 解除引用
练习题
基础练习
-
数组函数应用
// 创建一个包含学生信息的数组 // 使用各种函数进行数据操作: // - 过滤出年龄大于20的学生 // - 按成绩排序 // - 计算平均成绩 // - 提取所有学生姓名 -
数据处理
// 从用户提交的数据中: // - 移除重复值 // - 过滤空值 // - 验证必需字段 // - 格式化输出
进阶练习
-
复杂排序
// 实现一个多维数组排序函数 // 支持多字段排序 // 支持升序/降序 // 支持自定义排序规则 -
数组工具类
// 创建一个数组工具类 // 包含常用的数组操作方法 // 如:深度合并、嵌套访问、树形转换等
实战练习
-
数据分析工具
// 实现一个简单的数据分析工具 // 支持数据导入、清洗、分析 // 生成统计报告和图表数据 -
配置管理器
// 使用数组函数实现配置管理 // 支持配置合并、继承、验证 // 支持环境配置覆盖
总结
PHP的数组函数功能强大且丰富,掌握这些函数可以大大提高开发效率。通过本节的学习,你应该:
- 熟悉常用的数组函数及其用途
- 能够根据需求选择合适的函数
- 理解函数的性能特点
- 能够组合使用多个函数解决复杂问题
- 了解常见错误和优化技巧
在实际开发中,建议:
- 多查阅PHP官方文档了解函数详情
- 注意函数的参数和返回值类型
- 考虑性能影响,特别是处理大数组时
- 编写可读性强、易于维护的代码
数组函数是PHP开发的重要工具,熟练运用它们将让你的代码更加简洁、高效和优雅。