一、代码
<?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(快速定位错误)
}