Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What if call_user_func is supposed to return false?

Tags:

php

The function I'm calling with call_user_func is supposed to return FALSE. So how do I detect errors if the callable is invalid?

(Side note: Why didn't they have this throw an exception rather than return an error code? Or is there a way to "catch" errors? I have an error handle. Should I have it throw exceptions for me?)

like image 570
Eric G Avatar asked Aug 01 '12 21:08

Eric G


2 Answers

If you want to check if the function or method to be called really exists, you can use is_callable before calling call_user_func. You may wrap the whole thing in a function for easy reuse:

function call_uf($fn) {
    if(is_callable($fn)) {
        return call_user_func($fn);
    } else {
        throw new Exception("$fn is not callable");
    }
}

You asked in a comment about why PHP raises errors instead of using exceptions. I think that's because exceptions were introduced only in PHP5, so most PHP functions rely on error reporting. There seems to be a way around that, as the manual indicates:

Internal PHP functions mainly use Error reporting, only modern Object oriented extensions use exceptions. However, errors can be simply translated to exceptions with ErrorException.

like image 76
bfavaretto Avatar answered Oct 04 '22 16:10

bfavaretto


They did not throw Exception because they need keep this function backward compatible. There was no Exception in older PHP versions, PHP < 5.

The boolean return type was "reserved" for function failure report. What you need to do is discover why the function would fail. I guess the only reason it would fail is for invalid arguments.

Maybe wraping it in a safe call would do what you want:

function safe_call_user_func()
{
  $nargs = func_num_args();
  $args = func_get_args();
  if ( $nargs == 0 )
    throw new RuntimeException( 'Require at least the callback param' );
  if ( !is_callable( $args[0] )
    throw new InvalidArgumentException( 'Callback param is invalid' );
  return call_user_func_array( array_shift( $args ), $args );
}
like image 43
cavila Avatar answered Oct 04 '22 15:10

cavila