【问题标题】:MySQLi bind_param() error [duplicate]MySQLi bind_param()错误[重复]
【发布时间】:2023-03-25 07:59:01
【问题描述】:

我正在尝试创建一个接收查询(sql)和参数(数组)的函数,但我收到此错误:

PHP 警告:mysqli_stmt::bind_param() 的参数 2 应为 一个参考,给定的价值

我的代码是:

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

【问题讨论】:

  • 首先删除email="?"中的引号
  • 引用已删除 @Fred-ii- :)
  • 好的。现在,我不知道您为什么使用 $conn,而您已经将连接声明为 $mysqli = new mysqli,这可能是导致主要问题的原因。
  • @Fred-ii- 如果我直接使用$mysqli 我会收到此错误call_user_func_array() expects parameter 1 to be a valid callback, class 'mysqli' does not have a method 'bind_param'

标签: php mysql mysqli


【解决方案1】:

下面是一些代码,用于在“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;
   }
}

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      相关资源
      最近更新 更多