Php 字符串数组的mysqli bind_参数

Php 字符串数组的mysqli bind_参数,php,mysqli,bindparam,Php,Mysqli,Bindparam,我不能让它工作。我已经花了好几个小时在这上面了 这项工作: $mysqli = new mysqli("localhost", "root", "root", "db"); if(!$mysqli || $mysqli->connect_errno) { return; } $query_str= "SELECT name FROM table WHERE city IN ('Nashville','Knoxville')"; $query_prepared = $mysqli-&

我不能让它工作。我已经花了好几个小时在这上面了

这项工作:

$mysqli = new mysqli("localhost", "root", "root", "db");
if(!$mysqli || $mysqli->connect_errno)
{
    return;
}
$query_str= "SELECT name FROM table WHERE city IN ('Nashville','Knoxville')";
$query_prepared = $mysqli->stmt_init();
if($query_prepared && $query_prepared->prepare($query_str))
{       
    $query_prepared->execute();
但我不能让它与这样的绑定参数一起工作:

$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();
$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;
我做错了什么?

我还尝试了
调用用户函数数组
,但语法似乎不正确

编辑:

我已经严格地尝试了moskito-x的建议和这里列出的大量示例,以及其他一些随机网站上列出的示例,但没有任何效果。我认为问题可能是PHP5.4,这就是我的MAMP现在设置的

不能用一个
问号绑定两个变量

对于绑定的每个变量,都需要一个
问号

“bind_param”检查每个变量是否符合要求。之后,字符串值放在引号之间

这是行不通的

"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')";
一定是

"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\u prepared->bind\u param
逐个引用字符串参数。
变量的数量和字符串类型的长度必须与语句中的参数匹配

$query_str= "SELECT name FROM table WHERE city IN ('Nashville','Knoxville')";
将成为

$query_str= "SELECT name FROM table WHERE city IN (?,?)";
现在
bind_param
必须

bind_param("ss",$arg1,$arg2)
用这个

$query_str= "SELECT name FROM table WHERE city IN (?)";
bind_param
with

bind_param("s",$cities)
你得到

$query_str= "SELECT name FROM table WHERE city IN ('Nashville,Knoxville')";
这就是数组不起作用的原因。
解决这个问题的唯一办法是调用用户函数数组

$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);
}
如果初始化一个语句,则不需要执行以下操作

$query_prepared = $mysqli->stmt_init();
if($query_prepared && $query_prepared->prepare($query_str)) {
这是正确的

$query_prepared = $mysqli->stmt_init();
if($query_prepared->prepare($query_str)) {
如果不想使用
调用\u user\u func\u数组

您只有少量的参数
您可以使用以下代码来完成

[...]
$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();
  } 
 [...]
 }
[…]
$cities=explode(“,”,$_GET['cities');
如果(count($cities)>3{echo“太多参数”;}
其他的
{ 
$count=count($cities);
$SetIn=“(”;
对于($i=0;$i<$count;++$i){
$code.='s';
如果($i>0){$SetIn.=“,?”;}其他{$SetIn.=“?”;}
}
$SetIn.=”;
$query\u str=“从“$SetIn”中城市所在的表中选择名称;
//有两个参数$query\u str如下所示
//从城市所在的表中选择名称(?,)
$query_prepared=$mysqli->stmt_init();
如果($query\u prepared->prepare($query\u str))
{       
如果($count==1){$query_prepared->bind_param($code$cities[0])}
如果($count==2){$query_prepared->bind_param($code,$cities[0],$cities[1])}
如果($count==3){$query_prepared->bind_param($code,$cities[0],$cities[1],$cities[2]);
//有两个参数$query\u prepared->bind\u param()如下
//$query\u prepared->bind\u参数(“ss”、$cities[0]、$cities[1])
}    
$query_prepared->execute();
} 
[...]
}
我建议您尝试使用
call\u user\u func\u array
来访问

寻找
nick9v的解决方案


我在这方面也遇到了问题,在发现大多数人都在使用
call\u user\u func\u 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);
}

像这样使用call\u user\u func\u数组:

$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();
$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;

我的方法是:用所有单独的问号以及类型字符串准备查询

$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) .')';
连接

