diff --git a/README.md b/README.md index 06b757d7..e042f602 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ Polyfills are provided for: - the `CURL_HTTP_VERSION_3` and `CURL_HTTP_VERSION_3ONLY` constants introduced in PHP 8.4; - the `get_error_handler` and `get_exception_handler` functions introduced in PHP 8.5; - the `NoDiscard` attribute introduced in PHP 8.5; +- the `array_first` and `array_last` functions introduced in PHP 8.5; 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 diff --git a/src/Php85/Php85.php b/src/Php85/Php85.php index a406fe0e..b6619d5b 100644 --- a/src/Php85/Php85.php +++ b/src/Php85/Php85.php @@ -33,4 +33,18 @@ public static function get_exception_handler(): ?callable return $handler; } + + public static function array_first(array $array) + { + foreach ($array as $value) { + return $value; + } + + return null; + } + + public static function array_last(array $array) + { + return $array ? current(array_slice($array, -1)) : null; + } } diff --git a/src/Php85/README.md b/src/Php85/README.md index 6381a9be..a374d9e2 100644 --- a/src/Php85/README.md +++ b/src/Php85/README.md @@ -5,6 +5,7 @@ This component provides features added to PHP 8.5 core: - [`get_error_handler` and `get_exception_handler`](https://wiki.php.net/rfc/get-error-exception-handler) - [`NoDiscard`](https://wiki.php.net/rfc/marking_return_value_as_important) +- [`array_first` and `array_last`](https://wiki.php.net/rfc/array_first_last) More information can be found in the [main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). diff --git a/src/Php85/bootstrap.php b/src/Php85/bootstrap.php index 0da63eb9..44e872b1 100644 --- a/src/Php85/bootstrap.php +++ b/src/Php85/bootstrap.php @@ -22,3 +22,11 @@ function get_error_handler(): ?callable { return p\Php85::get_error_handler(); } if (!function_exists('get_exception_handler')) { function get_exception_handler(): ?callable { return p\Php85::get_exception_handler(); } } + +if (!function_exists('array_first')) { + function array_first(array $array) { return p\Php85::array_first($array); } +} + +if (!function_exists('array_last')) { + function array_last(array $array) { return p\Php85::array_last($array); } +} diff --git a/tests/Php85/Php85Test.php b/tests/Php85/Php85Test.php index fc4c7163..ea477025 100644 --- a/tests/Php85/Php85Test.php +++ b/tests/Php85/Php85Test.php @@ -78,6 +78,44 @@ public static function provideHandler() $handler = new TestHandlerInvokable(); yield [$handler, $handler]; } + + public function testArrayFirstArrayLast() + { + $this->assertNull(array_first([])); + $this->assertNull(array_last([])); + + $array = [1, 2, 3]; + unset($array[0], $array[1], $array[2]); + + $this->assertNull(array_first([])); + $this->assertNull(array_last([])); + + + $this->assertSame("single element", array_first(["single element"])); + $this->assertSame("single element", array_last(["single element"])); + + $str = "hello world"; + $this->assertSame($str, array_first([&$str, 1])); + $this->assertSame(1, array_last([&$str, 1])); + + $this->assertSame(1, array_first([1, &$str])); + $this->assertSame($str, array_last([1, &$str])); + + $this->assertSame(1, array_first([1 => 1, 0 => 0, 3 => 3, 2 => 2])); + $this->assertSame(2, array_last([1 => 1, 0 => 0, 3 => 3, 2 => 2])); + + $this->assertSame('a1', array_first(['a' => 'a1', 'b' => 'b1', 'c' => 'c1'])); + $this->assertSame('c1', array_last(['a' => 'a1', 'b' => 'b1', 'c' => 'c1'])); + + $this->assertSame([], array_first([100 => []])); + $this->assertSame([], array_last([100 => []])); + + $this->assertEquals(new \stdClass(), array_first([new \stdClass, false])); + $this->assertFalse(array_last([new \stdClass, false])); + + $this->assertTrue(array_first([true, new \stdClass])); + $this->assertEquals(new \stdClass(), array_last([true, new \stdClass])); + } } class TestHandler