我正在对登录系统进行编程,但是遇到了无法修复的错误:
警告:mysqli_stmt_close():C:\ Users \ Acer \ Desktop \ xampp \ htdocs \ Login System \ includes \ signup.inc.php中无效的对象或资源mysqli_stmt。
当我保存并打开文件时,一切正常,直到必须将数据发送到数据库为止。在那一刻,我收到该错误,并且数据库为空。
这是代码
<?php
if (isset($_POST['signup-submit'])) {
require 'dbh.inc.php';
$username = $_POST['uid'];
$email = $_POST['mail'];
$password = $_POST['pwd'];
$passwordrepeat = $_POST['pwd-repeat'];
if (empty($username) || empty($email) || empty($password) || empty($passwordrepeat)) {
header("Location: ../signup.php?error=emptyfields&uid=".$username."&mail=".$email);
exit();
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) && !preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../signup.php?error=invalidmailuid");
exit();
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
header("Location: ../signup.php?error=invalidmail&uid=".$username);
exit();
} elseif (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../signup.php?error=invaliduid&mail=".$email);
exit();
} elseif ($password !== $passwordrepeat) {
header("Location: ../signup.php?error=passcheck&uid=".$username."&mail=".$email);
exit();
} else {
$sql = "SELECT uidUsers FROM users WHERE uidUsers=?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../signup.php?error=sqlerror");
exit();
}
else {
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0){
header("Location: ../signup.php?error=usertaken&mail=".$email);
exit();
}
else {
$sql = "INSERT INTO users (uidUsers, mailUsers, pwdUsers) VALUES (?, ?, ?)";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
}
else {
$hashedPwd = password_hash($password, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, "sss", $username, $email, $hashedPwd);
mysqli_stmt_execute($stmt);
header("Location: ../signup.php?signup=success");
exit();
}
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
else {
header("Location: ../signup.php");
exit();
}
答案 0 :(得分:1)
TL; DR 您在可能未设置mysqli_stmt_close($stmt);
的代码段中调用$stmt
。
您的主要问题是,在进入mysqli_stmt_close()
之前,您无法知道正在运行什么代码。造成这种情况的原因有两个:(1)代码过于复杂和(2)格式错误(没有)。
您的帖子的早期版本中的代码根本没有格式化(看起来您已经对其进行了编辑以使其更好,但仍然存在一些问题)。格式正确,您的代码如下所示:
<?php
if (isset($_POST['signup-submit'])) {
require 'dbh.inc.php';
$username = $_POST['uid'];
$email = $_POST['mail'];
$password = $_POST['pwd'];
$passwordrepeat = $_POST['pwd-repeat'];
if (empty($username) || empty($email) || empty($password) || empty($passwordrepeat)) {
header("Location: ../signup.php?error=emptyfields&uid=" . $username . "&mail=" . $email);
exit();
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) && !preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../signup.php?error=invalidmailuid");
exit();
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
header("Location: ../signup.php?error=invalidmail&uid=" . $username);
exit();
} elseif (!preg_match("/^[a-zA-Z0-9]*$/", $username)) {
header("Location: ../signup.php?error=invaliduid&mail=" . $email);
exit();
} elseif ($password !== $passwordrepeat) {
header("Location: ../signup.php?error=passcheck&uid=" . $username . "&mail=" . $email);
exit();
} else {
$sql = "SELECT uidUsers FROM users WHERE uidUsers=?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
header("Location: ../signup.php?error=sqlerror");
exit();
} else {
mysqli_stmt_bind_param($stmt, "s", $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if ($resultCheck > 0) {
header("Location: ../signup.php?error=usertaken&mail=" . $email);
exit();
} else {
$sql = "INSERT INTO users (uidUsers, mailUsers, pwdUsers) VALUES (?, ?, ?)";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
} else {
$hashedPwd = password_hash($password, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt, "sss", $username, $email, $hashedPwd);
mysqli_stmt_execute($stmt);
header("Location: ../signup.php?signup=success");
exit();
}
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
} else {
header("Location: ../signup.php");
exit();
}
将来,您应该使用像PHPStorm这样的IDE,它将极大地帮助您格式化代码并捕获诸如此类的明显错误。
为简单起见,我们只看一下代码的结构(...
表示我在这里省略的代码):
<?php
if (isset($_POST['signup-submit'])) {
require 'dbh.inc.php';
$username = $_POST['uid'];
$email = $_POST['mail'];
$password = $_POST['pwd'];
$passwordrepeat = $_POST['pwd-repeat'];
if (empty($username) || empty($email) || empty($password) || empty($passwordrepeat)) {
// ...
}
// ... long series of elseif statements here...
else {
$sql = "SELECT uidUsers FROM users WHERE uidUsers=?";
$stmt = mysqli_stmt_init($conn);
// ...
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
} else {
// ...
}
如您所见,$stmt
仅设置在else
块内的一个位置。但是,您尝试在else
块的 outside 外部关闭它,这意味着$stmt
可能永远不会在尝试关闭它之前设置。
将mysqli_stmt_close($stmt);
移至设置和使用else
的{{1}}语句中。
此代码就是我们所说的“意大利面条代码”。我并不是说这很无礼。这只是您在这里拥有的现实。为避免将来出现此类问题:
$stmt
结构。当您有if... elseif... else
个字元时,就出问题了。在编写更多代码之前,您确实应该通读PHP: The Right Way。它将为您节省很多胃灼热的感觉。
请注意,您在此代码中还有其他一些我没有解决的问题,例如将用户输入直接插入elseif
中的URL中,而没有进行任何编码或过滤。例如,这可用于恶意重定向或其他恶意活动。 (您网站上其他页面上也可能遇到XSS问题。)