【问题标题】:mysqli queries coming up emptymysqli 查询为空
【发布时间】:2019-01-08 20:23:26
【问题描述】:

我正在制作一个 php 注册脚本,注册工作正常,一切都成功输入数据库,激活电子邮件工作正常,但每当我使用 mysqli 查询来选择或更新信息时,它都不起作用。

例如,当我使用我知道在数据库中的帐户登录时,它告诉我用户名不存在,当单击电子邮件中的激活链接时,查询无法更新数据库方式。

我确信这是我在新手中忽略的一个超级简单的错误,但经过几个小时的查找后我找不到合适的答案。我不确定是什么问题。

激活.php

require "/functions.php";

if (isset($_GET['user'])) {
  $user = $_GET['user'];
}
if (isset($_GET['key']) && (strlen($_GET['key']) == 32)){
  $key = $_GET['key'];
}

if (isset($user) && isset($key)) {
$sql = <<<SQL
  UPDATE users
  SET validation = NULL
  WHERE username='$user'
  AND validation='$key',
  user_group = 'member'
SQL;

$count = $db->affected_rows;

if ($count == 1)
{
    echo '<div>Your account is now active. You may now <a href="login.php">Log in</a></div>';

} else {
 echo '<div>Oops! Your account could not be activated. Please recheck the    link or contact the system administrator.</div>';

}
ob_end_flush();

} else {
  echo '<div>Error Occured .</div>';
}

?>

登录.php

// Globals & error variable
require "/functions.php";

    session_start();
    $error = "";

if (isset( $_POST['Submit'])) {
    if (empty($_POST['username']) || empty($_POST['password'])) {
        $error = "Please fill in all fields!";
}
else {

    $username=$_POST['username']; 
    $password=$_POST['password']; 

    // Injection-protection!
    $username = stripslashes($username);
    $password = stripslashes($password);
    $username = mysqli_real_escape_string($db, $username);
    $password = mysqli_real_escape_string($db, $password);

$sql = <<<SQL
    SELECT *
    FROM `users`
    WHERE `username`='$username'
SQL;

    $result = $db->query($sql);
    $count->num_rows;

    if($count==1){
        while ($row = mysqli_fetch_array($result)) {
            $hash = $row['password'];
            $ug = $row['user_group'];
        }

        salt();

        $options=['salt'=>$bcrypt_salt, 'cost'=>12];
        $password=$argv[1];

        if (crypt($password,$hash) == $hash) {
            $_SESSION['login_user']= $username;
            $_SESSION['user_group']= $ug;
            header("location:index.php");
        }
        else {
            $error = "Username or password is invalid!";
        }
    }
    else {
        $error = "That username doesn't exist!";
    }
    ob_end_flush();
    }
}

functions.php

 // db connect
 $db = new mysqli('HOST', 'USER', 'PASS', 'DB');

if($db->connect_errno > 0){
   die('Unable to connect to database [' . $db->connect_error . ']');
}

在旁注中,请随时提出你们看到的任何明显的不良做法。我是新人,但我不想养成坏习惯!

【问题讨论】:

  • $count-&gt;num_rows; ??试试$count = $result-&gt;num_rows;
  • Activate.php 中创建$sql,但从不执行它,只是在执行$count = $db-&gt;affected_rows;。你需要一个$db-&gt;query($sql);。请注意,在您的 $sql 中,您直接使用 $user$key 而无需先对其进行消毒。不是一个好主意。
  • 在 WHERE 子句中使用可能错误的逗号 , 检查 UPDATE 查询
  • 缺少 AND --- AND validation='$key' AND user_group = 'member' - 检查错误将表明语法错误 php.net/manual/en/mysqli.error.php
  • 有趣,从来不知道。让我想起了树枝

标签: php mysqli


【解决方案1】:

除了在 cmets 中已经说明您没有执行该查询(在通读之前我确实发现了这一点)之外,现在您有了这个代码块,除了您说的 cmets 中多余的逗号已删除:

WHERE username='$user'
AND validation='$key',
user_group = 'member'

它缺少一个 AND --- AND validation='$key' AND user_group = 'member'

检查错误将表明语法错误http://php.net/manual/en/mysqli.error.php

您还应该在标头后添加exit;,否则您的代码可能需要继续执行/运行。

旁注:

  • 请记住 cmets 中已经说明的关于 $count-&gt;num_rows; 的内容,并改用 $count = $result-&gt;num_rows;,而不是对激活文件执行查询 $db-&gt;query($sql);

error reporting 添加到文件顶部,这将有助于查找错误。

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);

// rest of your code

旁注:错误报告应该只在暂存阶段完成,而不是在生产阶段。


脚注:

您当前的激活文件代码对SQL injection 开放。使用prepared statementsPDO with prepared statements它们更安全


编辑:

  • 请仔细阅读以下内容,我的测试代码中包含注释以及注释说明/信息。

