diff --git a/packages/http/src/RequestHeaders.php b/packages/http/src/RequestHeaders.php index 72af828a1..b4253b906 100644 --- a/packages/http/src/RequestHeaders.php +++ b/packages/http/src/RequestHeaders.php @@ -33,17 +33,21 @@ public function offsetExists(mixed $offset): bool { $offset = strtolower($offset); - return isset($this->headers[$offset]); + return array_key_exists($offset, $this->headers); } - public function offsetGet(mixed $offset): string + public function offsetGet(mixed $offset): ?string { return $this->get((string) $offset); } public function get(string $name, ?string $default = null): ?string { - return $this->headers[strtolower($name)] ?? $default; + $name = strtolower($name); + + return array_key_exists($name, $this->headers) + ? $this->headers[$name] + : $default; } public function has(string $name): bool diff --git a/packages/http/tests/GenericRequestTest.php b/packages/http/tests/GenericRequestTest.php index f4a2e9f61..103266886 100644 --- a/packages/http/tests/GenericRequestTest.php +++ b/packages/http/tests/GenericRequestTest.php @@ -30,6 +30,7 @@ public function test_normalizes_header_access(): void $this->assertSame($upperCaseValue, $request->headers['uppercase']); $this->assertSame($upperCaseValue, $request->headers['UPPerCasE']); $this->assertSame($lowerCaseValue, $request->headers['lowercase']); + $this->assertNull($request->headers['missing']); $this->assertSame($upperCaseValue, $request->headers->get('UpperCase')); $this->assertEquals( diff --git a/packages/support/src/Arr/IsIterable.php b/packages/support/src/Arr/IsIterable.php index e293451e4..2d778d5b4 100644 --- a/packages/support/src/Arr/IsIterable.php +++ b/packages/support/src/Arr/IsIterable.php @@ -39,7 +39,11 @@ public function offsetExists(mixed $offset): bool public function offsetGet(mixed $offset): mixed { - return $this->value[$offset] ?? throw new OffsetDidNotExist(); + if (! array_key_exists($offset, $this->value)) { + throw new OffsetDidNotExist(); + } + + return $this->value[$offset]; } public function offsetSet(mixed $offset, mixed $value): void diff --git a/packages/support/tests/Arr/ImmutableArrayTest.php b/packages/support/tests/Arr/ImmutableArrayTest.php index 77ffa5a23..a65af892f 100644 --- a/packages/support/tests/Arr/ImmutableArrayTest.php +++ b/packages/support/tests/Arr/ImmutableArrayTest.php @@ -67,6 +67,14 @@ public function test_add_diverse_values(): void ); } + public function test_null_values_are_accessible_by_offset(): void + { + $collection = new ImmutableArray(['key' => null]); + + $this->assertTrue(isset($collection['key'])); + $this->assertNull($collection['key']); + } + public function test_remove_with_basic_keys(): void { $collection = new ImmutableArray([1, 2, 3]); diff --git a/packages/support/tests/Arr/ToArrayTest.php b/packages/support/tests/Arr/ToArrayTest.php index 1e6445cb1..8c25b0a39 100644 --- a/packages/support/tests/Arr/ToArrayTest.php +++ b/packages/support/tests/Arr/ToArrayTest.php @@ -57,12 +57,14 @@ public function test_array_access_and_countable_objects_are_converted_to_arrays( public function offsetExists($offset): bool { - return isset($this->data[$offset]); + return array_key_exists($offset, $this->data); } public function offsetGet($offset): mixed { - return $this->data[$offset] ?? null; + return array_key_exists($offset, $this->data) + ? $this->data[$offset] + : null; } public function offsetSet($offset, $value): void @@ -97,12 +99,14 @@ public function test_array_access_without_traversable_or_countable(): void public function offsetExists($offset): bool { - return isset($this->data[$offset]); + return array_key_exists($offset, $this->data); } public function offsetGet($offset): mixed { - return $this->data[$offset] ?? null; + return array_key_exists($offset, $this->data) + ? $this->data[$offset] + : null; } public function offsetSet($offset, $value): void diff --git a/packages/support/tests/Arr/WrapTest.php b/packages/support/tests/Arr/WrapTest.php index 016cd79d1..df52502b8 100644 --- a/packages/support/tests/Arr/WrapTest.php +++ b/packages/support/tests/Arr/WrapTest.php @@ -58,12 +58,14 @@ public function test_array_access_and_countable_objects_are_not_converted_to_arr public function offsetExists($offset): bool { - return isset($this->data[$offset]); + return array_key_exists($offset, $this->data); } public function offsetGet($offset): mixed { - return $this->data[$offset] ?? null; + return array_key_exists($offset, $this->data) + ? $this->data[$offset] + : null; } public function offsetSet($offset, $value): void diff --git a/packages/view/src/Parser/TokenCollection.php b/packages/view/src/Parser/TokenCollection.php index b2f63a95a..c9bc0ae5c 100644 --- a/packages/view/src/Parser/TokenCollection.php +++ b/packages/view/src/Parser/TokenCollection.php @@ -40,12 +40,14 @@ public function __debugInfo(): array public function offsetExists(mixed $offset): bool { - return isset($this->tokens[$offset]); + return array_key_exists($offset, $this->tokens); } public function offsetGet(mixed $offset): mixed { - return $this->tokens[$offset] ?? null; + return array_key_exists($offset, $this->tokens) + ? $this->tokens[$offset] + : null; } public function offsetSet(mixed $offset, mixed $value): void diff --git a/packages/view/tests/TempestViewParserTest.php b/packages/view/tests/TempestViewParserTest.php index c38135f41..5848b52c9 100644 --- a/packages/view/tests/TempestViewParserTest.php +++ b/packages/view/tests/TempestViewParserTest.php @@ -38,6 +38,15 @@ public function test_parser(): void HTML, $parsed->compile()); } + public function test_token_collection_treats_null_as_an_existing_offset(): void + { + $tokens = new TokenCollection(); + $tokens['nullable'] = null; + + $this->assertTrue(isset($tokens['nullable'])); + $this->assertNull($tokens['nullable']); + } + public function test_parse_self_closing_tag_with_attributes(): void { $tokens = new TokenCollection([