First-Class Callable Syntax
Turn any function or method into a Closure with the (...) syntax — type-safe, IDE-friendly references without stringly-typed callables.
PHP 8.1 gave us a clean way to grab a reference to a callable: append (...). strlen(...) is the strlen function as a Closure object; $obj->method(...) is a bound method; Klass::method(...) is a static one. No more error-prone strings like 'strlen' or [$obj, 'method'] arrays.
Easy example
<?php
$lengths = array_map(strlen(...), ['a', 'bb', 'ccc']);
print_r($lengths); // [1, 2, 3]Because the result is a real Closure, your IDE can follow it, refactoring tools rename it, and static analysis checks the signature — everything the old string callables couldn't do.
Example
When to use it
- Pass strlen(...) directly to array_map without wrapping it in an anonymous function.
- Store a reference to a specific object method as a closure using $obj->method(...) for deferred invocation.
- Replace a stringly-typed ['Math', 'sqrt'] callable with Math::sqrt(...) for IDE-refactorable references.
More examples
Built-in function as callable
strtoupper(...) creates a Closure from the built-in, replacing the verbose fn($s) => strtoupper($s) wrapper.
<?php
$words = ['hello', 'world', 'php'];
$upper = array_map(strtoupper(...), $words);
$lengths = array_map(strlen(...), $words);
print_r($upper); // HELLO, WORLD, PHP
print_r($lengths); // 5, 5, 3Static method as callable
Sanitizer::slug(...) creates a Closure from the static method; it is type-checked and IDE-refactorable.
<?php
class Sanitizer {
public static function slug(string $s): string {
return strtolower(preg_replace('/[^a-z0-9]+/i', '-', trim($s)));
}
}
$titles = ['Hello World', 'PHP 8 Features', 'First-Class Callables'];
$slugs = array_map(Sanitizer::slug(...), $titles);
print_r($slugs);Instance method as callable
$fmt->format(...) captures both the method and the bound object, creating a closure that remembers the currency.
<?php
class Formatter {
public function __construct(private string $currency) {}
public function format(float $amount): string {
return $this->currency . number_format($amount, 2);
}
}
$fmt = new Formatter('$');
$prices = [9.9, 24.99, 4.5];
$result = array_map($fmt->format(...), $prices);
print_r($result); // ['$9.90', '$24.99', '$4.50']
Discussion