使用下面的代码,证明对我来说是成功的。

确保:

  • 验证键的列是 VARCHAR
  • 它的长度是 50,作为测试,但 32 可能不够。
  • 在新测试之前首先更改列的长度,至少使用 40。
  • “验证”列接受 NULL 值。
  • 您选择了正确的数据库和表。
  • 验证键不包含任何尾随空格。

MD5 生成的字符串长度为 32,因此您可能需要为您的列增加它,例如 40 或 50。我的测试使用 50。

您的WHERE 子句将取决于它。

如果通过电子邮件发送的字符串包含空格,请确保没有尾随空格。

  • 使用trim()
  • 确保表格中输入的键最初不包含尾随空格。
  • 您必须重新开始。

即:

$key = $_GET['key'];
$key = trim($key);
  • 如果您的表仍包含“test”和您正在使用的“b5bad6f02c247458e3d888f94b568819”测试密钥,受影响的行将不起作用。
  • 为了让“affected_rows()”真正发挥作用,您需要为“用户”和“密钥”创建一个清晰的表格。
  • 因此,在运行新测试之前清除这些内容。

我还将删除此条件语句 if (isset($user) &amp;&amp; isset($key)) { 及其随附的右大括号 }

  • 它可能弊大于利。

你已经在这个区块中使用了类似的方法:

if (isset($_GET['user'])) {
  $user = $_GET['user'];
}
if (isset($_GET['key']) && (strlen($_GET['key']) == 32)){
  $key = $_GET['key'];
}

但是,我会将其修改为:(并进行测试)

if (isset($_GET['user'])) {
  $user = $_GET['user'];
}
else{ 
   echo "User is not set"; 
exit; // Stop the entire process, it's not set
}

if (isset($_GET['key']) && (strlen($_GET['key']) == 32)){
  $key = $_GET['key'];
}
else{ 
   echo "Key is not set"; 
exit; // Stop the entire process, it's not set
}

旁注:最好不要使用isset(),而是使用!empty()


我的测试代码:

旁注:你说你删除了user_group = 'member',确保这不会改变流程。

<?php 
$DB_HOST = 'xxx'; // Change those
$DB_USER = 'xxx'; // to your
$DB_PASS = 'xxx'; // own
$DB_NAME = 'xxx'; // credentials

$db = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($db->connect_errno > 0) {
  die('Connection failed [' . $db->connect_error . ']');
}

$activation = md5(uniqid(rand(), true));

echo $activation . "<br>";

$user = "test";
$key = "b5bad6f02c247458e3d888f94b568819 "; 
// deliberate space added at the end of the string, remove it from this when testing.

$key = trim($key); // trims off the space at the end of the key string.

echo strlen($key); // yep, gotten 32

$sql = <<<SQL
  UPDATE users
  SET validation = NULL
  WHERE username='$user'
  AND validation='$key'

SQL;

$result = $db->query($sql);

if($result) {
  echo "Success" . "<br>"; 
// This does not always mean it was truly successful. Use affected_rows()
}

else{
  echo "Failed" . mysqli_error($db);
}

$affected = $db->affected_rows;

if($affected){
  echo "Affected yes";
}

else{
  echo "Not affected";
}

如果这对你不起作用,那么我不知道我还能说什么或做什么,这将有助于进一步的帮助;对不起,我试过了。

衷心祝愿您一切顺利,希望此事得到解决。

【讨论】:

  • 好的,让我告诉你我有什么。我继续删除了 user_group 更新。一旦我完成了第一个更新,我就可以单独更新它。最初的想法是将数据库中的验证更改为 NULL 并将 user_group 更改为“成员”(来自验证) $sql = 查询($sql); $count = $result->affected_rows;还是没有骰子。
  • @MirandaRoberts affected_rows() 需要数据库连接。请参阅手册 php.net/manual/en/mysqli.affected-rows.php 即:printf("Affected rows (SELECT): %d\n", $mysqli-&gt;affected_rows);$mysqli 是 DB 连接变量。所以,在你的情况下,那将是printf("Affected rows (UPDATE for example): %d\n", $db-&gt;affected_rows);
  • @MirandaRoberts 所以,不要将$result 用于受影响的行与$result = $db-&gt;query($sql); - 使用printf("Affected rows (UPDATE for example): %d\n", $db-&gt;affected_rows); 并使用php.net/manual/en/mysqli.error.php 检查错误
  • 哦!那讲得通。所以在这种情况下,当使用时,它出现了受影响的行(SELECT):0。密钥和用户与数据库中的内容匹配,所以我仍然不确定这里出了什么问题。
  • 我正在玩的用户只是“测试”,每个密钥都使用以下代码生成:$activation = md5(uniqid(rand(), true));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 2014-02-11
  • 2013-09-14
  • 2023-03-27
相关资源
最近更新 更多