noj/dot

通过点符号访问嵌套数组/对象

1.0.1 2021-10-04 11:12 UTC

This package is auto-updated.

Last update: 2024-09-04 18:24:04 UTC


README

Travis (.com) Latest Stable Version PHP Version Support License Total Downloads

Dot 允许您使用点符号获取和设置数组键或对象属性。

安装

composer require noj/dot

使用方法

首先构建一个新的 Dot 实例

$dot = new Dot($data);
$dot = Dot::from($data); // alternative

除非特别说明,所有示例都使用以下数据结构

$data = [
    'groups' => [
        (object)[
            'name' => 'group1',
            'items' => [
                [
                    'name' => 'item1',
                    'rare' => false,
                ],
                [
                    'name' => 'item3',
                    'rare' => true,
                ],
            ]
        ],
        (object)[
            'name' => 'group2',
            'items' => []
        ],
        (object)[
            'name' => 'group3',
            'items' => [
                [
                    'name' => 'item2',
                    'rare' => true,
                ],
            ]
        ],
    ]
];

方法

Dot::count(string $path): int

计算给定路径上的项目数量。

$dot->count('groups.0.items'); // 2
$dot->count('groups.*.items'); // 3

Dot::find(string $path, mixed $equals): Dot

查找通过给定真值测试的项目。

// find where property === value
$dot->find('groups.*.items.*.rare', true)->get();
/*
[
    ['name' => 'item3', 'rare' => true],
    ['name' => 'item2', 'rare' => true],
]
*/

// pass a callback for custom comparisons 
$dot->find('groups.*.items.*.name', function (string $name) {
    return $name === 'item2' || $name === 'item3';
})->get(); // returns same as above

// leave off the property to receive the whole item
$dot->find('groups.*.items.*', function (array $item) {
    return $item['name'] === 'item3' && $item['rare'];
})->get();

Dot::first(string $path, mixed $equals): Dot

查找通过给定真值测试的第一个项目。

$dot->first('groups.*.items.*.rare', true)->get(); // ['name' => 'item3', 'rare' => true]

$dot->first('groups.*.items.*', function (array $item) {
    return $item['rare'] === true;
})->get(); // same as above

Dot::get(null|int|string $path): mixed

使用点符号访问嵌套数组键和对象属性

$dot->get('groups.0.items.1.name'); // 'item3'

如果键或属性不存在,Dot 安全地返回 null

$dot->get('groups.3.items.1.name'); // null

您可以使用通配符 * 从多个路径中提取值

$dot->get('groups.*.items.*.name'); // ['item1', 'item3', 'item2']

$dot->get('groups.*.items'); /* [
    ['name' => 'item1', 'rare' => false],
    ['name' => 'item3', 'rare' => true],
    ['name' => 'item2', 'rare' => true],
] */

您可以使用 @ 前缀调用函数

$data = [
    'foo' => new class {
        public function getBar() {
            return ['bar' => 'value'];
        }
    }
];

(new Dot($data))->get('foo.@getBar.bar'); // 'value'

如果没有传递参数,它将返回底层数据

$dot->get() === $data; // true

Dot::has(string $path): bool

如果路径存在,则返回 true,否则返回 false

$dot->has('groups.0.items.1.name'); // true

Dot::push(string $path, mixed $value): Dot

将值推送到现有的数组中

$dot->push('groups.0.items', ['name' => 'another item']);

// supports wildcards
$dot->push('groups.*.items', ['name' => 'another item']);

Dot::set(array|string $paths, mixed $value): void

您可以使用相同的语法设置嵌套值

$dot->set('groups.2.items.0.name', 'a different name');
echo $data['groups'][2]->items[0]['name']; // 'a different name'

使用通配符 * 设置多个路径的嵌套键

$dot->set('groups.*.items.*.name', 'set all to same name');

如果键不存在,则会创建键

$dot->set('groups.0.items.2.name', 'a new item');

默认情况下,set 将缺失值初始化为空数组。要表示某个值应该是一个对象,请使用 -> 分隔符

$dot->set('groups.3->items.2.name', 'a new item');

您可以通过传递数组一次性设置多个值

$dot->set([
    'groups.0.items.1.name' => 'something',
    'groups.2.items.0.name' => 'something else',
]):

您可以调用一个方法

$data = [
    'foo' => new class {
        public $bars = [];
        public function addBar($bar) {
            $this->bar[] = $bar;
        }
    }
];

$dot = new Dot($data);
$dot->set('foo.@addBar', 'value');
echo $data['foo']->bars; // ['value']

或为数组中的每个值调用一个方法

$dot->set('foo.@addBar*', ['value1', 'value2']);
echo $data['foo']->bars; // ['value1', 'value2']

非链式版本

所有方法都有非链式版本的自身作为独立函数,即

// instead of
$filtered = \Noj\Dot\Dot::from($data)
    ->find('groups.*.items.*.rare', true)
    ->get();

// you can do
$filtered = \Noj\Dot\find($data, 'groups.*.items.*.rare', true');