如何使用准备好的语句动态绑定参数? [英] how to dynamically bind parameters using prepared statement?

查看:75
本文介绍了如何使用准备好的语句动态绑定参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写准备好的语句以供用户输入.参数号是可变的,取决于用户输入.我正在尝试此代码

I am trying to write prepared statement for user input. parameter numbers are variable depends on user input. i am trying this code

php代码:

$string          = "my name";
$search_exploded = explode( " ", $string );
$num             = count( $search_exploded );
$cart            = array();
for ( $i = 1; $i <= $num; $i ++ ) {
    $cart[] = 's';
}
$str          = implode( '', $cart );
$inputArray[] = &$str;
$j            = count( $search_exploded );
for ( $i = 0; $i < $j; $i ++ ) {
    $inputArray[] = &$search_exploded[ $i ];
}
print_r( $inputArray );
foreach ( $search_exploded as $search_each ) {
    $x ++;
    if ( $x == 1 ) {
        $construct .= "name LIKE %?%";
    } else {
        $construct .= " or name LIKE %?%";
    }
}
$query = "SELECT * FROM info WHERE $construct";
$stmt  = mysqli_prepare( $conn, $query );
call_user_func_array( array( $stmt, 'bind_param' ), $inputArray );
if ( mysqli_stmt_execute( $stmt ) ) {

    $result = mysqli_stmt_get_result( $stmt );
    if ( mysqli_num_rows( $result ) > 0 ) {
        echo $foundnum = mysqli_num_rows( $result );
        while( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC ) ) {

            echo $id = $row['id'];
            echo $name = $row['name'];
        }
    }
}

当我print_r $ inputArray输出是这样的时候:

when i print_r $inputArray output is this:

   Array ( [0] => ss [1] => my [2] => name ) 

在错误日志中没有错误显示. 我在这里做什么错了,请告诉我.

there is no error showing in error log. what is wrong i am doing here please tell me.

推荐答案

100%经过测试/成功的代码:

%包装包含参数,而不是占位符. (有关其他说明,请参见嵌入式注释)

The % wrapping goes around the parameters, not the placeholders. (see inline comments for additional explanations)

$string = " b c ";

$strings = array_unique(preg_split('~\s+~', $string, -1, PREG_SPLIT_NO_EMPTY));  // isolate and remove duplicates
$where = '';
$types = '';
foreach ($strings as $s) {
    $params[] = "%{$s}%";  // wrap values in percent signs for LIKE
    $where .= (!$where ? " WHERE" : " OR") . " name LIKE ?";  // build clause
    $types .= 's';
}
// echo "<div>{$where}</div>";  // uncomment if you wish to see what is generated

if (!$conn = new mysqli("host", "user", "pass", "db")) {
    echo "Database Connection Error: " , $conn->connect_error;
} else {
    $query = "SELECT id, name FROM info{$where}";
    if(!$stmt = $conn->prepare($query)) {
        echo "Syntax Error @ prepare: " , $conn->error;  // don't show to public
    }else{
        if ($where) {
            array_unshift($params, $types);  // prepend the type values string
            $ref = [];  // add references
            foreach ($params as $i => $v) {
                $ref[$i] = &$params[$i];  // pass by reference as required/advised by the manual
            }
            call_user_func_array([$stmt, 'bind_param'], $ref);
        }    

        if (!$stmt->execute()) {
            echo "Error @ bind_param/execute: " , $stmt->error;  // don't show to public
        } elseif (!$stmt->bind_result($id, $name)) {
            echo "Error @ bind_result: " , $stmt->error;  // don't show to public
        } else {
            while ($stmt->fetch()) {
                echo "<div>$id : $name</div>"; 
            }
            $stmt->close();
        }
    }
}

p.s.如果您使用的是php5.6或更高版本,则可以享受splat/spread运算符(...)提供的更简短的语法.

p.s. If you are using php5.6 or higher, then you can enjoy the more brief syntax afforded by the splat/spread operator (...).

if ($where) {
    if (!$stmt->bind_param($types, ...$params)) {
        echo "MySQL Query Syntax Error: <b>Failed to bind placeholders and data</b>";  // $stmt->error;
    }
} 

这篇关于如何使用准备好的语句动态绑定参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