为了账号安全,请及时绑定邮箱和手机立即绑定

mysqli bind_param用于字符串数组

mysqli bind_param用于字符串数组

忽然笑 2019-11-20 14:24:58
我无法使它正常工作。我现在花了很多时间在上面。这有效:$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();但这我不能让它与这样的bind_param一起工作:$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();我究竟做错了什么?我也尝试过call_user_func_array,但似乎无法正确获取语法。编辑:我已经严格尝试过moskito-x的建议和此处列出的大量示例,以及在SO和随机网站上的其他示例,没有任何效果。我认为问题可能出在PHP 5.4上,这就是我的MAMP现在设置的
查看完整描述

3 回答

?
大话西游666

TA贡献1817条经验 获得超14个赞

您不能将两个变量绑定为一个question mark!


对于您绑定的每个变量,您都需要一个 question mark


“ 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_prepared->bind_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用


bind_param("s",$cities)

你得到


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

这就是为什么数组不起作用的原因。

解决这个问题的唯一方法是call_user_func_array


如果您初始化一条语句,则不需要进行以下操作


$query_prepared = $mysqli->stmt_init();

if($query_prepared && $query_prepared->prepare($query_str)) {

这是对的


$query_prepared = $mysqli->stmt_init();

if($query_prepared->prepare($query_str)) {

如果您不想使用call_user_func_array

并且只有少量参数

,则可以使用以下代码来实现。


[...]

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

  } 

 [...]

 }

我建议您尝试一下call_user_func_array。


寻找mysqli-stmt.bind-param的解决方案nick9v


查看完整回答
反对 回复 2019-11-20
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

像这样使用call_user_func_array:


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


查看完整回答
反对 回复 2019-11-20
?
噜噜哒

TA贡献1784条经验 获得超7个赞

通常情况下,这个问题太老了,无法提供远程可靠的解决方案,但Google仍将访客发送到这里。所以这是2019年及以后的答案。


我将从Mysqli准备的语句中为IN子句添加多个值的方式进行解释:


首先,我们需要创建一个字符串,该字符串的?标记与数组中元素的数量一样多。为此,我们将使用str_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)"; 

$stmt  = $mysqli->prepare($sql);

$types = str_repeat('s', count($array)); 

$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   

尽管此代码很大,但与迄今为止在本主题中提供的任何其他合理的解决方案相比,它是无与伦比的。


查看完整回答
反对 回复 2019-11-20
  • 3 回答
  • 0 关注
  • 717 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信