5

我一直在修改我的网站,从不受保护的 MySQL 查询到 mysqli 准备好的语句,一切都很顺利,直到我得到这个:没有为准备好的语句中的参数提供数据。

if(empty($err)) {
    $pSETQuery  = NULL;
    if(!empty($_POST['password'])) {
        $pSETQuery .= ", password = ?";
    }
    if($session->isSuperuser()) {
        $pSETQuery .= ", usertype = ?";
    }
    if(!($stmt = $database->prepare("UPDATE user SET username = ?, email = ? $pSETQuery WHERE UserId = ?"))) {
        $err[] = "PREPARE FAILED.";
    }
    $stmt->bind_param("s", $_POST['username']);
    $stmt->bind_param("s", $_POST['email']);
    if(!empty($_POST['password'])) {
        $stmt->bind_param("s", $_POST['password']);
    }
    if($session->isSuperuser()) {
        $stmt->bind_param("s", $_POST['usertype']);
    }
    $stmt->bind_param("i", $_POST['userid']);
    if(!$stmt->execute()){
        $err[] = "Execute failed. ERROR: " . $stmt->error;
    }

}
4

4 回答 4

6

您收到的错误是由于以下几行:

$stmt->bind_param("s", $_POST['username']);
$stmt->bind_param("s", $_POST['email']);

您只能调用bind_param()一次,并且您需要提供确切数量的值,因为您在 SQL 中有占位符。这个功能设计得不好,这也是人们偏爱PDO的主要原因之一。

要解决这个问题,您需要动态准备 3 样东西:占位符、类型和要绑定的变量。以下是动态构建此类查询的方法:

if(empty($err)) {
    $pSETQuery  = '';
    $types = 'sss'; // for the three constant placeholders
    $data = [$_POST['username'], $_POST['email']];
    if(!empty($_POST['password'])) {
        $pSETQuery .= ", password = ?";
        $types .= 's'; //concat one more
        $data[] = $_POST['password'];
    }
    if($session->isSuperuser()) {
        $pSETQuery .= ", usertype = ?";
        $types .= 's'; //concat one more
        $data[] = $_POST['usertype'];
    }
    $data[] = $_POST['userid']; // for UserId
    
    $stmt = $database->prepare("UPDATE user SET username = ?, email = ? $pSETQuery WHERE UserId = ?");
    $stmt->bind_param($types, ...$data);
    $stmt->execute();
}
于 2020-12-09T12:41:17.607 回答
1

你使用 Zend 框架吗?这可能是 PHP 和 Zend 之间的版本问题。我遇到了 PHP 5.3 + 的问题,他在使用 Zend 框架 1.8.3 插入或更新时遇到了同样的错误。

如果是这种情况,解决方案之一是将连接器更改为数据库。试试这个,它对我有用:

$db = new Zend_Db_Adapter_Pdo_Mysql(array(
    'host'     => '127.0.0.1',
    'username' => 'webuser',
    'password' => 'xxxxxxxx',
    'dbname'   => 'test'
));
于 2012-10-01T12:47:37.270 回答
-1

我刚刚找到了解决同样问题的方法。

这是一个传递给 MySQL 的值,即NULL. 而此列不能NULL在表定义中......

于 2013-03-18T17:58:10.990 回答
-1

“未为准备好的语句中的参数提供数据”表示语句正常,但您提供给 bind_param 的至少一个变量未按预期存在!我会打印出 $_POST 并查看发生了什么并最终设置 $pSETQuery = ''; 而不是空!

$_POST['username']
$_POST['email']
$_POST['password']
$_POST['usertype']
$_POST['userid'] // this one is the one I would really watch after, how do you tell the userid if the user is not logged ( i assume that from email, passwrod and might be wrong)
于 2012-09-29T23:07:58.803 回答