Jump to content

Purpose of syntax_only as true with is_callable?


NotionCommotion

Recommended Posts

What is a useful case for using $syntax_only as true with is_callable()?  Reference http://php.net/manual/en/function.is-callable.php.

 

bool is_callable ( mixed $var [, bool $syntax_only = FALSE [, string &$callable_name ]] )
 
syntax_only
If set to TRUE the function only verifies that name might be a function or method. It will only reject simple variables that are not strings, or an array that does not have a valid structure to be used as a callback. The valid ones are supposed to have only 2 entries, the first of which is an object or a string, and the second a string.

 

<?php
function t($obj,$methodname,$syntax_only)
{
    $rs=is_callable([$obj, $methodname], $syntax_only, $name);
    echo(($rs?'true':'false')." $name\n");
}
class someClass {
    public function publicMethod(){}
    protected function protectedMethod(){}
    private function privateMethod(){}
}
$o = new someClass();
t($o,'publicMethod',true);
t($o,'protectedMethod',true);
t($o,'privateMethod',true);
t($o,'missingMethod',true);
t($o,'publicMethod',false);
t($o,'protectedMethod',false);
t($o,'privateMethod',false);
t($o,'missingMethod',false);
true someClass::protectedMethod
true someClass::privateMethod
true someClass::missingMethod
true someClass::publicMethod
false someClass::protectedMethod
false someClass::privateMethod
false someClass::missingMethod

 

Link to comment
Share on other sites

It would be most useful when the callback corresponds to a class method, the class is not yet loaded at the time of is_callable, and you don't want to load the class yet (ie, want it lazy-loaded when needed).

 

For example, in a plugin architecture, you might have one script which defines a whole lot of callbacks/hooks into a framework. The framework will want to verify each callback looks valid but won't necessarily want to load the class definitions at that moment - there's no need to load the class if the callback happens to not get executed during the request.

Link to comment
Share on other sites

Say you're building a routing class that takes a path and a callback to execute if the request matches that path. You'd want to ensure that the callback is something that can be called, but you don't want to trigger a bunch of autoload requests for every possible route when likely only one of them will actually be called. So:

public function addRoute($path, $callback){
    if (!is_callable($callback, true)){
        throw new \InvalidArgumentException('$callback must be a callable type');
    }

    $this->routes[] = ['path' => $path, 'callback' => $callback];
}
It's just a way to provide a little validation by making sure the value at least looks like it might be correct without going through the effort to actually validate that it is in fact correct.

 

Later on when you know which route you want to call, then you can validate the method truly is callable by auto loading classes if needed.

 

private function executeRoute($route){
    if (!is_callable($route['callback'])){
        throw new \RuntimeException('Route callback is not valid.');
    }

    call_user_func($route['callback']);
}
By checking in both places you can potentially catch obvious errors early when the route is added, making debugging a bit easier. Less obvious errors such as a typo in a function name would have to wait until the actual call to be caught.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.