You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
call_user_func special function optimization unsound with strict_types #18591
<?phpdeclare(strict_types=1);
namespaceFoo;
// strlen() will be called with strict_types=0, so this is legal.var_dump(call_user_func('strlen', false));
// Called with strict_types=1var_dump(\call_user_func('strlen', false));
Resulted in this output:
int(0)
Fatal error: Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, false given in /in/bcCZ4:10
Stack trace:
#0 /in/bcCZ4(10): strlen(false)
#1 {main}
thrown in /in/bcCZ4 on line 10
IMO the 1st behaviour is more correct is sense how strict_types are handled in other functions.
No, the consistent way is to use weak mode. As it is the engine performing the function call and those are always in weak mode.
While it would make sense logically, it would rip huge holes into the type system, since call_user_func* doesn't do anything by itself, but is just a wrapper.
I think treating it as if the original function is called directly instead of via call_user_func - which is how it works currently if no namespace is used - is the more sensible (and stricter) choice
Activity
mvorisek commentedon May 19, 2025
present since eternity - https://3v4l.org/kqsCu
IMO the 1st behaviour is more correct is sense how strict_types are handled in other functions.
Girgias commentedon May 19, 2025
No, the consistent way is to use weak mode. As it is the engine performing the function call and those are always in weak mode.
kkmuffme commentedon Sep 3, 2025
Basically reported 7 years ago: https://bugs.php.net/bug.php?id=72248
(with slight nuance/difference)
While it would make sense logically, it would rip huge holes into the type system, since call_user_func* doesn't do anything by itself, but is just a wrapper.
I think treating it as if the original function is called directly instead of via call_user_func - which is how it works currently if no namespace is used - is the more sensible (and stricter) choice