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%’

在SQL中的WHERE和HAVING语句中使用别名?

访问更新语句在 C# 中不起作用

SQL语句中where条件的写法

日期计算在 Oracle SQL 案例语句中不起作用?

SQL语句如何查询ACCESS数据库中某一字符串字段长度等于某个值的所有记录?