我整天都呆在这里,在搜索了许多网站(包括该网站)后,我得出的结论是,由于我的能力不足,我之前没有被问过这个问题。
我在这里有一条准备好的声明,我想根据用户名和电子邮件更新数据库中的密码字段,其更新而不是插入的原因是因为这是我的安全保护,因为它不批准网站摄影师,除非他们已发送链接
<?php
if (isset($_POST['approved-photographer'])) {
require 'dbh.php';
$username = $_POST['username'];
$email = $_POST['mail'];
$password = $_POST['password'];
$password2 = $_POST['password-repeat'];
if (empty($username) || empty($email) || empty($password) ||
empty($password2))
{
header("location:signup.php?error=emptyfields&username=" . $username
. "&mail=.$email");
exit();
} elseif ($password !== $password2) {
header("location:approvedphoto.php?error=passwordcheck&username=" .
$username . "&mail=" . $email);
exit();
} else {
$sql = "SELECT Password
FROM photographers
WHERE Username= '$username'
AND Email= '$email'";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("location:approvedphoto.php?error=sqlerror");
exit();
} else {
$sql = "INSERT INTO photographers (Password) VALUES (?)";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("location:approvedphoto.php?error=sqlerror2");
exit();
} else {
$hashedpwd = password_hash($password, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, "s", $hashedpwd);
mysqli_stmt_execute($stmt);
header("location:signin.php?signup=success");
exit();
}
}
}
}
任何帮助将不胜感激。感谢您阅读
答案 0 :(得分:1)
使用MySQLi的简短答案是您没有绑定参数,可以使用mysqli_stmt_bind_param
来完成(未来的读者,由于编辑,最后一条语句现在不相关了)。总体而言,您的sql语句编辑后似乎还不清楚,您通常是在更新密码(在这种情况下,您需要一个WHERE
子句,这样就不必更新每个人的密码),或者应该使用密码插入新用户。
这是一个或多或少的切线答案,但是我想为使用PDO
(而不是mysqli)而戴上帽子。 MySQLi仅使用一种数据库形式MySQL。另外,它允许对数据库交互的面向对象的解决方案要少得多。这是如何通过PDO完成此操作的示例:
//specifies the driver, ip/database etc. Swap out for your ip and database used
$driverStr = 'mysql:host=<ip>;dbname=<database>;charset=utf8';
//you can set some default behaviors here for your use, I put some examples
//I left a link below so you can see the different options
$options = [
//spew exceptions on errors, helpful to you if you have php errors enabled
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
//substite what you need for username/password here as well, $options can be omitted
$conn = new PDO($driverStr, '<username>', '<password>', $options);
Link to the aforementioned attributes
现在我们已经建立了联系:
//I used a "named parameter", e.g. :password, instead of an anonymous parameter
$stmt = $conn->prepare("UPDATE Photographers SET password = :password WHERE Username = :username");
//with our prepared statement, there's a few ways of executing it
//1) Using #bind*
//there's also #bindValue for not binding a variable reference
//for params, PARAM_STR is default and can be safely omitted
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->bindParam(':username', $username);
$stmt->execute();
//2) Using execute directly
$stmt->execute(['password' => $password, 'username' => $username]);
然后,该语句是查询,而不仅仅是数据库更新/插入,我们可以简单地检索该语句的结果。通过使用#bindParam,您还可以只更新变量的值并根据需要重新执行该语句,这可能对其他一些语句很有用。
//see #fetch and #fetchAll's documentation for the returned data formatting
$results = $stmt->fetchAll(PDO::FETCH_OBJ); //return it as a php object
$results = $stmt->fetch(PDO::FETCH_NUM)[0]; //unsafely retrieve the first value as a number
多年来,我发现此方法比mysqli_*
甚至不推荐使用的mysql_*
方法中的任何一种都更加清洁和可管理。