is_callable

Checks whether a value can be called as a function in the current scope.

Signature
is_callable(mixed $value, bool $syntax_only = false, string &$callable_name = null): bool
  • Added in PHP 4.0.6

Parameters

ParameterTypeDescription
$valuemixedThe value to check.
$syntax_onlyoptionalbool= falseIf true, only verifies that the value has the shape of a callable (a string, a closure, an invokable object, or a two-element array of object/class plus string) without checking that the target actually exists.
$callable_nameoptionalstring= nullAssigned by reference the callable's name, for example "SomeClass::someMethod".

Return value

booltrue if $value is callable, false otherwise.

Errors

Does not throw, but may trigger class autoloading when $value names a class and $syntax_only is false.

Changelog

  • PHP 8.0.0Non-static methods can no longer be checked through a class name: is_callable(['ClassName', 'nonStaticMethod']) and is_callable('ClassName::nonStaticMethod') now return false. Pass an object instance instead.

is_callable() asks whether a value can actually be invoked right now. It accepts every callable form: a function-name string, 'Class::staticMethod', an [$object, 'method'] or ['Class', 'staticMethod'] array, a Closure, and any object whose class defines __invoke().

With the default $syntax_only = false it performs a real lookup — the function or method must exist and be reachable from the calling scope, which means a private method returns false when checked from outside the class. Set $syntax_only to true to skip the lookup and only validate the shape; that avoids autoloading a class you do not want loaded yet.

Two traps worth knowing

A class implementing __call() makes is_callable([$obj, 'anything']) return true for every method name, since the magic method could handle it. If you need to know whether a real method is declared, use method_exists() instead — or both, since they answer different questions.

Since PHP 8.0, checking a non-static method through a class name returns false; you must pass an instance.

When to reach for it

Validate a user-supplied callback before storing it in an event dispatcher, plugin registry or middleware pipeline, so the failure surfaces at registration rather than deep inside a dispatch loop.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Validating a callback passed into an event dispatcher or plugin registry before it is stored
  • Checking that an optional hook exists on an object before invoking it in a middleware pipeline
  • Using $syntax_only = true to sanity-check a 'Class::method' config string without autoloading the class

Frequently asked questions

What is the difference between is_callable() and function_exists()?

function_exists() only handles plain function-name strings, while is_callable() also accepts closures, invokable objects and [object, 'method'] arrays, and checks visibility from the calling scope. Use is_callable() for anything you intend to invoke as a callback.

Why does is_callable(['MyClass', 'myMethod']) return false?

Because since PHP 8.0 a non-static method can no longer be checked through its class name. Pass an instance instead: is_callable([new MyClass(), 'myMethod']).

Does is_callable() autoload classes?

Yes, when you pass a class-name based callable and leave $syntax_only as false. Set $syntax_only to true to validate the shape without triggering the autoloader.

More examples

syntax_only and the callable name

The static method resolves and $name comes back as DateTime::createFromFormat. The missing class fails the real lookup but passes the syntax-only check, which still fills in the name — useful for validating config strings before the class is loaded.

Example · php
<?php
var_dump(is_callable(['DateTime', 'createFromFormat'], false, $name));
echo $name, "\n";

var_dump(is_callable(['NoSuchClass', 'nope'], false, $n2));
var_dump(is_callable(['NoSuchClass', 'nope'], true, $n3));
echo $n3, "\n";

__call() makes everything callable

is_callable() says true because __call() would indeed handle the invocation, while method_exists() correctly says the method is not declared. Both answers are right — they just answer different questions.

Example · php
<?php
class Proxy {
    public function __call(string $name, array $args): string {
        return "forwarded: $name";
    }
}

$p = new Proxy();

var_dump(is_callable([$p, 'anythingAtAll']));
var_dump(method_exists($p, 'anythingAtAll'));
echo $p->anythingAtAll(), "\n";

Registering validated handlers

The invalid handler is caught at registration time with a clear message instead of causing a fatal Error later during dispatch. The three surviving callables — two named functions and one closure — all run through the same call site.

Example · php
<?php
$handlers = ['strtoupper', 'no_such_function', fn($s) => "[$s]", 'trim'];
$valid = [];

foreach ($handlers as $h) {
    if (is_callable($h)) {
        $valid[] = $h;
    } else {
        echo 'rejected: ', get_debug_type($h), ' ', var_export($h, true), "\n";
    }
}

foreach ($valid as $fn) {
    echo $fn('  php  '), "\n";
}

Discussion

  • Be the first to comment on this lesson.