Search code examples
phpprepared-statementbindparam

Possible to pass string of variables: to stmt->bind_param()?


Im in a situation where a mysqli query is created dynamically from $_GET values, which are always changing depending on the custom searches made . Would it be possible to pass a correctly formatted (and dynamically created) string to show the different variables in question.

Example: $variabletypelist = "sss"; $variablestring = "$dogs, $cats, $weasels";

$stmt->bind_param($variabletypelist, $variablestring);

So that the end result would look similar to

stmt->bind_param($variabletypelist,$dogs, $cats, $weasels)

I realise there is this a problem since $variablestring is being taken as the variable to be bound to instead of binding to $dogs, $cats, $weasels.

Is there any simple way to do this with a string for the variables?


Solution

  • There's a number of solutions to call mysqli_stmt::bind_param with a dynamic number of parameters, none of them involve describing a list as a string, that's just dumb. When you need a list, you use an array.

    You can use call_user_func_array() to call any function in PHP specifying the parameters it should be called with in an array. It creates a problem though because the paramters of mysqli_stmt::bind_param have to be passed as reference and not by value, but workarounds can be made.

    Example:

    $vars = [$dogs, $cats, $weasels];
    $refs = [$variabletypelist];
    
    foreach ($vars as &$val)
        $refs[] = &$val;
    call_user_func_array([$stmt, 'bind_param'], $refs);
    

    You can also use the non-oop version of this method if this syntax looks confusing to you:

    $vars = [$dogs, $cats, $weasels];
    $refs = [$stmt, $variabletypelist];
    
    foreach ($vars as &$val)
        $refs[] = &$val;
    call_user_func_array('mysqli_stmt_bind_param', $refs);
    

    It can also be done with ReflectionClass() that (I didn't test) apparently doesn't require fixing references:

    $vars = [$dogs, $cats, $weasels];
    
    $ref = new \ReflectionClass('mysqli_stmt');
    $met = $ref->getMethod('bind_param');
    $met->invokeArgs($stmt, array_merge([$variabletypelist], $vars));