Fix double access to ArrayAccess methods#760
Fix double access to ArrayAccess methods#760brunobg wants to merge 12 commits intowebonyx:masterfrom
Conversation
This is a proposal to fix webonyx#759
|
I'm supporting this change 👍 I discovered this some time ago and AFAIK suggested to lighthouse to adapt this but it wasn't picked up (and I also don't use lighthouse, I just noticed this in different Laravel / GraphQL adapter). I tested this on a private project with lots of GraphQL tests, no issues found. Are we concerned about a BC break here? Maybe we should considering target the next major version? #JustBeingCautious here |
|
@mfn great to see you around here. This change indeed causes breakage when |
|
@spawnia see my reply on the original issue and the new patch. @mfn I think that should be as safe as the currently released code and doesn't even need a major version, could be part of a patch release. There are no changes to array and object. There's a worst case scenario, with a trashy implementation of ArrayAccess. Let's say one that just wraps over a normal array, calling |
|
Hey @spawnia anything else I can do about this? I'd love to get this accepted. |
|
The implementation looks fine, I would like to get more feedback. @vladar usually comes by every few weeks and merges a bunch of PRs. |
|
Considering other reports such as nuwave/lighthouse#1671, who knows how many people are having this behavior without noticing, please consider this PR and a new release ASAP @vladar and @spawnia . Thanks! |
spawnia
left a comment
There was a problem hiding this comment.
This change does smooth over the weird semantics of ArrayAccess in a way that is beneficial to most if not all users.
|
This PR is trying to fix a problem in the wrong place. <?php
class Foo implements ArrayAccess
{
private $foo = [];
public function __construct(array $foo)
{
$this->foo = $foo;
}
public function offsetExists($offset)
{
return isset($this->foo[$offset]);
}
public function offsetGet($offset)
{
return $this->foo[$offset];
}
public function offsetSet($offset, $value)
{
$this->foo[$offset] = $value;
}
public function offsetUnset($offset)
{
unset($this->foo[$offset]);
}
}Now with the proposed change if you try to access a missing key like this: $d = new Foo([ 'foo' => 'bar' ]);
$property = null;
try {
$property = $d['bar'];
} catch (Throwable $e) {
// pass
}you will get PHP notice: Obviously, you can have an additional So this is a breaking change and also an invalid behavior. The generic implementation for Or alternatively you can set it globally via |
spawnia
left a comment
There was a problem hiding this comment.
The semantics of ArrayAccess are not that weird after all, having checked how they work in https://3v4l.org/OLqvr.
I think this change can be valid if you know you are dealing with inefficient implementations, such as Laravel's. As @vladar noted, it is easily possible to overwrite the default resolver in such a case.
|
Closing this though I disagree as explained in the issue. Also, note that a detailed analysis of what happens in Laravel laravel/framework#36026 shows that real implementations can throw in offsetExists(). So if you're worried that a trivial implementation can throw a notice in my PR, you should be worried that it can also throw exceptions. |
This is a proposal to fix #759