CodeBlanks Logo Icon CodeBlanks

First-class callable syntax

PHP course · Expert · Lesson 41/54

Learn the first-class callable syntax that creates closures with ....

First-class callable syntax (...)

PHP 8.1 added first-class callable syntax: it turns any callable into a Closure, e.g. $fn = strlen(...).

The three dots (...) are a placeholder meaning 'arguments go here'. The resulting Closure behaves exactly like the original.

It is clearer than older forms: instead of Closure::fromCallable('strlen') you write strlen(...). Method references work too: $obj->method(...) and Foo::method(...).

Attributes (#[Attribute])

PHP 8.0 added attributes: attach metadata to classes, methods and properties. The syntax is #[Route("/users")], written inside square brackets.

To declare an attribute class, mark it with #[Attribute]. Its constructor parameters carry data.

Attributes are read at runtime with the Reflection API; frameworks use them for routing, validation and dependency injection.

Exercise Route attribute and first-class callable

Define a Route attribute class: marked with #[Attribute], with a constructor that takes string $path.

Apply the #[Route("/users")] attribute to a list_users function. Then obtain a Closure with list_users(...) and call it; the output should be users.

Show example solution
#[Attribute]
class Route {
  public function __construct(public string $path) {}
}

#[Route("/users")]
function list_users(): void {
  echo "users\n";
}

$fn = list_users(...);
$fn();

Test yourself

  1. First-class callable syntax

    $upper = ____;
    echo $upper("hi");
    
    Show answer
    $upper = strtoupper(...);
    echo $upper("hi");
    
  2. What does strlen(...) return?

    • The result of strlen
    • A Closure for strlen
    • The definition of strlen
    • It throws an error
    Show answer

    A Closure for strlen — Correct. strlen(...) returns a Closure; when you call it with an argument, strlen runs.

  3. Callable and attribute concepts

    ...
    first-class callable placeholder
    Closure
    callable object
    #[Route]
    metadata declaration
    Reflection
    reads metadata

All lessons in Expert