我正在尝试执行参数化查询以更新数据库中的某些内容。
问题是mysqli_stmt_prepare失败。 require用于连接数据库。
require 'includes/dbInclude.php';
if ($codeQuery > 0){
$confirmationUsername = $_GET['confirmationUsername'];
$active = "active";
$noCode = "";
$insertSql = "UPDATE users SET accountStatus = ? WHERE username = $confirmationUsername";
$insertSql2 = "UPDATE users SET confirmationCode = ? WHERE username = $confirmationUsername";
$statement = mysqli_stmt_init($connection);
$statement2 = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($statement, $insertSql)){
header("Location: registerComplete.php?error=sqlError1");
exit();
}
elseif (!mysqli_stmt_prepare($statement2, $insertSql2)){
header("Location: registerComplete.php?error=sqlError2");
exit();
}
else{
mysqli_stmt_bind_param($statement, "s", $active);
mysqli_stmt_execute($statement);
mysqli_stmt_bind_param($statement2, "s", $noCode);
mysqli_stmt_execute($statement2);
}
}
dbInclude.php包含:
<?php
//connection variables
$serverName = "localhost";
$dbUsername = "root";
$dbPassword = "";
$dbName = "ecglive";
//connection
$connection = mysqli_connect($serverName, $dbUsername, $dbPassword, $dbName);
//connection error
if(!$connection){
die("There was an error connceting to the database: " . mysqli_connect_error());
}
在我使用它的地方工作。我也尝试将代码复制到此代码中,以查看连接数据库是否存在任何问题。不是。
如果它在第一个错误处显示sqlError1,并且如果我将其删除,则总是在第一个错误处发生。
我做错了吗?
答案 0 :(得分:2)
除了username
之外,还需要绑定accountstatus
,以帮助减轻SQL注入。
require 'includes/dbInclude.php';
if ($codeQuery > 0){
$confirmationUsername = $_GET['confirmationUsername'];
$active = "active";
$noCode = "";
$insertSql = "UPDATE users SET accountStatus = ? WHERE username = ?";
$insertSql2 = "UPDATE users SET confirmationCode = ? WHERE username = ?";
$statement = mysqli_stmt_init($connection);
$statement2 = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($statement, $insertSql)){
exit(header("Location: registerComplete.php?error=sqlError1") );
} elseif (!mysqli_stmt_prepare($statement2, $insertSql2)){
exit(header("Location: registerComplete.php?error=sqlError2") );
} else{
mysqli_stmt_bind_param($statement, "ss", $active,$confirmationUsername);
mysqli_stmt_execute($statement);
mysqli_stmt_bind_param($statement2, "ss", $noCode,$confirmationUsername);
mysqli_stmt_execute($statement2);
}
}
答案 1 :(得分:1)
此代码使用一种非常奇怪的样式,它的冗长程度远远超出了必要。这是更简单的形式:
require 'includes/dbInclude.php';
// Enable exception reporting
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
if ($codeQuery > 0) {
try {
// Prepare one query that sets both properties.
$stmt = $connection->prepare('UPDATE users SET accountStatus=?,confirmationCode=? WHERE username=?');
// Bind parameters directly form the source, no variables needed.
$stmt->bind_param('ss', 'active', '', $_GET['confirmationUsername']);
// Attempt to execute
$stmt->execute();
}
catch (Exception $e) {
// Error handling here...
header("Location: registerComplete.php?error=sqlError2");
exit();
}
}
您在这里实际上并没有做很多事情,因此没有理由使代码如此冗长。
也就是说,如果这是用于某种用户访问控制层的注册系统,而这不是一个学术项目,则应在创建巨大混乱之前停止使用此代码。编写自己的访问控制层并不容易,而且有很多机会把它严重地弄错。
像development framework这样的现代Laravel都内置了强大的authentication system。这是一个已解决的问题,您无需在这里尝试重新发明轮子。
至少要遵循recommended security best practices,并且永远不要将密码存储为纯文本或诸如 SHA1或MD5 之类的弱哈希。