1

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?

8
  • 1
    What is the content of $variablename? var_dump($variablename) Commented Dec 14, 2016 at 3:06
  • The exact same. Commented Dec 14, 2016 at 3:10
  • string(22) "'product','dd','lizzy'" Commented Dec 14, 2016 at 3:13
  • There is the error. call_user_func($func_name, $argument1, $argument2) needs the function name as a single string variable. Each argument needs to be an extra argument. You can use use call_user_func_array similar. One argument for the name, one argument as array for all arguments to the user function. Commented Dec 14, 2016 at 3:16
  • i cant imagine why you would ever want to do this. Commented Dec 14, 2016 at 3:19

4 Answers 4

1

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);
Sign up to request clarification or add additional context in comments.

5 Comments

so like every one else has said, no you can't do that.
No, I say: "You can do that. Learn the correct syntax and signature of functions".
you can, if you do it a completely different way, ok that's clear.
Thanks! To put it in layman's terms; while you can put the function name in a variable, it still expects the arguments separate. That makes sense in one way and is completely counter intuitive in another way... but that's life. ;-) I understand newbs asking questions can be annoying, but we all have to learn, and Googling didn't solve this for me, as I was thinking along the wrong lines. You lot gave me that push on the right track I was after. Every answer seems correct and each would have helped me. But the long one got my vote since it will help other newbs best, I think.
It might be counter intuitive to some absolute beginners, however, you will often want want to map an array to the argument list of a specific function. It's in most situations easier to keep it separate. Also the invocation some_func($arg1, $arg2) distinguishes between the function identifier and the argument list. So it's not too counter intuitive once you got it. :)
1

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.

Comments

1

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).

1 Comment

Seeing your subsequent post, it looks like $variablename is a string and that its contents are NOT a function name.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.