PHP 8.2: Partially-supported callable are deprecated
PHP 8.2 deprecates certain patterns of callables that do not work with the $callable()
pattern.
PHP supports several forms to create a callable. A callable can then be called with or without parameters using $callable()
syntax, user_call_func
(/_array
), or by passing it to PHP function that calls back a given callback.
Unaffected Callable Patterns
$callable = 'strlen';
$callable = ['MyClass', 'myMethod'];
$callable = 'MyClass::myMethod'];
$callable = Closure::fromCallable();
$callable = [$this, 'myMethod'];
$callable = [new MyClass(), 'myMethod'];
$callable = strlen(...);
$callable = strlen(...);
example above uses First-class callable syntax added in PHP 8.1.
All of the patterns of creating a callable are compatible with $callable()
syntax, user_call_func
(/_array
) functions, and passing to a function expects a callable
.
All of them also return true
for is_callable
, and are accepted for callable
parameter/return type.
Deprecated Callable Patterns
Currently, there are some forms of creating callables that are not consistent when it is used:
$callable = "self::method";
$callable = "parent::method";
$callable = "static::method";
$callable = ["self", "method"];
$callable = ["parent", "method"];
$callable = ["static", "method"];
$callable = ["MyClass", "MyParentClass::myMethod"];
$callable = [new MyClass(), "MyOtherClass::myMethod"];
All of the patterns above are considered valid callable
values for the callable
type and is_callable
function. Further, they are also accepted by user_call_func
(/_array
) functions and functions that accept a callable
.
These callable patterns are inconsistent, as in they are not supported by the $callable($params)
calling pattern. In PHP 8.2 and later, calling such callable emits a deprecation notice:
class Test {
public static function myMethod(): void {
echo "Called";
}
public static function call(): void {
$callable = 'self::myMethod';
call_user_func($callable);
}
}
$callable = Test::call();
// "Called";
The self::myMethod
callable is not it was called with $callable()
pattern:
Error: Class "self" not found in ... on line ...
However, call_user_func
, call_user_func_array
, and internal functions that accept a callable (such as array_map
) allow this pattern. In PHP 8.2 and later, calling such callable
emits a deprecation notice:
Deprecated: Use of "self" in callables is deprecated in ... on line ...
All of the patterns above result in a similar deprecation notice at the time the callables are called. Passing such callables to is_callable
function or using them with callable
return/parameter types does not emit a deprecation notice.
Avoiding the Deprecation Notice
The easiest way to avoid the deprecation notice is to convert all self
, parent
, and static
keywords in the callable construction to their corresponding class names. This can be easily done with the ::class
magic method, which resolves to the fully-qualified class name.
class Test {
public static function myMethod(): void {
echo "Called";
}
public static function call(): void {
- $callable = 'self::myMethod';
+ $callable = self::class . '::myMethod';
call_user_func($callable);
}
}
$callable = Test::call();
// "Called";
Alternately, using first-class callable syntax (added in PHP 8.1) or the array syntax might be an improvement for code clarity. Further, it is possible to use $callable()
syntax, that is slightly faster because it avoids the call_user_func
function call overhead:
- $callable = 'self::myMethod';
+ $callable = self::myMethod(...);
- call_user_func($callable);
+ $callable();
Rationale Behind the Change
PHP supported various callable construct syntax over the years, and it now needs to account for method visibility (e.g. calling a private
method from a class context) and other factors that make handling these patterns technically complex.
This deprecation also aims to reduce the context-dependability of callables such as self::myMethod
, and encourage the Closure
APIs, that can correctly handle the class contexts regardless of the call-site.
Instead of extending $callable()
call pattern to accommodate the now-deprecated patterns, the decision was made to deprecate using these context-dependent and uncommon callable constructs with call_user_func
and related functions.
$callable()
is the recommended and most widely adopted calling pattern for callables, and this deprecation also encourages it.
Backwards Compatibility Impact
From PHP 8.2 and later, calling any of the callables with deprecated callable constructs emit a deprecation notice.
The easiest way to avoid this deprecation notice is to make use of ::class
magic constant that resolves to the actual class name. This should work all PHP >= 5.3 versions.
On PHP 8.0 and later, it is also possible to use the ::class
magic constant on class objects.