$mysql = new mysqli($host, $user, $pass, $dbname);
$statement =
    $mysql->prepare($query)
OR  die(sprintf(
        'Query error (%s) %s', $mysql->errno, $mysql->error
    ))
;
然后使用“…”标记/省略号()绑定数组

if ($statement) {
    $statement->bind_param($dibs, ...$cities);
    $statement->execute();

    $statement->close();
}
$mysql->close();

我知道它有点违背了为了逃避而绑定的目的(但至少它可以很好地处理整数列表,即id)。如果您看到了改进这种方法的方法,请随意编辑/评论。

这是我在将表单输入命名为与mysql列名相同的名称后所做的

$post_fields = array_keys($_POST);
$post_values = array_values($_POST);

$fields_type_i = array("age","age_share","gender_share");  // all mysql col names type int

$fields = "";           // user input fields
$values = "";           // user input vals
$placeholders = "";     // ?,?,?
$params_type = "";      // s=string i=integer

foreach ($post_fields as $field) {
    $fields .= "`".$field."`,"; 
}


这项任务有点复杂,但可行。我将从我的文章中得到解释:

  • 首先,我们需要创建一个字符串,该字符串中的
    标记与数组中的元素数量相同。为此,我们将使用非常方便的
    str\u repeat()
    函数
  • 然后,必须将带有逗号分隔问号的字符串添加到查询中。虽然它是一个变量,但在本例中它是安全的,因为它只包含常量值
  • 然后,必须像准备任何其他查询一样准备此查询
  • 然后我们需要创建一个字符串,该字符串的类型将与bind_param()一起使用。请注意,通常没有理由对绑定变量使用不同的类型-mysql会乐意将它们全部作为字符串接受。有边缘病例,但极为罕见。对于日常使用,您可以始终保持简单,并使用“s”表示所有内容<代码>str_repeat()
再次被拯救
  • 然后我们需要将数组值绑定到语句。不幸的是,您不能将其作为单个变量来编写,就像这样
    $stmt->bind_-param(“s”,$array)
    ,在
    bind_-param()
    中只允许使用标量变量。幸运的是,有一个函数正好满足我们的需要——将一个值数组发送到一个函数中,就好像它是一组不同的变量一样
  • 其余的一切照常进行-执行查询,获取结果并获取数据 因此正确的示例代码是

    $array = ['Nashville','Knoxville']; // our array
    $in    = str_repeat('?,', count($array) - 1) . '?'; // placeholders
    $sql   = "SELECT name FROM table WHERE city IN ($in)"; // sql
    $stmt  = $mysqli->prepare($sql); // prepare
    $types = str_repeat('s', count($array)); //types
    $stmt->bind_param($types, ...$array); // bind array at once
    $stmt->execute();
    $result = $stmt->get_result(); // get the mysqli result
    $data = $result->fetch_all(MYSQLI_ASSOC); // fetch the data   
    

    尽管这段代码相当大,但它比目前为止本主题中提供的任何其他可行解决方案都要小得多。

    可能重复的可能重复您看到我的答案了吗?@moskito-x是的,它对我不起作用。
    $str_get_cities=“”。内爆(“,”,$get_cities)。“。不要使用引号!!这是通过使用“s”选项绑定参数来完成的!你建议使用
    call\u user\u func\u array
    ,但你从来没有在这里展示过怎么做这里是call_user_func_array()的一个用例,解释了整个问题“在结合call_user_func_array()使用mysqli_stmt_bind_param()时必须小心。请注意,mysqli_stmt_bind_param()需要通过引用传递参数,而call_user_func_array()需要通过引用传递参数可以接受变量列表作为参数,这些变量可以表示引用或值。“源->如果您在文档中添加更多解释和源,那么这肯定会被接受!回答得好!这不起作用,所有参数都必须是引用。因此,您需要将格式定义为