Skip to content

Commit 3d43518

Browse files
yaniYanicompwright
authored
fix: overloading behaviour (#14)
* fix overloading behaviour * Remove clone statements * fix overloading usage and test cases * fix name of overload testcases --------- Co-authored-by: Yani <yani@xenokore.com> Co-authored-by: Jonathon Hill <jhill9693@gmail.com>
1 parent 8ec48a5 commit 3d43518

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

features/access.feature

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,11 @@ Feature: Session access
3333
Scenario: Iterate over non-populated session
3434
When data does not exist
3535
Then data is not iterated
36+
Scenario: Overload existing array
37+
When empty array for overload exists
38+
Then overloading using property access succeeds
39+
And overloading using property access succeeds
40+
Scenario: Overload non existing array
41+
When data does not exist
42+
Then overloading using array access fails
43+
And overloading using property access fails

src/Session.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Countable;
99
use ArrayAccess;
1010
use RuntimeException;
11+
use Stringable;
1112

1213
class Session implements ArrayAccess, Iterator, Countable
1314
{
@@ -46,13 +47,17 @@ public function __construct(string $name, ?string $id = null, array $contents =
4647
*
4748
* @throws RuntimeException if not initialized
4849
*/
49-
public function __get(string $name)
50+
public function &__get(string $name)
5051
{
5152
if (!$this->isInitialized()) {
5253
throw new RuntimeException('Session not initialized');
5354
}
5455

55-
// @phpstan-ignore-next-line
56+
if(!isset($this->contents[$name])){
57+
\trigger_error("Array key not found: '$name'", \E_USER_NOTICE);
58+
return null;
59+
}
60+
5661
return $this->contents[$name];
5762
}
5863

@@ -133,13 +138,20 @@ public function offsetUnset($name): void
133138
unset($this->contents[$name]);
134139
}
135140

136-
public function offsetGet($name): mixed
141+
public function &offsetGet($name): mixed
137142
{
138143
if (!$this->isInitialized()) {
139144
throw new RuntimeException('Session not initialized');
140145
}
141146

142-
// @phpstan-ignore-next-line
147+
148+
if(!isset($this->contents[$name])){
149+
if($name === null || \is_scalar($name) || $name instanceof Stringable){
150+
\trigger_error("Array key not found: '$name'", \E_USER_NOTICE);
151+
}
152+
return null;
153+
}
154+
143155
return $this->contents[$name];
144156
}
145157

tests/behavior/AccessContext.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ public function dataExists(): void
3434
Assert::assertCount(1, $this->session);
3535
}
3636

37+
/**
38+
* @When empty array for overload exists
39+
*/
40+
public function emptyArrayForOverloadExists(): void
41+
{
42+
$this->session = new Session('foo', 'bar', ['foo' => []]);
43+
Assert::assertTrue($this->session->isWriteable());
44+
Assert::assertCount(1, $this->session);
45+
}
46+
3747
/**
3848
* @Then property check returns false
3949
*/
@@ -199,4 +209,58 @@ public function iteratorFails(): void
199209

200210
Assert::assertSame(0, $counter);
201211
}
212+
213+
/**
214+
* @Then overloading using array access succeeds
215+
*/
216+
public function arrayOverloadSucceeds(): void
217+
{
218+
// @phpstan-ignore-next-line
219+
$this->session['foo'][] = 'baz';
220+
// @phpstan-ignore-next-line
221+
Assert::assertSame('baz', $this->session['foo'][0]);
222+
}
223+
224+
/**
225+
* @Then overloading using property access succeeds
226+
*/
227+
public function objectOverloadSucceeds(): void
228+
{
229+
// @phpstan-ignore-next-line
230+
$this->session->foo[] = 'baz';
231+
// @phpstan-ignore-next-line
232+
Assert::assertSame('baz', $this->session->foo[0]);
233+
}
234+
235+
/**
236+
* @Then overloading using array access fails
237+
*/
238+
public function arrayOverloadFails(): void
239+
{
240+
try {
241+
$errorThrown = false;
242+
// @phpstan-ignore-next-line
243+
$this->session['foo'][] = 'baz';
244+
} catch (Throwable $e) {
245+
$errorThrown = true;
246+
} finally {
247+
Assert::assertTrue($errorThrown);
248+
}
249+
}
250+
251+
/**
252+
* @Then overloading using property access fails
253+
*/
254+
public function objectOverloadFails(): void
255+
{
256+
try {
257+
$errorThrown = false;
258+
// @phpstan-ignore-next-line
259+
$this->session->foo[] = 'baz';
260+
} catch (Throwable $e) {
261+
$errorThrown = true;
262+
} finally {
263+
Assert::assertTrue($errorThrown);
264+
}
265+
}
202266
}

0 commit comments

Comments
 (0)