-
-
Notifications
You must be signed in to change notification settings - Fork 565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix double access to ArrayAccess methods #760
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! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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