Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable parameter/result binding with prepared statements

Tags:

php

mysql

mysqli

In a project that I'm about to wrap up, I've written and implemented an object-relational mapping solution for PHP. Before the doubters and dreamers cry out "how on earth?", relax -- I haven't found a way to make late static binding work -- I'm just working around it in the best way that I possibly can.

Anyway, I'm not currently using prepared statements for querying, because I couldn't come up with a way to pass a variable number of arguments to the bind_params() or bind_result() methods.

Why do I need to support a variable number of arguments, you ask? Because the superclass of my models (think of my solution as a hacked-up PHP ActiveRecord wannabe) is where the querying is defined, and so the find() method, for example, doesn't know how many parameters it would need to bind.

Now, I've already thought of building an argument list and passing a string to eval(), but I don't like that solution very much -- I'd rather just implement my own security checks and pass on statements.

Does anyone have any suggestions (or success stories) about how to get this done? If you can help me solve this first problem, perhaps we can tackle binding the result set (something I suspect will be more difficult, or at least more resource-intensive if it involves an initial query to determine table structure).

like image 501
Brian Warshaw Avatar asked Aug 15 '08 19:08

Brian Warshaw


People also ask

Which function bind variables to prepared statement as parameter?

$stmt->bind_param("sss", $firstname, $lastname, $email); This function binds the parameters to the SQL query and tells the database what the parameters are.

What do you understand by prepared and bind parameters statement?

Prepare is followed by execute. During execute the client binds parameter values and sends them to the server. The server executes the statement with the bound values using the previously created internal resources. A prepared statement can be executed repeatedly.

How do you bind variables in SQL query?

Use a bind variable in PL/SQL to access the variable from SQL*Plus. Bind variables are variables you create in SQL*Plus and then reference in PL/SQL. If you create a bind variable in SQL*Plus, you can use the variable as you would a declared variable in your PL/SQL subprogram and then access the variable from SQL*Plus.

What is a binding parameter?

A parameter binding is a piece of information that is transmitted from the origin to the destination of a flow. A parameter binding has a name and a value, which is obtained at its origin component. A flow may have a multiple parameter binding, passing a set of values instead of a single one.


3 Answers

The more modern way to bind parameters dynamically is via the splat/spread operator (...).

Assuming:

  • you have a non-empty array of values to bind to your query and
  • your array values are suitably processed as string type values in the context of the query and
  • your input array is called $values

Code for PHP5.6 and higher:

$stmt->bind_param(str_repeat('s', count($values)), ...$values);

In fact, all of the arguments fed to bind_param() can be unpacked with the splat/spread operator if you wish -- the data types string just needs to be the first element of the array.

array_unshift($values, str_repeat('s', count($values)));
$stmt->bind_param(...$values);
like image 117
mickmackusa Avatar answered Oct 19 '22 19:10

mickmackusa


You've got to make sure that $array_of_params is array of links to variables, not values themselves. Should be:

$array_of_params[0] = &$param_string; //link to variable that stores types

And then...

$param_string .= "i";
$user_id_var = $_GET['user_id'];//
$array_of_params[] = &$user_id_var; //link to variable that stores value

Otherwise (if it is array of values) you'll get:

PHP Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference


One more example:

$bind_names[] = implode($types); //putting types of parameters in a string
for ($i = 0; $i < count($params); $i++)
{
   $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3...
   $$bind_name = $params[$i]; //create a variable with this name and put value in it
   $bind_names[] = & $$bind_name; //put a link to this variable in array
}

and BOOOOOM:

call_user_func_array( array ($stmt, 'bind_param'), $bind_names); 
like image 37
zhikharev Avatar answered Oct 19 '22 17:10

zhikharev


In PHP you can pass a variable number of arguments to a function or method by using call_user_func_array. An example for a method would be:

call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);

The function will be called with each member in the array passed as its own argument.

like image 35
John Downey Avatar answered Oct 19 '22 18:10

John Downey