WHERE 语句在应该更新数据的 SQL 中不起作用[关闭]
Posted
技术标签:
【中文标题】WHERE 语句在应该更新数据的 SQL 中不起作用[关闭]【英文标题】:WHERE statement not working in SQL that should update data [closed] 【发布时间】:2020-06-15 01:57:05 【问题描述】:这次我试图在用户个人资料上进行最后一次查看。我在我的 phpmyadmin 中添加了一个名为 lastseen 的列,类型为“DATETIME”。当用户注销时,lastseen 应该更新为当前的日期和时间。所以我在我的注销脚本中创建了一个 SQL 来更新这个值。当我测试它时,它并没有像往常一样工作。尝试了很多东西,但没有任何帮助。我发现如果没有我的 WHERE 语句,日期只会按应有的方式更新,但遗憾的是所有用户。所以 SQL 中需要 WHERE 语句。我在没有它的情况下测试后又添加了它,但它不再工作了,这让我确定它与 WHERE 有什么关系,但我真的不明白是什么。
这是我的注销脚本:
<?php
session_start();
session_unset(); // Well.. One of these two will definitely work!
session_destroy();
// Updating
include('C:\xampp2\htdocs\settings\sh_config.php');
include('./static/index/scripts/session_start.php');
$conn = mysqli_connect($database['host'], $database['user'], $database['password'], $database['db'], $database['port']);
$last_timestamp = date("Y-m-d H:i:s");
$last_user = $_SESSION['username'];
$lastseen_query = mysqli_query($conn, "UPDATE users SET lastseen='$last_timestamp' WHERE username = '$last_user'");
header('Location: /');
$conn->close();
?>
"sh_config.php" 的包含是私有的,但我会告诉它在这个脚本中的作用。很简单的答案:我在该文件中配置了数据库连接。所以 $database 的所有内容都在该文件中正确配置。
“session_start.php”的脚本:
<?php
include('C:\xampp2\htdocs\settings\sh_config.php');
session_start();
// Initializing variables
$username = "";
$email = "";
$errors = array();
// Connect to the database
$db = mysqli_connect($database['host'], $database['user'], $database['password'], $database['db'], $database['port']);
// REGISTER USER
if (isset($_POST['reg_user']))
// Receive all input values from the form
$username = mysqli_real_escape_string($db, $_POST['username']);
$email = mysqli_real_escape_string($db, $_POST['email']);
$password_1 = mysqli_real_escape_string($db, $_POST['password_1']);
$password_2 = mysqli_real_escape_string($db, $_POST['password_2']);
$fname = mysqli_real_escape_string($db, $_POST['fname']);
$lname = mysqli_real_escape_string($db, $_POST['lname']);
$sex = mysqli_real_escape_string ($db, $_POST["sex"]);
$bday = mysqli_real_escape_string($db, $_POST['bday']);
// Form validation: ensure that the form is correctly filled ...
// By adding (array_push()) corresponding error unto $errors array
if (empty($username)) array_push($errors, "Username is required");
if (empty($email)) array_push($errors, "Email is required");
if (empty($password_1)) array_push($errors, "Password is required");
if (empty($fname)) array_push($errors, "Firstname is required");
if (empty($lname)) array_push($errors, "Lastname is required");
if (empty($sex)) array_push($errors, "What is your gender?");
if (empty($bday)) array_push($errors, "When is your cakeday?");
if ($password_1 != $password_2)
array_push($errors, "The two passwords do not match");
// First check the database to make sure
// A user does not already exist with the same username and/or email
$user_check_query = "SELECT * FROM users WHERE username='$username' OR email='$email' LIMIT 1";
$result = mysqli_query($db, $user_check_query);
$user = mysqli_fetch_assoc($result);
if ($user) // If user exists
if ($user['username'] === $username)
array_push($errors, "Username already exists");
if ($user['email'] === $email)
array_push($errors, "Email already exists");
// Finally, register user if there are no errors in the form
if (count($errors) == 0)
$password = md5($password_1); // Encrypt the password before saving in the database
$user_ip = $_SERVER['REMOTE_ADDR']; // Getting the IP of the user
$bio = $config['default-bio']; // Setting default biography
$profileimg = $config['default-profileimg']; // Setting default profile image
$timestamp = date('d.m.Y'); // Defining the current date
$query = "INSERT INTO users (username, bio, profileimg, regdate, email, password, firstname, lastname, gender, birthday, ip)
VALUES('$username', '$bio', '$profileimg', '$timestamp', '$email', '$password', '$fname', '$lname', '$sex', '$bday', '$user_ip')";
mysqli_query($db, $query);
session_regenerate_id();
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = TRUE;
$_SESSION['success'] = "You are now logged in";
// Generate user id
$generate_id_query = "SELECT id FROM users WHERE username='$username' ORDER BY id";
$get_id = $db->query($generate_id_query);
$gen_id = $get_id->fetch_assoc();
if ($gen_id['id'] <= 0) // Checking if the user id is a valid id (not below or equal to 0), and if not, displaying a critical error
array_push($errors, "Something went wrong whilst signing up, please refer to the helpcenter. (SE100)");
if ($get_id->num_rows > 0 && $gen_id['id'] > 0) // Redirecting the user to his or her profile if it is a valid id
header('location: /content/users/profile?id=' . $gen_id['id'] . '');
// ...
// LOGIN USER
if (isset($_POST['login_user']))
$username = mysqli_real_escape_string($db, $_POST['username']);
$password = mysqli_real_escape_string($db, $_POST['password']);
if (empty($username))
array_push($errors, "Username or email is required");
if (empty($password))
array_push($errors, "Password is required");
if (count($errors) == 0)
$password = md5($password);
$query = "SELECT * FROM users WHERE ( username='$username' OR email = '$username' ) AND password='$password'";
$results = mysqli_query($db, $query);
if (mysqli_num_rows($results) == 1)
session_regenerate_id();
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = TRUE;
$_SESSION['success'] = "You are now logged in";
// Get user id
$get_id_query = "SELECT id FROM users WHERE username='$username' ORDER BY id";
$get_id = $db->query($get_id_query);
$user_id = $get_id->fetch_assoc();
if ($user_id['id'] <= 0) // Checking if the user id is a valid id (not below or equal to 0), and if not, displaying a critical error
array_push($errors, "Something went wrong whilst logging in, please refer to the helpcenter. (SE100)");
if ($get_id->num_rows > 0 && $user_id['id'] > 0) // Redirecting the user to his or her feed if it is a valid id
header('location: /content/users/profile?id=' . $user_id['id'] . '');
else
array_push($errors, "Your credentials do not match our records");
?>
嗯,如您所见,其中包含很多信息。基本上,这管理着注册和登录以及使用用户 ID 重定向到唯一配置文件的所有内容。我认为这个文件可能会派上用场,因为在这个文件中定义了 id 和用户名。如果您看起来不错,您会看到我将此文件包含在我的注销脚本中,因此定义的单词应该可以正常工作,但它们不能。尝试在没有包含的情况下在文件中重新定义它也不起作用。 哦,顺便说一句, 我使用 MySQLi。
请帮帮我,已经谢谢了。
【问题讨论】:
您可以将 lastseen 设为 DATETIME 并将您的查询更改为UPDATE users SET lastseen=now() WHERE username = '$last_user';
我不明白您的注销脚本背后的逻辑。它是真正的脚本还是只是一个例子?
经过仔细检查,我认为问题在于您正在取消会话设置,然后尝试从中读取。将$last_user = $_SESSION['username'];
移到session_unset();
之前,然后重试。还要看看@vonas 在他的回答中写了什么。另外,请阅读SQL injection 并使用prepared statements。您构建查询的方式是不安全的。
@El_Vanja 这是一个真实有效的注销脚本。
@El_Vanja + 感谢您提供的信息,我一定会学习如何准备好声明,但我认为这并不危险,因为它是一个本地项目,而且永远都是。
【参考方案1】:
您的代码中有一个错误,即当用户使用他们的电子邮件地址登录时,该地址存储在$_SESSION['username']
中。在您的注销脚本中,您假设这实际上是他们的用户名,而实际上可能不是。将您的更新查询更改为这样的内容,您的问题可能会得到解决:
UPDATE users
SET lastseen='$last_timestamp'
WHERE username = '$last_user'
OR email = '$last_user';
虽然这可能有效,但我建议您使用您的宝贵用户id
。不要比较容易出现各种错误(大小写错误的字母、前导/尾随空格、不同编码等)的字符串,而是比较您的 ID。这不仅减少了出错的可能性,而且还减少了您的计算时间,尤其是在数据库查找的上下文中。
$_SESSION['user_id'] = $user_id['id']; // or $gen_id['id'] in the signup code.
$last_user = $_SESSION['user_id'];
$lastseen_query = mysqli_query($conn, "UPDATE users SET lastseen='$last_timestamp' WHERE id = '$last_user'");
将来要自己调试此类问题,您可以使用一种流行的、快速而肮脏的方式来转储变量的内容:在创建用户时打印/回显 $username
和 $email
的值并回显上面脚本中使用的$username
的值,以更新数据库中最后看到的值,如下所示:
$username = mysqli_real_escape_string($db, $_POST['username']);
$email = mysqli_real_escape_string($db, $_POST['email']);
var_dump($username);
var_dump($email);
$last_user = $_SESSION['username'];
var_dump($last_user);
如果$last_user
的转储与$email
匹配,则您知道上述错误适用并且是您的脚本行为不端的原因。您可能还会发现字符串值存在一些问题(可能在某些时候出现意外突变),这会导致 SQL 查询中的比较失败。
【讨论】:
谢谢!做了一些更多的研究,我不是通过用户名而是通过 URL 获得了 ID。我将登录脚本中定义的 id 添加到了注销页面,该 ID 引用了具有唯一 ID 的配置文件。前任。注销?id=1。这样我做了 $_GET['id] 并在 URL 中找到了 id。使用该 ID,我可以成功更新最后一次看到的内容。我什至添加了在线、离线、afk、dnd 和不可见的活动状态:D。注销时,它会更新为离线,登录时它会自动更新为在线。谢谢你让我走上正轨,现在我可以继续我的项目了。以上是关于WHERE 语句在应该更新数据的 SQL 中不起作用[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
SQL语句中模糊查询中不区分大小写怎么写?如:select × from table where number like‘%PK%’