Skip to content

Commit d2b61eb

Browse files
joshuarueswegnicolas-grekas
authored andcommitted
Add PHP 8.4 array_* polyfill
1 parent e85ab80 commit d2b61eb

File tree

5 files changed

+164
-0
lines changed

5 files changed

+164
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Polyfills are provided for:
6868
- the `Date*Exception/Error` classes introduced in PHP 8.3;
6969
- the `SQLite3Exception` class introduced in PHP 8.3;
7070
- the `mb_ucfirst` and `mb_lcfirst` functions introduced in PHP 8.4;
71+
- the `array_find`, `array_find_key`, `array_any` and `array_all` functions introduced in PHP 8.4;
7172

7273
It is strongly recommended to upgrade your PHP version and/or install the missing
7374
extensions whenever possible. This polyfill should be used only when there is no

src/Php84/Php84.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,48 @@ public static function mb_lcfirst(string $string, ?string $encoding = null): str
6363

6464
return $firstChar . mb_substr($string, 1, null, $encoding);
6565
}
66+
67+
public static function array_find(array $array, callable $callback)
68+
{
69+
foreach ($array as $key => $value) {
70+
if ($callback($value, $key)) {
71+
return $value;
72+
}
73+
}
74+
75+
return null;
76+
}
77+
78+
public static function array_find_key(array $array, callable $callback)
79+
{
80+
foreach ($array as $key => $value) {
81+
if ($callback($value, $key)) {
82+
return $key;
83+
}
84+
}
85+
86+
return null;
87+
}
88+
89+
public static function array_any(array $array, callable $callback): bool
90+
{
91+
foreach ($array as $key => $value) {
92+
if ($callback($value, $key)) {
93+
return true;
94+
}
95+
}
96+
97+
return false;
98+
}
99+
100+
public static function array_all(array $array, callable $callback): bool
101+
{
102+
foreach ($array as $key => $value) {
103+
if (!$callback($value, $key)) {
104+
return false;
105+
}
106+
}
107+
108+
return true;
109+
}
66110
}

src/Php84/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Symfony Polyfill / Php84
44
This component provides features added to PHP 8.4 core:
55

66
- [`mb_ucfirst` and `mb_lcfirst`](https://wiki.php.net/rfc/mb_ucfirst)
7+
- [`array_find`, `array_find_key`, `array_any` and `array_all`](https://wiki.php.net/rfc/array_find)
78

89
More information can be found in the
910
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).

src/Php84/bootstrap.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,19 @@ function mb_ucfirst($string, ?string $encoding = null): string { return p\Php84:
2323
if (!function_exists('mb_lcfirst')) {
2424
function mb_lcfirst($string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); }
2525
}
26+
27+
if (!function_exists('array_find')) {
28+
function array_find(array $array, callable $callback) { return p\Php84::array_find($array, $callback); }
29+
}
30+
31+
if (!function_exists('array_find_key')) {
32+
function array_find_key(array $array, callable $callback) { return p\Php84::array_find_key($array, $callback); }
33+
}
34+
35+
if (!function_exists('array_any')) {
36+
function array_any(array $array, callable $callback): bool { return p\Php84::array_any($array, $callback); }
37+
}
38+
39+
if (!function_exists('array_all')) {
40+
function array_all(array $array, callable $callback): bool { return p\Php84::array_all($array, $callback); }
41+
}

tests/Php84/Php84Test.php

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,34 @@ public function testMbLcFirst(string $string, string $expected): void {
3030
$this->assertSame($expected, mb_lcfirst($string));
3131
}
3232

33+
/**
34+
* @dataProvider arrayFindDataProvider
35+
*/
36+
public function testArrayFind(array $array, callable $callback, $expected): void {
37+
$this->assertSame($expected, array_find($array, $callback));
38+
}
39+
40+
/**
41+
* @dataProvider arrayFindKeyDataProvider
42+
*/
43+
public function testArrayFindKey(array $array, callable $callback, $expected): void {
44+
$this->assertSame($expected, array_find_key($array, $callback));
45+
}
46+
47+
/**
48+
* @dataProvider arrayAnyDataProvider
49+
*/
50+
public function testArrayAny(array $array, callable $callback, bool $expected): void {
51+
$this->assertSame($expected, array_any($array, $callback));
52+
}
53+
54+
/**
55+
* @dataProvider arrayAllDataProvider
56+
*/
57+
public function testArrayAll(array $array, callable $callback, bool $expected): void {
58+
$this->assertSame($expected, array_all($array, $callback));
59+
}
60+
3361
public static function ucFirstDataProvider(): array {
3462
return [
3563
['', ''],
@@ -68,4 +96,78 @@ public static function lcFirstDataProvider(): array {
6896
["ß", "ß"],
6997
];
7098
}
99+
100+
public static function arrayFindDataProvider(): array {
101+
$callable = function ($value): bool {
102+
return strlen($value) > 2;
103+
};
104+
105+
$callableKey = function ($value, $key): bool {
106+
return is_numeric($key);
107+
};
108+
109+
return [
110+
[[], $callable, null],
111+
[['a', 'aa', 'aaa', 'aaaa'], $callable, 'aaa'],
112+
[['a', 'aa'], $callable, null],
113+
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, '123'],
114+
[['a' => '1', 'b' => '12', 'c' => '123', 3 => '1234'], $callableKey, '1234'],
115+
];
116+
}
117+
118+
public static function arrayFindKeyDataProvider(): array {
119+
$callable = function ($value): bool {
120+
return strlen($value) > 2;
121+
};
122+
123+
$callableKey = function ($value, $key): bool {
124+
return is_numeric($key);
125+
};
126+
127+
return [
128+
[[], $callable, null],
129+
[['a', 'aa', 'aaa', 'aaaa'], $callable, 2],
130+
[['a', 'aa'], $callable, null],
131+
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, 'c'],
132+
[['a' => '1', 'b' => '12', 'c' => '123', 3 => '1234'], $callableKey, 3],
133+
];
134+
}
135+
136+
public static function arrayAnyDataProvider(): array {
137+
$callable = function ($value): bool {
138+
return strlen($value) > 2;
139+
};
140+
141+
$callableKey = function ($value, $key): bool {
142+
return is_numeric($key);
143+
};
144+
145+
return [
146+
[[], $callable, false],
147+
[['a', 'aa', 'aaa', 'aaaa'], $callable, true],
148+
[['a', 'aa'], $callable, false],
149+
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, true],
150+
[['a' => '1', 'b' => '12', 'c' => '123', 3 => '1234'], $callableKey, true],
151+
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callableKey, false],
152+
];
153+
}
154+
155+
public static function arrayAllDataProvider(): array {
156+
$callable = function ($value): bool {
157+
return strlen($value) > 2;
158+
};
159+
160+
$callableKey = function ($value, $key): bool {
161+
return is_numeric($key);
162+
};
163+
164+
return [
165+
[[], $callable, true],
166+
[['a', 'aa', 'aaa', 'aaaa'], $callable, false],
167+
[['aaa', 'aaa'], $callable, true],
168+
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, false],
169+
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callableKey, false],
170+
[[1 => '1', 2 => '12', 3 => '123', 4 => '1234'], $callableKey, true],
171+
];
172+
}
71173
}

0 commit comments

Comments
 (0)