diff --git a/src/macros/output/Hyperf/Collection/Arr.php b/src/macros/output/Hyperf/Collection/Arr.php index d04d3778c..c32da9bb0 100644 --- a/src/macros/output/Hyperf/Collection/Arr.php +++ b/src/macros/output/Hyperf/Collection/Arr.php @@ -99,6 +99,14 @@ public static function integer(ArrayAccess|array $array, string|int|null $key, ? { } + /** + * Push an item into an array using "dot" notation. + * @return array + */ + public static function push(array $array, string|int|null $key, mixed ...$values) + { + } + /** * Get a string item from an array using "dot" notation. * @return string diff --git a/src/macros/src/ArrMixin.php b/src/macros/src/ArrMixin.php index 005b048df..4f331b84b 100644 --- a/src/macros/src/ArrMixin.php +++ b/src/macros/src/ArrMixin.php @@ -217,4 +217,31 @@ public function sortByMany() return $array; }; } + + public function push() + { + return function (array $array, string|int|null $key, mixed ...$values) { + if ($key === null) { + foreach ($values as $value) { + $array[] = $value; + } + return $array; + } + + $current = Arr::get($array, $key, []); + + if (!is_array($current)) { + throw new InvalidArgumentException( + sprintf('Array value for key [%s] must be an array, %s found.', $key, gettype($current)) + ); + } + + $merged = array_merge($current, $values); + + $result = $array; + Arr::set($result, $key, $merged); + + return $result; + }; + } } diff --git a/tests/Macros/ArrTest.php b/tests/Macros/ArrTest.php index 303f8b5ef..72d7fcd07 100644 --- a/tests/Macros/ArrTest.php +++ b/tests/Macros/ArrTest.php @@ -8,8 +8,12 @@ * @document https://github.com/friendsofhyperf/components/blob/main/README.md * @contact huangdijia@gmail.com */ +use FriendsOfHyperf\Macros\ArrMixin; use Hyperf\Collection\Arr; +// Register the mixin for tests +Arr::mixin(new ArrMixin()); + require_once __DIR__ . '/Stubs/Common.php'; test('test arrayable', function () { @@ -242,3 +246,27 @@ function ($a, $b) { $this->assertTrue(Arr::some(['foo', 2], fn ($value, $key) => is_string($value))); $this->assertTrue(Arr::some(['foo', 'bar'], fn ($value, $key) => is_string($value))); }); + +test('test push', function () { + $array = []; + + $array = Arr::push($array, 'office.furniture', 'Desk'); + $this->assertEquals(['Desk'], $array['office']['furniture']); + + $array = Arr::push($array, 'office.furniture', 'Chair', 'Lamp'); + $this->assertEquals(['Desk', 'Chair', 'Lamp'], $array['office']['furniture']); + + $array = []; + + $array = Arr::push($array, null, 'Chris', 'Nuno'); + $this->assertEquals(['Chris', 'Nuno'], $array); + + $array = Arr::push($array, null, 'Taylor'); + $this->assertEquals(['Chris', 'Nuno', 'Taylor'], $array); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Array value for key [foo.bar] must be an array, boolean found.'); + + $array = ['foo' => ['bar' => false]]; + Arr::push($array, 'foo.bar', 'baz'); +});