Re: Strict type declarations not enforced for Reflection API invocation
| From: | Niklas Keller | Date: | Wed, 11 Oct 2017 11:48:31 +0000 |
| Subject: | Re: Strict type declarations not enforced for Reflection API invocation | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-100862@lists.php.net to get a copy of this message | ||
2017-10-11 11:03 GMT+02:00 Pedro Magalhães <mail@pmmaga.net>:
> On Tue, Oct 10, 2017 at 5:53 PM, Nikita Popov <nikita.ppv@gmail.com>
> wrote:
> >
> > The problem are not internal function calls, the problem are callbacks.
> In
> > fact, the proposed fix does not actually fix the problem you encountered
> in
> > PHPUnit, as it is going to use the strictness mode at the reflection
> > call-site, not the strictness mode used by the file defining the data
> > provider.
> >
>
> For those that didn't have a look at the PR, my goal was to try to ensure
> that if we are looking for which strictness to use, we should look at the
> place of the closest "user" call instead of the function (user or internal)
> that called the current one. The reason for this problem lies in the fact
> that
ZEND_ARG_USES_STRICT_TYPES() will simply look at the
> caller
> regardless of what it is. Although this is enough to allow calling
> functions that were defined as non-strict in a strict manner, it does cause
> this kind of shortcomings with callbacks.
>
>
> > I believe that the proper way to fix this is to handle dynamic function
> > invocations differently from direct invocations. Direct invocations
> should
> > use the strictness level of the call-site, while dynamic invocations
> should
> > use the strictness level of the declaration-site.
>
I'm not sure about that. That might be reasonable for closures, but not for
other dynamic invocations.
> I agree that this should be about dynamic vs direct instead of user vs
> internal but IMHO, making the strictness vary from call-site to
> declaration-site depending on that may be a bit too confusing. Would it be
> possible/reasonable to try to find the place where the dynamic call was
> started? (i.e. the dataProvider, the mapped function for a userland
> array_map, etc...)
>
I don't think that's reasonably possible. Think about some event emitter
like that:
```
class EventEmitter {
private array $callbacks = [];
public function on(string $eventName, callable $callback): void {
$this->callbacks[$eventName][] = $callback;
}
public function emit(string $eventName, $value): void {
foreach ($this->callbacks[$eventName] ?? [] as $callback) {
$callback($value);
}
}
}
```
Where is a dynamic call to a registered callback started? Depending on the
strictness level of the caller of emit()? What if that emit() is called
from another file with another strictness level?
Regards, Niklas