MySQLi bind_param()错误

时间:2015-03-24 15:15:22

标签: php mysql mysqli

我试图创建一个接收查询(sql)和参数(数组)的函数,但是我收到了这个错误:

  

PHP警告:参数2到mysqli_stmt :: bind_param()应该是   参考,给定值

我的代码是:

function dbRead($query, $param) {
    $mysqli = new mysqli(DB::READ_HOST, DB::READ_USER, DB::READ_PASS, DB::NAME);
    // Check that connection was successful.
    if ($mysqli->connect_error) {
        $result = "Connection error";
    } else {
        // Check that $conn creation succeeded
        if ($conn = $mysqli->prepare($query)) {
            call_user_func_array(array($conn, 'bind_param'), $param);  
            $conn->execute();
            $result = $conn->get_result();
            $result = $result->fetch_array();
            $conn->close();
        } else {
            $result = "Prepare failed";
        }
    }
    $mysqli->close();
    return $result;
}

$test = dbRead('SELECT * FROM user WHERE id=? and email=?', array(123,'example@example.com'))

如果我的功能代码是

function dbRead($query, $param) {
    $mysqli = new mysqli(DB::READ_HOST, DB::READ_USER, DB::READ_PASS, DB::NAME);
    // Check that connection was successful.
    if ($mysqli->connect_error) {
        $result = "Connection error";
    } else {
        // Check that $conn creation succeeded
        if ($conn = $mysqli->prepare($query)) {
            $ref = array();
            foreach ($param as $key => $value) {
                $ref[$key] = &$param[$key];
            }
            call_user_func_array(array($conn, 'bind_param'), $ref);  
            $conn->execute();
            $result = $conn->get_result();
            $result = $result->fetch_array();
            $conn->close();
        } else {
            $result = "Prepare failed";
        }
    }
    $mysqli->close();
    return $result;
}

我收到此错误

  

PHP警告:mysqli_stmt :: bind_param():类型中的元素数   定义字符串不匹配绑定变量的数量

我的PHP版本是5.4.36

2 个答案:

答案 0 :(得分:0)

以下是一些代码,用于将存储在数组中的可变数量的参数绑定到“mysqli”中。查询。

我在一个已被删除的答案中使用它,而不是因为我希望。 ; - /

我还没有对它进行修改以符合这些要求,但希望它能够显示出获得“mysqli”的方法。查询工作。它当时经过测试。

'棘手'部分是获得正确的参考'。

<?php   // Q23967579
  // I used a lot of code from this example: http://www.php.net/manual/en/mysqli-stmt.bind-param.php
session_start();

// show input... delete this line later
var_dump($_POST, __FILE__.__LINE__);

// database connection...
$mysqlDb = mysqli_connect('localhost', 'test', 'test', 'testmysql');

$columns = array('category'     => array('type' => 's', 'test' => ' `category` = ? '),
                  'color'       => array('type' => 's', 'test' => ' `color` = ? '),
                  'pic'         => array('type' => 's', 'test' => ' `pic` = ? '),
                  'size'        => array('type' => 's', 'test' => ' `size` = ? '),
                  'min_price'   => array('type' => 'd', 'test' => ' `price` >= ? '),
                  'max_price'   => array('type' => 'd', 'test' => ' `price` <= ? '),
                );

$params = new BindParam();
$whereClause  = '';
$andLit = ' AND ';

// i choose to drive off the search columns...
foreach ($columns as $searchCol => $selection) {
    if (!empty($_POST[$searchCol])) { // process it
        $value = $_POST[$searchCol];
        if ($value == 'all') { // not needed for the search...
            continue;
        }

        // add it to all the various places
        $whereClause .= (!empty($whereClause) ? $andLit : '') . $selection['test'];
        $params->add($selection['type'], $value);
    }
}

// now build the query...
$sql = 'select * from products '. (!empty($whereClause) ? ' where '. $whereClause : '');
$query = mysqli_prepare($mysqlDb, $sql);
$allOk = call_user_func_array('mysqli_stmt_bind_param', array_merge(array($query), $params->get()));
$allOk = mysqli_execute($query);

$queryResult = mysqli_stmt_get_result($query);
while ($row = mysqli_fetch_assoc($queryResult)) {
    var_dump($row);
}
// end of program
exit;

/* -------------------------------------------------
 * utility classes
 */
class BindParam {
    private $values = array(),
             $types = '';

    public function add( $type, $value ) {
        $this->values[] = $value;
        $this->types .= $type;
    }

    public function get() {
        $out = array();
        $out[] = $this->types;
        foreach($this->values as &$value) {
            $out[] =& $value;
       }
       return $out;
   }
}

答案 1 :(得分:0)

我试图做一些非常相似的事情,并将来自PHP References和bind_param上几个不同帖子的解决方案拼凑在一起。 bind_param示例中可能没有立即清楚的(或者您忘记了)第一个参数是参数类型的string,每个参数一个字符(在您的情况下,可能"is" int string ),你已经知道其余的参数必须是你的第二个函数定义中的引用。

因此,创建参数数组应该是这样的:

$ref = array("is");
foreach ($param as $value)
   $ref[count($ref)] = &$value;

虽然有很多方法可以做到这一点......你应该将参数类型与查询一起传递,但是在类型精确类型时,MySQL似乎很放松。我也更喜欢传递连接,并支持多个结果行,例如

function doRead($conn, $query, $argTypes, $args){
   $success = false;
   $execParams = array($argTypes);
   foreach($args as $a)
      $execParams[count($execParams)] = &$a;

   if (!$stmt = $conn->prepare($query)){
      echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
   }else if (!call_user_func_array(array($stmt, "bind_param"), $execParams)){
      echo "Param Bind failed, [" . implode(",", $args) . "]:" . $argTypes . " (" . $stmt->errno . ") " . $stmt->error;
   } else if (!$stmt->execute()) {
      echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
   } else
      $success = true;

   $ret = array();
   if($success){
      $res = $stmt->get_result();
      while ($row = $res->fetch_array(MYSQLI_ASSOC))
         array_push($ret, $row);
   }
   $stmt->close();
   return $ret;
}