在 $bind_param() 中动态绑定参数; mysqli

Posted

技术标签:

【中文标题】在 $bind_param() 中动态绑定参数; mysqli【英文标题】:Dynamically bind params in $bind_param(); Mysqli 【发布时间】:2015-12-10 08:31:09 【问题描述】:

我有一个 DB 类,它处理所有的查询都将对数据库进行 我有 mysqli 准备工作正常。 bind_param 也可以正常工作,但问题是我想动态定义变量类型。 这是我的代码

public function query($sql, $params = array())
        $this->_error = false;
        if($this->_query = $this->_mysqli->prepare($sql))
            $x = 1;
            if(count($params))
                foreach($params as $param)
                    $this->_query->bind_param($x, $param);
                    $x++;
                
            

IN PDO 拳头参数定义了我猜的位置,所以这个函数通过每次设置 X = 1 和 x++ 运行良好, 但在bind_param 第一个参数定义类型我猜 正如 php.net 手册所说 如果用户推动我设置的积分值,有什么办法吗 x = 我 对于字符串 x = 小号 依此类推,适用于所有 4 种类型...

喜欢

if((int)$param->)
    x = i;

有想法的人吗?

提前致谢

【问题讨论】:

在 PDO 中,我通过在开始时说 x = 1 表示第一个占位符来完成它。最后我说 x++ 意味着下一次 x = 2 所以发送时间它将绑定到第二个参数。但我同意你关于 mysqli 的看法,所以我可以在下面使用你定义的方法吗?这完全替代了我的问题? 【参考方案1】:

对于类型,这很容易。一直使用s

还有一个复杂得多的问题:实际上不能循环绑定,所以必须使用call_user_func()

public function query($sql, $params = array())

    if (!$params)
    
        return $this->_mysqli->query($sql);
    
    $stmt = $this->_mysqli->prepare($sql);
    $types = str_repeat("s", count($params));

    if (strnatcmp(phpversion(),'5.3') >= 0)
    
        $bind = array();
        foreach($values as $key => $val)
        
            $bind[$key] = &$params[$key];
        
     else 
        $bind = $values;
    

    array_unshift($bind, $types);
    call_user_func_array(array($stmt, 'bind_param'), $bind);

    $stmt->execute();
    return $stmt->get_result();

请注意,您不应将语句分配给局部变量,并且错误变量也没有用处。例外在各方面都更好。

看上面的代码你在翻PDO之前应该三思而后行,这样的功能只需要三行:

public function query($sql, $params = array())

    $stmt = $this->_pdo->prepare($sql);
    $stmt->execute($params);
    return $stmt;

如果您没有使用 PDO 的经验,这里是我写的 PDO tutorial,您将从中了解到它是最简单但功能最强大的数据库 API,只需很少的代码即可获取数十种不同格式的数据。

【讨论】:

如果我也用 s 表示积分? 我在 PDO 中没有命令这就是我选择 mysqli 的原因,因为我比 PDO 更了解你的建议?【参考方案2】:

这是一个可以提供帮助的示例(prepare() 函数是一个类方法)。

function prepare( $query, $bind = array() )
   
    if ( !$stmt = $this->mysqli->prepare( $query ) ) 
        throw new Exception( 'Query failed: ' . $query . PHP_EOL . $this->mysqli->error );  

    // if $bind is not an empty array shift the type element off the beginning and call stmt->bind_param() with variables to bind passed as reference
    if ( $type = array_shift( $bind ) )
        call_user_func_array( 
            array( $stmt, 'bind_param' ), 
            array_merge( array( $type ), array_map( function( &$item )  return $item; , $bind ) ) 
        );

    if ( !$stmt->execute() ) 
        throw new Exception( 'Execute failed: ' . PHP_EOL . $stmt->error );

    // choose what to return here ( 'affected_rows', 'insert_id', 'mysqli_result', 'stmt', 'array' ) 


使用示例:

$db->prepare( "SELECT * FROM user WHERE user_name = ? OR user_email = ?", [ 'ss', $user_name, $user_name ] );

【讨论】:

我喜欢你的想法,让我试试看,直到@你的常识回答我的问题 如果我想选择 * 而不像 select * from members 那样的任何参数,你能做到吗? @SaeedAnsari, $bind 是可选参数,只需使用$db->prepare( "select * from members" ); 谢谢我现在正在使用它:) 当我使用它选择数据时,它工作正常,但是如果我使用此查询插入数据,我会在布尔值上调用成员函数 fetch_assoc() 如果 stmt 成功执行,我将使用这三行代码$result = $stmt->get_result(); return $result->fetch_assoc(); return $result->num_rows;

以上是关于在 $bind_param() 中动态绑定参数; mysqli的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHP 中动态绑定 mysqli bind_param 参数?

mysql绑定参数bind_param原理以及防SQL注入

mysqli_stmt::bind_param() - 为每个参数指定另一个数据类型而不是“s”

将多个参数绑定到mysqli查询中

绑定布尔值的 bind_param 问题

PHP / MySQLi - 数组作为 bind_param