请开启 JavaScript
php5.5版本以下不支持 array_column方法,自定义 – 老迟笔记

php5.5版本以下不支持 array_column方法,自定义

一、代码

<?php
/**
 * 兼容 PHP 5.5 以下版本的 array_column 实现
 * 从二维数组中提取指定列的值,或根据指定键构建键值对数组
 *
 * @param array $array 待处理的二维数组(必须是索引数组或关联数组,元素需为数组类型)
 * @param int|string|null $columnKey 要提取的列名/索引(null 表示返回完整二维元素)
 * @param int|string|null $indexKey 作为返回数组键名的列名/索引(null 表示使用默认数字索引)
 * @throws InvalidArgumentException 当入参类型不合法时抛出异常(便于调试错误)
 */
if (!function_exists('array_column')) {
    function array_column($array, $columnKey, $indexKey = null) {
        // 1. 严格校验入参类型,避免后续逻辑异常
        // 校验 $array 必须是数组
        if (!is_array($array)) {
            throw new InvalidArgumentException(
                sprintf('First parameter must be an array, %s given', gettype($array))
            );
        }
        // 校验 $columnKey 合法类型(null、字符串、整数)
        if ($columnKey !== null && !is_string($columnKey) && !is_int($columnKey)) {
            throw new InvalidArgumentException(
                sprintf('Second parameter (columnKey) must be null, string or integer, %s given', gettype($columnKey))
            );
        }
        // 校验 $indexKey 合法类型(null、字符串、整数)
        if ($indexKey !== null && !is_string($indexKey) && !is_int($indexKey)) {
            throw new InvalidArgumentException(
                sprintf('Third parameter (indexKey) must be null, string or integer, %s given', gettype($indexKey))
            );
        }

        $returnArray = [];

        // 2. 遍历二维数组,处理每个元素
        foreach ($array as $value) {
            // 跳过非数组元素(避免触发 "Cannot use string offset as an array" 警告)
            if (!is_array($value)) {
                continue;
            }

            // 3. 处理索引键($indexKey):确定返回数组的键名
            $currentIndex = null;
            if ($indexKey !== null) {
                // 若 $indexKey 对应的键不存在,跳过当前元素
                if (!isset($value[$indexKey])) {
                    continue;
                }
                $currentIndex = $value[$indexKey];
            }

            // 4. 处理列值($columnKey):确定返回数组的值
            $currentValue = null;
            if ($columnKey === null) {
                // $columnKey 为 null:返回完整二维元素
                $currentValue = $value;
            } else {
                // $columnKey 不为 null:仅当键存在时才获取值,否则跳过
                if (!isset($value[$columnKey])) {
                    continue;
                }
                $currentValue = $value[$columnKey];
            }

            // 5. 填入返回数组(根据是否有 $indexKey 决定键名)
            if ($currentIndex !== null) {
                $returnArray[$currentIndex] = $currentValue;
            } else {
                $returnArray[] = $currentValue;
            }
        }
        return $returnArray;
    }
}

二、使用示例与效果验证

1、提取指定列(无索引键)
$users = [
    ['id' => 1, 'name' => '张三', 'age' => 20],
    ['id' => 2, 'name' => '李四', 'age' => 25],
    ['id' => 3, 'name' => '王五', 'age' => 30],
];

// 提取 "name" 列
$result = array_column($users, 'name');
// 输出:['张三', '李四', '王五'](与原生函数结果一致)
print_r($result);
2、提取指定列并指定索引键
$users = [
    ['id' => 1, 'name' => '张三', 'age' => 20],
    ['id' => 2, 'name' => '李四', 'age' => 25],
    ['id' => 3, 'name' => '王五', 'age' => 30],
];

// 以 "id" 为键,提取 "name" 列
$result = array_column($users, 'name', 'id');
// 输出:[1 => '张三', 2 => '李四', 3 => '王五'](与原生函数结果一致)
print_r($result);
3、返回完整二维元素(列键为 null)
$users = [
    ['id' => 1, 'name' => '张三', 'age' => 20],
    ['id' => 2, 'name' => '李四', 'age' => 25],
    ['id' => 3, 'name' => '王五', 'age' => 30],
];

// 以 "id" 为键,返回完整用户信息
$result = array_column($users, null, 'id');
// 输出:[
//     1 => ['id' => 1, 'name' => '张三', 'age' => 20],
//     2 => ['id' => 2, 'name' => '李四', 'age' => 25],
//     3 => ['id' => 3, 'name' => '王五', 'age' => 30]
// ](与原生函数结果一致)
print_r($result);
4、处理非法入参(触发异常)
$users = [
    ['id' => 1, 'name' => '张三', 'age' => 20],
    ['id' => 2, 'name' => '李四', 'age' => 25],
    ['id' => 3, 'name' => '王五', 'age' => 30],
];

// 传入非数组(如字符串),触发异常
try {
    array_column('not an array', 'name');
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
    // 输出:First parameter must be an array, string given(快速定位错误)
}