How do I write a function that can accept unlimited number of parameters?
What am trying to do is create a function within a class that wraps the following:
Have you taken a look at func_get_args, func_get_arg and func_num_args
So for example:
function foo(){
if ( func_num_args() > 0 ){
var_dump(func_get_args());
}
}
or:
function bind_param(){
if ( func_num_args() <= 1 ){
return false; //not enough args
}
$format = func_get_arg(0)
$args = array_slice(func_get_args(), 1)
//etc
}
EDIT
Regarding Ewan Todds comment:
I don't have any knowlege of the base API you are creating the wrapper for, but another alternative may be to do something with chaining functions so your resulting interface looks something like:
$var->bind()->bindString($code)
->bindString($language)
->bindString($official)
->bindDecimal($percent);
Which I would prefer over the use of func_get_args as the code is probably more readable and more importantly less likely to cause errors due to the the lack of a format variable.
At 5 parameters, this design is starting to exhibit the AntiPattern "Too Many Parameters". This suggests the refactoring called Parameter Object, an object or structure with data members representing the arguments to be passed in. However, avoid making it a Magic Container.
See also Introduce Parameter Object refactoring at refactoring.com.
The answers with func_get_args() will work fine for non-reference parameters. However, there's a trick to getting passed-by-reference parameters to work. Also, it's not technically a function which accepts unlimited parameters, but simply some arbitrarily large number, say one hundred.
What you can do, is define a function which takes a large number of arguments, and have them default to null. Then, inside that function, append each non-null reference to an array, which would then be used to call *bind_param()* using *call_user_func_array()*.
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...)
{
$vars = array($types);
$vars[] = $arg1;
if ($arg2 != null)
$vars[] = &$arg2;
if ($arg3 != null)
$vars[] = &$arg3;
...
if (!call_user_func_array(array($stmt, "bind_param"), $vars))
{
if ($stmt->errno == 0)
return array(-1, "Unknown error binding parameters.");
else
return array(-1, "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error);
}
return array(0, "");
}
The real trick is that you don't want to write this thing by hand. Just make another script which will output the body of this function (everything between the squiggle brackets) as *my_bind_param_body.php*. Then, just define the header of the function in your main file, and include the body into that function definition. i.e.
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...)
{
return include "my_bind_param_wrapper_body.php";
}
Use func_get_args():
function my_func() {
$args = func_get_args();
foreach ($args as $arg) {
echo "Arg: $arg\n";
}
}
The above suggests are all good, but I don't think they will be suitable for your situation.
$stmt->bind_param('sssd', $code, $language, $official, $percent);
If you want to wrap this function, you will need to pass references to the original argument variables to the bind_param function. I don't think func_get_args() gives you this, it gives you values instead. Thus it won't be possible to use these to pass to the parent function. I battled with a similar issue when trying to extend mysqli_stmt and never came to satisfactory solution.
This is not really an answer to your question I'm afraid, just a warning that other arguments may not work in your particular application of arbitrary number of arguments.
Previously you should have used func_get_args(), but in the php 5.6, you can use ... operator.
So for example you can write the function which returns you a sum of all the numbers, sent to the function:
function bind_param(...$params){
var_dump($params);
}
Your params is actually an array of all elements.