2

This is not a duplicate of "https://stackoverflow.com/questions/4351835/in-php-how-do-i-check-if-a-function-exists".

How do I check if input is callable, either as an existing function or a language construct that behaves like a function?

22
  • 1
    Since empty is, as you say, not a function, it's somewhat vague what you want to know. Why would you be trying to call language constructs using variable code snippets (which is typically not possible to begin with)? Commented Nov 20, 2013 at 14:00
  • 5
    you ask to see if something is a function, but complain aoubt function_exists that it will fail for something that is not a function? Commented Nov 20, 2013 at 14:00
  • 1
    The intent is to detect whether input callback (whether it is a function or a language construct) can be used to validate user input. Commented Nov 20, 2013 at 14:01
  • 3
    Guys I too an curious what the use case is for this. Regardless, I think it's a valid question. There are language constructs that behave like functions and then there are actual functions, and it seems valid to ask how to tell if something is callable either way. Commented Nov 20, 2013 at 14:06
  • 3
    function canICall($function) { $callableConstructs = array("empty","unset","eval","array","exit","isset","list"); return function_exists($function) || in_array($function, $callableConstructs); } Commented Nov 20, 2013 at 14:09

2 Answers 2

1

There are all kinds of potential problems with what you're asking. However if I understand you right, you simply want to know if somename can be called like somename('someinput').

If that's true, then it appears you need to use a combination of function_exists and a manual lookup of language constructs from the List of Keywords.

Something like this perhaps:

function canICall($function) {
    $callableConstructs = array("empty","unset","eval","array","exit","isset","list");
    return function_exists($function) || in_array($function, $callableConstructs);
}

That $callableConstructs array is not complete, look at the List of Keywords page to build it out.

Yes it is hackish, but without a built-in way to do this in PHP I don't see another option.

Note that just because you can call something like a function, does not make it a function, nor does it mean that it behaves like a function in other ways.

You cannot call it dynamically:

$var = "empty";
$var('someinput'); // Does NOT work

Nor does this work:

call_user_func('empty', $foo);

You could use it in an eval call, but I hope you understand the huge list of reasons why that can be dangerous.

Sign up to request clarification or add additional context in comments.

3 Comments

But the calling code would need to look like if (canICall('empty')) empty($foo) or if (canICall($func) && $func == 'empty') empty($foo), so... what's the point?
"What's the point?" Again, we're back to his use case. Which we don't know do we? Just trying to answer the simple question...
And IMO the correct answer is to point out that the working of function_exists is correct for a reason... :)
1

Since empty always exists and is a language construct which cannot be called using variable functions, it doubly makes no sense to want to use function_exists on it. Even if function_exists would work, it is not possible to write this code:

$func = 'empty';
if (function_exists($func)) {
    $func($var);
}

The only way to call empty() is to write it literally in your source code. You cannot call it using variable functions any more than you can do that with list() = or /.

The best you could do is:

if (function_exists('empty')) {
    empty($foo);
}

But because empty always exists, what's the point in testing for it?

If you want to make a validation rule, simply write your own function:

function isEmpty($value) {
    return !$value;
}

$rule = 'isEmpty';

This does exactly the same thing.

Or you make empty a special case in your rule execution:

function validate($rule, $value) {
    switch ($rule) {
        case 'empty' :
            return !$value;

        default :
            if (!function_exists($rule)) {
                throw new InvalidArgumentException("$rule does not exist");
            }
            return $rule($value);
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.