常用数组函数

PHP提供了丰富的内置数组函数,这些函数可以大大简化数组操作,提高开发效率。掌握这些数组函数对于高效编写PHP代码至关重要。本章将介绍最常用和实用的数组函数,并通过实际示例展示它们的应用。

函数分类概览

PHP的数组函数可以分为以下几个主要类别:

  1. 数组创建和填充函数 - 创建和初始化数组
  2. 数组信息获取函数 - 获取数组的基本信息
  3. 数组搜索和过滤函数 - 查找和筛选数组元素
  4. 数组排序函数 - 对数组进行排序
  5. 数组合并和拆分函数 - 组合和分解数组
  6. 数组计算函数 - 进行数学计算
  7. 数组转换函数 - 改变数组的结构或类型
  8. 数组比较函数 - 比较数组的差异

数组创建和填充函数

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);  // 解除引用

练习题

基础练习

  1. 数组函数应用

    // 创建一个包含学生信息的数组
    // 使用各种函数进行数据操作:
    // - 过滤出年龄大于20的学生
    // - 按成绩排序
    // - 计算平均成绩
    // - 提取所有学生姓名
    
  2. 数据处理

    // 从用户提交的数据中:
    // - 移除重复值
    // - 过滤空值
    // - 验证必需字段
    // - 格式化输出
    

进阶练习

  1. 复杂排序

    // 实现一个多维数组排序函数
    // 支持多字段排序
    // 支持升序/降序
    // 支持自定义排序规则
    
  2. 数组工具类

    // 创建一个数组工具类
    // 包含常用的数组操作方法
    // 如:深度合并、嵌套访问、树形转换等
    

实战练习

  1. 数据分析工具

    // 实现一个简单的数据分析工具
    // 支持数据导入、清洗、分析
    // 生成统计报告和图表数据
    
  2. 配置管理器

    // 使用数组函数实现配置管理
    // 支持配置合并、继承、验证
    // 支持环境配置覆盖
    

总结

PHP的数组函数功能强大且丰富,掌握这些函数可以大大提高开发效率。通过本节的学习,你应该:

  1. 熟悉常用的数组函数及其用途
  2. 能够根据需求选择合适的函数
  3. 理解函数的性能特点
  4. 能够组合使用多个函数解决复杂问题
  5. 了解常见错误和优化技巧

在实际开发中,建议:

  • 多查阅PHP官方文档了解函数详情
  • 注意函数的参数和返回值类型
  • 考虑性能影响,特别是处理大数组时
  • 编写可读性强、易于维护的代码

数组函数是PHP开发的重要工具,熟练运用它们将让你的代码更加简洁、高效和优雅。