Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

PHP's Callable Typehint Too Loose?

DZone's Guide to

PHP's Callable Typehint Too Loose?

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

PHP got support for closures in version 5.3, and in PHP 5.4 we got support for a callable typehint, that can be used as such:

<?php

function callMe(callable $callBack) {

    $callBack();

}

?>

All these little changes make it feel more comfortable to apply functional programming concepts to PHP, but occasionally we need to drop back to using less aesthetically pleasing code.


To use our callMe function to call back directly to a object method, we use this syntax:

<?php
callMe([$object, 'method']);
?>

This also works with static methods:

<?php
callMe(['\\Namespace\\MyClass', 'method']);
?>

Or if you are on PHP 5.5:

<?php
callMe([MyClass::class, 'method']);
?>

These all work, because when you execute this code:

<?php
$foo = [$object, 'method'];
$foo();
?>

...PHP will actually correctly execute method on our $object. But there's an exception. Aside from the previous syntax for calling static methods, PHP also allows this to fulfill the callable typehint:

callMe('MyClass::method');

Unfortunately, this will trigger the following error:

Fatal error: Call to undefined function MyClass::method() in /in/Kkr3F on line 14
Process exited with code 255.

The only remedy is to change our original function from:

<?php

function callMe(callable $callBack) {

    $callBack();

}

?>

to:

<?php

function callMe(callable $callBack) {

    call_user_func($callBack);

}

?>

call_user_func($callBack); does what $callBack() does, but it's less aesthetically pleasing.


So if you rely on the callable typehint, or the is_callable() function, be aware that you need to use call_user_func() to get reliable results.


Lastly


I came to write this because I got a bug report from someone who wanted to be able to use the 'MyClass::method' syntax. I was a bit surprised this didn't work, as I had always used ['MyClass', 'method']. So, before changing all my $x() to call_user_func($x), I first had to figure out how this was possible.


What do you think? Is this a PHP bug? Or was I wrong to think that this should have worked in the first place?

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:
php ,html5 ,php 5.4

Published at DZone with permission of Evert Pot, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}