Skip to content

Commit

Permalink
feature #481 Add PHP 8.4 array_* polyfill (joshuaruesweg)
Browse files Browse the repository at this point in the history
This PR was squashed before being merged into the 1.x branch.

Discussion
----------

Add PHP 8.4 `array_*` polyfill

See: https://wiki.php.net/rfc/array_find

Commits
-------

d2b61eb Add PHP 8.4 `array_*` polyfill
  • Loading branch information
nicolas-grekas committed Jun 19, 2024
2 parents 2357270 + d2b61eb commit 0e4546d
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Polyfills are provided for:
- the `Date*Exception/Error` classes introduced in PHP 8.3;
- the `SQLite3Exception` class introduced in PHP 8.3;
- the `mb_ucfirst` and `mb_lcfirst` functions introduced in PHP 8.4;
- the `array_find`, `array_find_key`, `array_any` and `array_all` functions introduced in PHP 8.4;

It is strongly recommended to upgrade your PHP version and/or install the missing
extensions whenever possible. This polyfill should be used only when there is no
Expand Down
44 changes: 44 additions & 0 deletions src/Php84/Php84.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,48 @@ public static function mb_lcfirst(string $string, ?string $encoding = null): str

return $firstChar . mb_substr($string, 1, null, $encoding);
}

public static function array_find(array $array, callable $callback)
{
foreach ($array as $key => $value) {
if ($callback($value, $key)) {
return $value;
}
}

return null;
}

public static function array_find_key(array $array, callable $callback)
{
foreach ($array as $key => $value) {
if ($callback($value, $key)) {
return $key;
}
}

return null;
}

public static function array_any(array $array, callable $callback): bool
{
foreach ($array as $key => $value) {
if ($callback($value, $key)) {
return true;
}
}

return false;
}

public static function array_all(array $array, callable $callback): bool
{
foreach ($array as $key => $value) {
if (!$callback($value, $key)) {
return false;
}
}

return true;
}
}
1 change: 1 addition & 0 deletions src/Php84/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Symfony Polyfill / Php84
This component provides features added to PHP 8.4 core:

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

More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
Expand Down
16 changes: 16 additions & 0 deletions src/Php84/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,19 @@ function mb_ucfirst($string, ?string $encoding = null): string { return p\Php84:
if (!function_exists('mb_lcfirst')) {
function mb_lcfirst($string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); }
}

if (!function_exists('array_find')) {
function array_find(array $array, callable $callback) { return p\Php84::array_find($array, $callback); }
}

if (!function_exists('array_find_key')) {
function array_find_key(array $array, callable $callback) { return p\Php84::array_find_key($array, $callback); }
}

if (!function_exists('array_any')) {
function array_any(array $array, callable $callback): bool { return p\Php84::array_any($array, $callback); }
}

if (!function_exists('array_all')) {
function array_all(array $array, callable $callback): bool { return p\Php84::array_all($array, $callback); }
}
102 changes: 102 additions & 0 deletions tests/Php84/Php84Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,34 @@ public function testMbLcFirst(string $string, string $expected): void {
$this->assertSame($expected, mb_lcfirst($string));
}

/**
* @dataProvider arrayFindDataProvider
*/
public function testArrayFind(array $array, callable $callback, $expected): void {
$this->assertSame($expected, array_find($array, $callback));
}

/**
* @dataProvider arrayFindKeyDataProvider
*/
public function testArrayFindKey(array $array, callable $callback, $expected): void {
$this->assertSame($expected, array_find_key($array, $callback));
}

/**
* @dataProvider arrayAnyDataProvider
*/
public function testArrayAny(array $array, callable $callback, bool $expected): void {
$this->assertSame($expected, array_any($array, $callback));
}

/**
* @dataProvider arrayAllDataProvider
*/
public function testArrayAll(array $array, callable $callback, bool $expected): void {
$this->assertSame($expected, array_all($array, $callback));
}

public static function ucFirstDataProvider(): array {
return [
['', ''],
Expand Down Expand Up @@ -68,4 +96,78 @@ public static function lcFirstDataProvider(): array {
["ß", "ß"],
];
}

public static function arrayFindDataProvider(): array {
$callable = function ($value): bool {
return strlen($value) > 2;
};

$callableKey = function ($value, $key): bool {
return is_numeric($key);
};

return [
[[], $callable, null],
[['a', 'aa', 'aaa', 'aaaa'], $callable, 'aaa'],
[['a', 'aa'], $callable, null],
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, '123'],
[['a' => '1', 'b' => '12', 'c' => '123', 3 => '1234'], $callableKey, '1234'],
];
}

public static function arrayFindKeyDataProvider(): array {
$callable = function ($value): bool {
return strlen($value) > 2;
};

$callableKey = function ($value, $key): bool {
return is_numeric($key);
};

return [
[[], $callable, null],
[['a', 'aa', 'aaa', 'aaaa'], $callable, 2],
[['a', 'aa'], $callable, null],
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, 'c'],
[['a' => '1', 'b' => '12', 'c' => '123', 3 => '1234'], $callableKey, 3],
];
}

public static function arrayAnyDataProvider(): array {
$callable = function ($value): bool {
return strlen($value) > 2;
};

$callableKey = function ($value, $key): bool {
return is_numeric($key);
};

return [
[[], $callable, false],
[['a', 'aa', 'aaa', 'aaaa'], $callable, true],
[['a', 'aa'], $callable, false],
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, true],
[['a' => '1', 'b' => '12', 'c' => '123', 3 => '1234'], $callableKey, true],
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callableKey, false],
];
}

public static function arrayAllDataProvider(): array {
$callable = function ($value): bool {
return strlen($value) > 2;
};

$callableKey = function ($value, $key): bool {
return is_numeric($key);
};

return [
[[], $callable, true],
[['a', 'aa', 'aaa', 'aaaa'], $callable, false],
[['aaa', 'aaa'], $callable, true],
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callable, false],
[['a' => '1', 'b' => '12', 'c' => '123', 'd' => '1234'], $callableKey, false],
[[1 => '1', 2 => '12', 3 => '123', 4 => '1234'], $callableKey, true],
];
}
}

0 comments on commit 0e4546d

Please sign in to comment.