Bug #74998 [Wfx->Nab]: callable typehint generates redundant and unnecessary deprecation warning

From: Date: Thu, 27 Jul 2017 21:16:05 +0000
Subject: Bug #74998 [Wfx->Nab]: callable typehint generates redundant and unnecessary deprecation warning
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-210377@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74998&edit=1 ID: 74998 Updated by: nikic@php.net Reported by: alex dot howansky at gmail dot com Summary: callable typehint generates redundant and unnecessary deprecation warning -Status: Wont fix +Status: Not a bug Type: Bug Package: Scripting Engine problem Operating System: Fedora 25 PHP Version: 7.1.7 Block user comment: N Private report: N Previous Comments: ------------------------------------------------------------------------ [2017-07-27 21:15:50] nikic@php.net Both deprecation warnings are correct. And yes, you should absolutely drop the callable type hint, because what you are accepting is clearly not a callable. It may help to consider what is going to happen when the deprecation is realized: Your code will already error at the typehint, not just at the call. Not generating a deprecation notice at the typehint would be disingenuous, as the typehint is going to throw exception in a future version of PHP. ------------------------------------------------------------------------ [2017-07-27 21:07:05] alex dot howansky at gmail dot com Description: ------------ If you have a function/method that takes an argument typehinted with callable, and you pass it an array of static strings which references a method that's not defined as static, you'll get a deprecation warning about making a static call to a non-static method -- even if you never actually invoke the callable. If you then invoke the callable, you'll get an identical second deprecation warning. Note the test script. As is, it generates two identical warnings, on adjacent lines, one for the callable typehint, and one for the actual call. The first is unwanted and unnecessary. The warning should be triggered only when I actually make the deprecated call. Simply passing a static callable should not trigger the warning. I.e., PHP shouldn't warn me about something I might possibly do in the future, it should warn me only about things I've actually done. Since the invocation will always generate a warning, there's no need to also generate one when validating the typehint. Otherwise, you will always get two identical warnings for a single issue. Suppose I add some conditional logic to this method, to detect if the callable is static and automatically instantiate an object for it if so: if (is_string($callable[0])) { call_user_func([new $callable[0], $callable[1]]); } else { call_user_func($callable); } This should not generate any deprecation warnings, as nothing would ever get called statically. As it stands, in order to get rid of the warnings, I would have to remove the callable typehint. Test script: --------------- <?php error_reporting(E_ALL); class Caller { public function call(callable $callable) { call_user_func($callable); } } class Foo { public function bar() { echo "here\n"; } } $caller = new Caller(); $callable = ['Foo', 'bar']; $caller->call($callable); Expected result: ---------------- PHP Deprecated: Non-static method Foo::bar() should not be called statically in /tmp/foo.php on line 7 here Actual result: -------------- PHP Deprecated: Non-static method Foo::bar() should not be called statically in /tmp/foo.php on line 6 PHP Deprecated: Non-static method Foo::bar() should not be called statically in /tmp/foo.php on line 7 here ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=74998&edit=1

« previous php.bugs (#210377) next »