|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-05-20 13:47 UTC] bwoebi@php.net
Description:
------------
Due to our call_user_func() optimizations (which by the way also removes the additional internal stack frame in the stacktrace...; which ultimately causes the misbehavior), call_user_func[_array]() calls apply, when optimized, the strict_type mode of the caller, which they shouldn't.
In general, PHP functions count internally as weakly typed and this behavior shall be always the same.
Test script:
---------------
// first script (works as expected, with namespace)
<?php declare(strict_types=1); namespace a; var_dump(call_user_func("strlen", 1));'
// second script (bad behavior, without namespace)
<?php declare(strict_types=1); var_dump(call_user_func("strlen", 1));'
Expected result:
----------------
// first script
int(1)
// second script
int(1)
Actual result:
--------------
// first script
int(1)
// second script
Fatal error: Uncaught TypeError: strlen() expects parameter 1 to be string, integer given in Command line code:1
Stack trace:
#0 Command line code(1): strlen(1)
#1 {main}
thrown in Command line code on line 1
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Dec 07 11:00:01 2025 UTC |
This does not only apply to PHP internal functions, this code has the same behavior: Test scripts: <?php declare(strict_types=1); namespace a; var_dump( call_user_func(function(string $test) { return $test; }, 5) ); <?php declare(strict_types=1); var_dump( call_user_func(function(string $test) { return $test; }, 5) ); However in this scenario the desired behavior is different. Since we have strict types on user code I assume we would always want an error, even in namespaces.> So the behavior of the non-namespaced code is correct, but the namespaced code behaves erroneously. That's backwards. The bug is as reported. Function calls made from within PHP do not use strict typing. call_user_func("strlen") should work as if strlen is being called from within call_user_func's stack frame and thus not use strict typing, however c_u_f used when not in a namespace is optimized into the equivalent function call - the second script compiles into a literal strlen(1) call - which is why strict_types kicked in. Optimization or not, it should work just like a userland implementation of <?php // declare(strict_types=0); function call_user_func_userland($function, ...$args) { return $function(...$args); } ?>