Sending an array of parameters to bind_param

2019-09-15 07:38发布

问题:

I have the parameters to send to a prepared statement in an array, I am using call_user_func_array and using it as such call_user_func_array(array($stmt, "bind_param"), array_merge(array($types), $params_fixed)), where $types contains the types and $params_fixed contains the parameters.

I ran it and got the error Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in ..., I searched for this error and an answer was to send the parameters by reference so I added an ampersand before the $params_fixed parameter however now I get the error Fatal error: Call-time pass-by-reference has been removed in ....

How can I resolve this issue? What am I missing here?

NOTE: Before learning I had to use call_user_func_array, I was using it as such $stmt->bind_param($types, ...$params_fixed)

NOTE 2: below is the code for filling the array to send

    $params_fixed = array();
    $types = "";
    if($param_count > 0) {
      foreach($params as $param) {
        switch(gettype($param)) {
          case "boolean":
            $types = $types . "i";
            $params_fixed[] = $param ? 1 : 0;
            break;
          case "integer":
            $types = $types . "i";
            $params_fixed[] = &$param;
            break;
          case "double":
            $types = $types . "d";
            $params_fixed[] = &$param;
            break;
          case "string":
            $types = $types . "s";
            $params_fixed[] = &$param;
            break;
          default:
            $types = $types . "s";
            $params_fixed[] = null;
            break;
        }
      }
    }

NOTE 3: below is the code in question

public function query($sql, ...$params) {
  $param_num_sql = substr_count($sql, "?");
  $param_count = count($params);

  if($param_num_sql != $param_count) {
    $this->error = 'parameters don\'t match';
    return null;
  }

  $params_fixed = array();
  $types = "";
  if($param_count > 0) {
    foreach($params as $param) {
      $types = $types . "s";
      $params_fixed[] = &$param;

      // switch(gettype($param)) {
      //   case "boolean":
      //     $types = $types . "i";
      //     $params_fixed[] = $param ? 1 : 0;
      //     break;
      //   case "integer":
      //     $types = $types . "i";
      //     $params_fixed[] = $param;
      //     break;
      //   case "double":
      //     $types = $types . "d";
      //     $params_fixed[] = $param;
      //     break;
      //   case "string":
      //     $types = $types . "s";
      //     $params_fixed[] = $param;
      //     break;
      //   default:
      //     $types = $types . "s";
      //     $params_fixed[] = null;
      //     break;
      // }
    }
  }

  if($param_num_sql == 0) {
    $result = $this->conn->query($sql);
  } else {
    $stmt = $this->conn->prepare($sql);

    //call_user_func_array(array($stmt, "bind_param"), array_merge(array($types), $params_fixed));

    //if(!$stmt->bind_param($types, ...$params_fixed)) {


echo "<br/>types: $types<br/>";
echo '<br/>';
print_r($params_fixed);
echo '<br/>';


    if(!call_user_func_array(array($stmt, "bind_param"), array_merge(array($types), $params_fixed))) {
      // an error occurred
    }

    $stmt->execute();

    $result = $stmt->get_result();

    $stmt->close();
  }

  if($result != null && $result->num_rows > 0)
    return $result->fetch_all();
  else
    return null;
}

and below is the code calling this method

$dbcon->query($query, $fname, $mname, $lname, $dob, $mobile, $home, $email, $area, $city, $street, $bldg, $floor, $car_capacity, $status, $prefer_act, $volunteer_days, $backup_days);

回答1:

try like this

        $mysqli = new mysqli('localhost', 'root','','mydb');

        $stmt=$mysqli->prepare("select * from blog where id=? and date=?");
            $title='1';
            $text='2016-04-07';
        call_user_func_array(array($stmt, "bind_param"),array_merge(array('ss'),array(&$title,&$text)));
        $stmt->execute();
        $result = $stmt->get_result();
        print_r($result->fetch_array());
        echo $stmt->error;

ok if you have parameters coming from the array

        $mysqli = new mysqli('localhost', 'root','','jobspace');

        $stmt=$mysqli->prepare("select * from listings where listing_type_sid=? and user_sid=?");
            $title='6';
            $text='8';
            $arr=array($title,$text);
            foreach($arr as &$ar){
               $new[]=&$ar;
            }
        $types = implode(array_fill(0,count($arr),'s'));        
        call_user_func_array(array($stmt, "bind_param"),array_merge(array($types),$new));
        $stmt->execute();
        $result = $stmt->get_result();
        print_r($result->fetch_array());
        echo $stmt->error;