David Dylan
David Dylan

Reputation: 214

php call_user_func variable error

I'm just feeling my way around with some tests to get an idea of how to tackle a coding issue. Now, I'm getting behavior I don't understand.

function product($a, $b) {
echo "Yo ".$a;
echo "Yo ".$b;
}

call_user_func('product', 'dd', 'lizzy');

The above works, however,

$variablename = "'product','dd','lizzy'";
call_user_func($variablename);

throws an error:

Warning: call_user_func() expects parameter 1 to be a valid callback, function ''product','dd','lizzy'' not found or invalid function name

Obviously $variablename contains the same values.

Anyone any hint for me to put me back on track?

Upvotes: 1

Views: 2507

Answers (4)

Pinke Helga
Pinke Helga

Reputation: 6682

Pay attention to the signature of call_user_func and call_user_func_array.

function product($a, $b) {
  echo "Yo ".$a;
  echo "Yo ".$b;
  echo "<br>\n";
}

// there are 3 single arguments
call_user_func('product', 'dd', 'lizzy');

// the same with variables
$fn_name = 'product';
$arg1    = 'dd';
$arg2    = 'lizzy';

call_user_func($fn_name, $arg1, $arg2);

// or give ARGUMENS ONLY as array, but function name as string scalar
$args    = array($arg1, $arg2);
call_user_func_array($fn_name, $args);

// if you for some reason need to handle a single array for the name and arguments in one,
// you need to write your own function:
function call_user_func_array2($call_info)
{
  $fn_name = array_shift($call_info);  //extract first item
  call_user_func_array($fn_name, $call_info);
}

$call_info = array($fn_name, $arg1, $arg2);
call_user_func_array2($call_info);

In addition we can extend the code above to process on a given string "'product','dd','lizzy'". (e.g. in situations when it is stored in this form in some database)

You first need to extract the comma separated values in this string. You can achieve this by str_getcsv or more flexible by a regular expression. Let's say it is separated by comma with optional whitespaces and enclosed in single or double qoutes. The regex could look like: (?:^|,)\s*(['"])(.+?)\1\s*?(?=,|$). The 2nd subpatter (.+?) will capture everything inside the single/double quotes.

Combined with call_user_func_array2 it looks like that:

function call_user_func_string($call_info)
{
  if(!preg_match_all('~(?:^|,)\s*([\'"])(.+?)\1\s*?(?=,|$)~u', $call_info, $matches))
    throw new Exception("call_user_func_string expects parameter 1 to be a string like `'functionname','arg1','arg2' [,...]` "
                      . 'or `"functionname","arg1","arg2" [,...]`.');

  call_user_func_array(array_shift($matches[2]), $matches[2]);
}


// some differently formatted examples

$my_string = "'product','dd','lizzy'";
call_user_func_string($my_string);

$my_string = '  "product"  ,  "dd"  ,  "lizzy"  ';
call_user_func_string($my_string);

$my_string = <<<'_END_'
    'product'   ,   "dd",'lizzy'    ,"lucy's cat"   
_END_;

call_user_func_string($my_string);

Upvotes: 1

weirdo
weirdo

Reputation: 334

From the error telling;

the first argument need to be valid callback/function name.

when you set $variablename like you mention above, sure it will be trown a error.

"'product', 'dd', 'lizzy' it not a valid callback name in your case.

Upvotes: 1

S. Imp
S. Imp

Reputation: 2895

If you look at the PHP Docs on call_user_func, you should see that it requires at least one parameter -- and that first parameter has to be of type callable.

Obviously $variablename contains the same values.

Not sure how this is obvious. Nothing in your code defines this value. It should specify some function or object-and-method (see the callable link above).

Upvotes: 1

cFreed
cFreed

Reputation: 4474

Adding what you didn't precisely show, your 2nd try looks like this:

$variablename = "'product', 'dd', 'lizzy'";
call_user_func($variablename);

When executing the 2nd line, $variablename is the only argument, while call_user_func() expects three.

And so the error you get is pretty normal!
Definetly you can't expect one argument to be "dispatched" into several ones.

Upvotes: 1

Related Questions