Laravel的数组操作之所以写起来顺手,很大程度上要归功于Illuminate\Support\Arr这个辅助类。它把日常开发中最常见的数组操作都封装成了语义明确的方法,配合点号语法可以轻松读写深层嵌套数组。本文围绕Arr类的核心方法展开,配合代码示例说明每个方法的适用场景,并聊聊如何在非Laravel项目中复用这套工具。

Arr类基础读写方法:get、set、has、forget
先看最常用的四个方法。原生PHP里想取一个可能不存在的深层值,得写一串isset判断,而Arr::get用点号路径一行搞定:
$data = [
'user' => [
'profile' => [
'name' => '张三'
]
]
];
// 原生写法需要层层判断
$name = isset($data['user']['profile']['name']) ? $data['user']['profile']['name'] : '默认名';
// Arr写法,键不存在时返回默认值
$name = Arr::get($data, 'user.profile.name', '默认名');第三个参数是默认值,不传时返回null。这个方法还支持数组形式的路径,比如Arr::get($data, ['user', 'profile', 'name']),在键名本身包含点号时特别有用。
Arr::set和Arr::forget是一对反向操作。set可以往深层写入值,中间层不存在会自动创建数组;forget则按点号路径删除指定层级的数据:
Arr::set($data, 'user.profile.age', 25); // 即使 user.profile 原本不存在也会自动补齐层级结构 Arr::forget($data, 'user.profile.age'); // 也可以批量删除:Arr::forget($data, ['user.profile.age', 'user.profile.name']);
Arr::has用于判断某个点号路径是否存在,注意它和Arr::exists的区别:has会递归深入嵌套数组,而exists只判断第一层键是否存在,等价于array_key_exists。很多人会把这两个方法搞混,实际使用时has支持的路径更灵活,exists性能更好,按需选择即可。
数据筛选与提取:only、except、pluck、where
处理接口返回或表单数据时,经常需要提取部分字段或剔除敏感字段。Arr::only和Arr::except正好对应这两个需求:
$user = ['id' => 1, 'name' => '张三', 'password' => 'xxx', 'email' => 'zhangsan@bbccb.com']; // 只取部分字段,常用于白名单过滤 $safe = Arr::only($user, ['id', 'name']); // 剔除敏感字段,常用于响应前清理数据 $safe = Arr::except($user, ['password']);
Arr::pluck是使用频率极高的方法,它从二维数组中提取某一列的值,还能指定第二个参数作为结果的键:
$users = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
];
$names = Arr::pluck($users, 'name'); // ['张三', '李四']
$idMap = Arr::pluck($users, 'name', 'id'); // [1 => '张三', 2 => '李四']相比原生的array_column,pluck支持点号路径提取更深层的字段,例如Arr::pluck($orders, 'user.name', 'id')可以直接取订单里嵌套的用户名,这一点array_column做不到。
条件筛选则交给Arr::where,它接收一个回调,返回通过筛选的元素并保留原有键名。如果想要不保留键名,可以在后面接一个array_values:
$numbers = [10, 20, 30, 40];
$filtered = Arr::where($numbers, function ($value, $key) {
return $value >= 20;
});
// [1 => 20, 2 => 30, 3 => 40]
$reindexed = array_values($filtered); // [20, 30, 40]结构转换:collapse、flatten、divide、dot
多维数组拍平是另一个高频需求。Arr::flatten把嵌套数组压成一维,第二个参数可限制递归深度;Arr::collapse则只把「数组的数组」合并成一个:
$nested = ['a', ['b', ['c']]]; Arr::flatten($nested); // ['a', 'b', 'c'] Arr::flatten($nested, 1); // ['a', 'b', ['c']] 只拍一层 Arr::collapse([[1, 2], [3, 4]]); // [1, 2, 3, 4]
Arr::dot和Arr::undot是一对有趣的工具。dot把多维数组展开成点号键名的一维数组,undot反向还原,在需要批量校验嵌套字段或缓存复杂数据结构时很实用:
$array = ['user' => ['name' => '张三', 'age' => 25]]; $dotted = Arr::dot($array); // ['user.name' => '张三', 'user.age' => 25] $restored = Arr::undot($dotted); // 还原为原始嵌套结构
其他几个值得记住的方法:Arr::first取第一个通过回调筛选的元素,找不到时返回默认值;Arr::random随机取若干个元素;Arr::shuffle打乱数组;Arr::sort按回调排序;Arr::prepend往数组头部插入元素并保留字符串键名。
在非Laravel项目中复用Arr类
这套工具并不依赖Laravel框架本身。如果项目用的是Composer,直接执行composer require illuminate/support或者更轻量的illuminate/collections就能引入。引入后记得先加载Composer的自动加载文件:
<?php require __DIR__ . '/vendor/autoload.php'; use Illuminate\Support\Arr; $host = Arr::get($_SERVER, 'HTTP_HOST', 'localhost'); echo $host;
还有一种做法是把GitHub上symfony阵营的一些独立数组工具包作为替代,比如symfony/var-exporter配合自定义封装,但如果团队已经熟悉Laravel的API风格,直接抽Arr类源码到自己项目里维护也是常见方案,这个类只有一个文件,依赖极少,迁移成本几乎为零。
使用时有几个细节容易踩坑。第一,Arr::get对值为null的键返回null,和键不存在时的表现一样,如果需要严格区分这两种情况,请改用Arr::has判断。第二,Arr::only返回的是新数组,不会修改原数组,链式操作时要记得接收返回值。第三,pluck在提取对象数组时会自动调用属性或getter,混用对象与数组时行为一致,这一点可以放心。
熟练掌握这套数组工具后,大部分嵌套数组的读写、过滤、转换代码都能压缩到一两行,可读性也远好于层层嵌套的三元表达式。建议把常用方法整理成速查表贴在手边,写代码时按场景直接套用,效率提升会非常明显。
PHP数组处理Laravel Arr辅助函数数组操作修改时间:2026-09-14 11:09:40