mysqli_stmt :: bind_result():绑定变量数与预准备语句中的字段数不匹配

时间:2013-12-18 09:20:24

标签: php mysql mysqli prepared-statement

我一直在尝试使用预准备语句在PHP中编写登录表单但每次我尝试登录时都会收到以下错误:

  

mysqli_stmt :: bind_result():绑定变量数与预准备语句中的字段数不匹配

这是我的代码:

<?php
session_start();

$mysqli = new mysqli("localhost", "root" , "" , "security");
if(mysqli_connect_errno()){
    echo "Wrong" ;
}
if($stmt = $mysqli->prepare("SELECT username AND password FROM users WHERE username =? AND password =?")){
    $username = $_POST['name'];
    $password = $_POST['password'];
    $stmt->bind_param('ss' ,$username ,$password);
    $stmt->execute();
    $stmt->bind_result($password ,$username);
    if($stmt->fetch() == 'true')
    {
        echo "welcome";
    } else{
        echo "wrong password";
    }
}
?>

有人能告诉我为什么会这样吗?

3 个答案:

答案 0 :(得分:5)

$mysqli->prepare("SELECT username, password FROM users WHERE username = ? AND password = ?");
$username = $_POST['name'];
$password = $_POST['password'];
$stmt->bind_param('ss' ,$username ,$password);
$stmt->execute();
$stmt->bind_result($username ,$password);

您的选择语法错误,正确的语法是 SELECT field1, field2, field3 FROM TABLE WHERE field1 = ? AND field2 = ?

要选择更多字段,只需用逗号分隔,而不是AND

另外,我意识到你是用明文保存你的密码,这是不好的做法,考虑使用像sha1()

这样的众多散列函数来散列它们。

答案 1 :(得分:0)

如果那真的是你的代码,可能是$ _POST [“name”]或$ _POST [“password”]是一个数组,所以bind_param绑定的不只是一个值。

检查:

var_dump($_POST["name"]);
var_dump($_POST["password"]);

答案 2 :(得分:0)

说明

该错误消息明确指出您SELECT 的列数与您提供给 mysqli_stmt::bind_result() 的变量数不匹配。它们需要完全匹配。

例如:

--      ↓ 1   ↓ 2   ↓ 3
SELECT col1, col2, col3 FROM tableA

要获取 3 列,因此您需要提供 3 个变量。

$stmt->bind_result($var1, $var2, $var3);

列数与变量数不匹配的原因可能有很多。

计算你的列和变量

最简单的原因是您在计数中犯了错误。对两者进行复述。也许您更改了 SQL 但忘记调整 bind_result()

选择 *

不建议将 SELECT *bind_result() 一起使用。表中的列数可能会因架构更改或连接而发生变化,并且会破坏您的应用程序。 始终明确列出所有列!

SQL 逻辑问题

问题中的代码包含一个逻辑错误。 SELECT username AND password 在结果中生成一列。 AND 关键字的计算结果为布尔表达式。要选择多个列,您必须使用 ,。也许查询中存在另一个逻辑错误,导致 SQL 生成的列数与您预期的不同?

更新和插入

INSERTUPDATEDELETE 等 DML 语句不会产生结果集。您不能将变量绑定到此类准备好的语句。您需要执行另一个 SELECT 语句来获取数据。

从准备好的语句中获取数组

mysqli_stmt::bind_result() 的返回值不是数组,它只是一个布尔值。如果您希望此函数返回一个数组,那么您可能正在寻找带有 get_result()fetch_all()

要选择数组,您需要先获取 mysqli_result 对象。

$stmt = $mysqli->prepare("SELECT username AND password FROM users WHERE username = ?");
$stmt->bind_param('s', $username);
$stmt->execute();
$mysqli_result = $stmt->get_result();

// The object can then be iterated or used with fetch_* methods
foreach($mysqli_result as $row) {
}
// or
$arrayRow = $mysqli_result->fetch_assoc();

如果您的 PHP 安装中不存在此功能,则表示您没有正确安装 PHP。您需要重新编译它,或者启用 mysqlnd(例如在 cPanel 中)。

如果您只学习 PHP,那么学习 PDO 会容易得多。