I can not get this to work. I've spent way to many hours on it now.
This works:
$mysqli = new mysqli("localhost", "root", "root", "db");
if(!$mysqli || $mysqli->connect_errno)
{
return;
}
$query_str= "SELECT name FROM table WHERE city IN ('Nashville','Knoxville')";
if($query_prepared && $query_prepared->prepare($query_str))
{
$query_prepared->execute();
But this I can NOT get it to work with a bind_param like this:
$query_str= "SELECT name FROM table WHERE city IN (?)";
$query_prepared = $mysqli->stmt_init();
if($query_prepared && $query_prepared->prepare($query_str))
{
$cities= explode(",", $_GET['cities']);
$str_get_cities= "'".implode("','", $get_cities)."'"; // This equals 'Nashville','Knoxville'
$query_prepared->bind_param("s", $cities);
$query_prepared->execute();
What am I doing wrong?
I've also tried call_user_func_array, but can't seem to get the syntax correct. Any help would be greatly appreciated!
EDIT: I've rigorously tried moskito-x's suggestions and tons of examples listed here and else where on SO and random websites, and nothing works. I think the issue might be PHP 5.4, which is what my MAMP is set to right now.
You can not bind two variables with one question mark
!
For every variable you bind you need one question mark
"bind_param" checks each variable whether it matches the requirements. afterwards the string value is placed between quotes.
This will not work.
"SELECT name FROM table WHERE city IN (?)"; ( becomes too )
$q_prepared->bind_param("s", $cities);
"SELECT name FROM table WHERE city IN ('city1,city2,city3,city4')";
must be.
"SELECT name FROM table WHERE city IN (?,?,?,?)"; ( becomes too )
$q_prepared->bind_param("ssss", $city1,$city2,$city3,$city4);
"SELECT name FROM table WHERE city IN ('city1','city2','city3','city4')";
$query_prepared->bind_param
quotes string params one by one.
And the number of variables and length of string types must match the parameters in the statement.
$query_str= "SELECT name FROM table WHERE city IN ('Nashville','Knoxville')";
will become
$query_str= "SELECT name FROM table WHERE city IN (?,?)";
now bind_param
must be
bind_param("ss",$arg1,$arg2)
with this
$query_str= "SELECT name FROM table WHERE city IN (?)";
and bind_param
with
bind_param("s",$cities)
you get
$query_str= "SELECT name FROM table WHERE city IN ('Nashville,Knoxville')";
That's why an array not works .
The only solution for this fact is call_user_func_array
if you init a statement, following is unnecessary
$query_prepared = $mysqli->stmt_init();
if($query_prepared && $query_prepared->prepare($query_str)) {
This is correct
$query_prepared = $mysqli->stmt_init();
if($query_prepared->prepare($query_str)) {
if you don't want to use call_user_func_array
and you have only a small count of arguments
you can do it with the following code.
[...]
$cities= explode(",", $_GET['cities']);
if (count($cities)>3) { echo "too many arguments"; }
else
{
$count = count($cities);
$SetIn = "(";
for($i = 0; $i < $count; ++$i) {
$code.='s';
if ($i>0) {$SetIn.=",?";} else {$SetIn.="?";}
}
$SetIn.=")";
$query_str= "SELECT name FROM table WHERE city IN ".$SetIn;
// with 2 arguments $query_str will look like
// SELECT name FROM table WHERE city IN (?,?)
$query_prepared = $mysqli->stmt_init();
if($query_prepared->prepare($query_str))
{
if ($count==1) { $query_prepared->bind_param($code, $cities[0]);}
if ($count==2) { $query_prepared->bind_param($code, $cities[0],$cities[1]);}
if ($count==3) { $query_prepared->bind_param($code, $cities[0],$cities[1],$cities[2]);
// with 2 arguments $query_prepared->bind_param() will look like
// $query_prepared->bind_param("ss",$cities[0],$cities[1])
}
$query_prepared->execute();
}
[...]
}
I would suggest you try it with call_user_func_array
to reach.
look for the solution of nick9v
mysqli-stmt.bind-param
use call_user_func_array like this:
$stmt = $mysqli->prepare("INSERT INTO t_file_result VALUES(?,?,?,?)");
$id = '1111';
$type = 2;
$result = 1;
$path = '/root';
$param = array('siis', &$id, &$type, &$result, &$path);
call_user_func_array(array($stmt, 'bind_param'), $param);
$stmt->execute();
printf("%d row inserted. \n", $stmt->effected_rows);
$stmt->close;
The way I did it: prepare the query with all its separate question marks, as well as the type string.
$cities = array('Nashville','Knoxville');
$dibs = '';
$query = "SELECT name FROM table WHERE city IN (";
$marks = array();
foreach ($cities as $k => $city) {
// i,s,b,d type based on the variables to bind.
$dibs .= 's';
array_push($marks, '?');
}
$query .= implode(',', $marks) .')';
Connect.
$mysql = new mysqli($host, $user, $pass, $dbname);
$statement =
$mysql->prepare($query)
OR die(sprintf(
'Query error (%s) %s', $mysql->errno, $mysql->error
))
;
Then you use "..." token / ellipsis (documentation) in order to bind the array.
if ($statement) {
$statement->bind_param($dibs, ...$cities);
$statement->execute();
$statement->close();
}
$mysql->close();
I know it kinda defeats the purpose of binding in order to escape (but at least it works good with a list of integers, i.e. IDs). If you see a way how to improve this approach, feel free to edit/comment.
I was having trouble with this too, and got it working with eval
before finding out that most people are using call_user_func_array
$fields = array('model','title','price'); // fields in WHERE clause
$values = array( // type and value for each field
array('s','ABCD-1001'),
array('s','[CD] Test Title'),
array('d','16.00')
);
$sql = "SELECT * FROM products_info WHERE "; // start of query
foreach ($fields as $current){ // build where clause from fields
$sql .= '`' . $current . '` = ? AND ';
}
$sql = rtrim($sql,'AND '); // remove last AND
$stmt = $db->prepare($sql);
$types = ''; $vals = '';
foreach ($values as $index => $current_val){ // build type string and parameters
$types .= $current_val[0];
$vals .= '$values[' . $index . '][1],';
}
$vals = rtrim($vals,','); // remove last comma
$sql_stmt = '$stmt->bind_param("' . $types . '",' . $vals . ');'; // put bind_param line together
eval($sql_stmt); // execute bind_param
$stmt->execute();
$stmt->bind_result($col1,$col2,$col3,$col4,$col5,$col6); // this could probably also be done dynamically in the same way
while ($stmt->fetch()){
printf("%s %s %s %s %s %s\n", $col1,$col2,$col3,$col4,$col5,$col6);
}
来源:https://stackoverflow.com/questions/17226762/mysqli-bind-param-for-array-of-strings