多次调用$ stmt-> bind_param

时间:2016-08-09 18:14:45

标签: php mysqli prepared-statement bindparam

我遇到的情况是我想构建一个以这种格式获取$bindParam变量的代码:

$bindParams = [$type1 => $param1, $type2 => $param2, ... ]

我想构建一些代码,将这些参数动态添加到预准备语句中 这是我到目前为止构建的代码:

$mysql = new mysqli("localhost", "root", "", "db1");
$stmt = $mysql->prepare($sql);
foreach($bindParams as $type => $data) {
    $stmt->bind_param($type, $data);
}
$stmt->execute();
$result = $stmt->get_result();
// and after perhaps twiddling with the result set, but this is not the case .....

对于您的实例

$sql = "INSERT INTO table1 (name, age) VALUES (?,?);"

$bindParams = ["s" => "hello", "i" => 15] 

这并不总是具有此结构,并且可以更改为$bindParams = ["s" => "hello", "i" => 15, "d" => 22.5],因此$sql会分别发生变化。

第一次编译器转到$stmt->bind_param($type, $data);之后,firefox刷新了这个错误:

  

警告:mysqli_stmt :: bind_param():变量数量与第23行D:\ PHP \ tr.php中预准备语句中的参数数量不匹配

我知道PDO支持如here at the end of the page.所述,但也许正如您所料,我不是PDO的粉丝所以;)
我的另一个选择是使用php中提供的eval()变通办法,但这可能是我想到的。

还有其他办法吗?

3 个答案:

答案 0 :(得分:9)

我遇到了同样的问题,并且找到了一个更简单的答案:

$array_of_values = array( "Brasil", "Argentina" );
$types = "ss";
$mysqli_stmt->bind_param( $types, ...$array_of_values );

这称为"参数解包",自PHP 5.6起可用

答案 1 :(得分:8)

可悲的是mysqli不支持这一点。一遍又一遍地调用函数会覆盖这些值,所以当你有更多时,你只能绑定一个参数。

有几种方法可以解决这个问题

  1. 切换到PDO。您可以使用
  2. 为每个函数调用创建一个绑定
  3. 使用call_user_func_array

    将params绑定为一个聚合
    $sqltype = '';
    $sqldata = [];
    foreach($bindParams as $type => $data) {
        $sqltype .= $type;
        $sqldata[] = &$data; // MUST be a reference
    }
    array_unshift($sqldata, $sqltype); // prepend the types
    call_user_func_array([$stmt, 'bind_param'], $sqldata);
    

答案 2 :(得分:1)

我使用类似的东西来进行动态过程调用。

呼叫示例:

    $mapi = new MySQLIAPI($con);
    $mapi->BeginProc();
    $mapi->AddParameter("user", $usern, "s");
    $mapi->AddParameter("email", $email, "s");
    $mapi->AddParameter("passwd", $pwd, "s");
    $id = $mapi->CallProc("ij_create_user");
    $id = $id[0];

    if(isset($id['mysql_error']) || isset($id["error"])){
      return "error";
    }
    return $id["id"];

示例类:

class MySQLIAPI
{
    private $con = null;
    private $Variables = null;
    private $values = null;
    private $types = null;
    private $vQu = null;
    private $stmt = null;
    function __construct($dbc)
    {
        $this->con = $dbc;
            $this->Variables = [];
        $this->values = [];
        $this->types = [];
        $this->vQu = [];
    }
    function BeginProc()
    {
        $this->stmt = $this->con->stmt_init(); // initialize statement
    }

    function AddParameter($key, $val, $type)
    {
        $this->Variables[] = "@" . $key;
        $this->values[]    = $val;
        $this->types[]     = $type;
        $this->vQu[]       = "?";
    }

    //KeyPair is v = the value, t = the type s or d
    function CallProc($Proc) {
      $out_var = null;

      $call = "";
      if(sizeof($this->values) > 0)
        $call = "CALL ".$Proc."(".implode(",", (array)$this->vQu).")";
      else
        $call = "CALL ".$Proc."()";

     if($this->stmt->prepare($call));//call stored procedure with database server session variable
     {
       if(sizeof($this->values) > 0) {
         $params = array_merge(array(implode("", $this->types)), $this->values);
         call_user_func_array(array($this->stmt, 'bind_param'), $this->refValues($params));
       }

       $this->stmt->execute();
       $result = $this->stmt->get_result();

       /* Error Checking */
       $mySQLiError = mysqli_stmt_error($this->stmt);
       if ($mySQLiError != "") {
         $this->resetStmt();
         $this->stmt->close();
         $this->stmt = null;
         return array('mysql_error' => $mySQLiError);
       }

       while ($row = $result->fetch_array(MYSQLI_ASSOC))
       {
         $out_var[] = $row;
       }
       $result->free();
       while($this->stmt->more_results())
       {
         $this->stmt->next_result();
       }

       $this->resetStmt();
       $this->stmt->close();
       $this->stmt = null;
     }

     return $out_var;
    }
    private function refValues($arr)
    {
        if (strnatcmp(phpversion(), '5.3') >= 0) //Reference is required for PHP 5.3+
            {
            $refs = array();
            foreach ($arr as $key => $value)
                $refs[$key] =& $arr[$key];
            return $refs;
        }
        return $arr;
    }
    private function resetStmt()
    {
        //Reset Params
        $this->Variables = array();
        $this->values    = array();
        $this->types     = array();
        $this->vQu       = array();
    }
}