Laravel中使用带通配符的data_get()同时返回匹配项的键
解决Laravel中多通配符路径下生成目标响应结构的问题
场景说明
开发API代理时,需要转发请求到后端服务器,过滤响应后仅返回指定字段的子集给客户端。
原始响应数据
{ "images": [ { "id": 2360545, "src": "https://my_site.com/tester-300x300-1.png", "name": "tester.png" }, { "id": 2433529, "src": "https://my_site.com/background-01-1.png", "name": "background.png" } ] }
当前问题
使用data_get($data, 'images.*.name')能正确提取所有name值组成的数组:
[ 'tester.png', 'background.png' ]
但需要将这些值整理为数组嵌套对象的格式返回:
{ "images": [ { "name": "tester.png" }, { "name": "background.png" } ] }
尝试两种data_set写法均无法得到预期结果:
- 写法一:因
$response_to_client初始为空,无对应结构导致写入失败
$response_to_client = []; $names = data_get($data, 'images.*.name'); data_set($response_to_client,'images.*.name',$names);
- 写法二:生成的结构不符合要求,
name被处理为数组而非对象属性
$response_to_client = []; $names = data_get($data, 'images.*.name'); data_set($response_to_client,'images.name',$names);
返回结果:
{ "images": { "name": [ "tester.png", "background.png" ] } }
需要支持多通配符键路径的通用解决方案,Laravel原生辅助函数未提供直接返回通配符匹配项完整键路径的方法。
解决方案
方案1:自定义函数获取带键路径的匹配结果
针对多通配符场景,自定义函数遍历数据并提取匹配项的键路径与对应值:
function data_get_with_keys($data, $path) { $segments = explode('.', $path); $current = ['', $data]; // 初始键前缀为空,对应原始数据 $next = []; foreach ($segments as $segment) { foreach ($current as $keyPrefix => $value) { if ($segment === '*') { if (is_array($value)) { foreach ($value as $index => $item) { $newKey = $keyPrefix === '' ? (string)$index : "{$keyPrefix}.{$index}"; $next[$newKey] = $item; } } } else { if (isset($value[$segment])) { $newKey = $keyPrefix === '' ? $segment : "{$keyPrefix}.{$segment}"; $next[$newKey] = $value[$segment]; } } } $current = $next; $next = []; } return array_map(function ($key, $value) { return ['key' => $key, 'value' => $value]; }, array_keys($current), $current); }
使用该函数生成目标结构:
$response_to_client = []; $matchedItems = data_get_with_keys($data, 'images.*.name'); foreach ($matchedItems as $item) { data_set($response_to_client, $item['key'], $item['value']); }
执行后即可得到预期的嵌套对象数组结构。
方案2:直接遍历数组构建(适合明确结构场景)
如果数据结构固定,可直接遍历原始images数组生成目标结构,代码更简洁高效:
$response_to_client['images'] = array_map(function ($image) { return ['name' => $image['name']]; }, data_get($data, 'images', []));
此方案无需处理通配符,适合字段路径明确的场景;若需处理更复杂的多通配符路径(如a.*.b.*.c),则方案1更通用。
内容的提问来源于stack exchange,提问作者Meyer Auslander - Tst
相关产品推荐
相关产品推荐

