mysqli查询空洞

时间:2015-06-28 02:20:20

标签: php mysqli

我正在制作一个php注册脚本并且注册工作正常,所有内容都成功地插入到数据库中,并且激活电子邮件工作正常,但每当我使用mysqli查询来选择或更新信息时,它都不起作用。< / p>

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

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

Activate.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>';
}

?>

的login.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 . ']');
}

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

1 个答案:

答案 0 :(得分:1)

除了评论中已经说明你没有执行该查询(我确实发现的事情,在阅读之前),现在你是,那里&# 39;这个代码块,除了你说删除的评论中的额外逗号:

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;,否则您的代码可能希望继续执行/运行。

旁注:

  • 请记住有关$count->num_rows;的评论中已经说明的内容,而是使用$count = $result->num_rows;而不是为激活文件执行查询$db->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个。
  • &#34;验证&#34; column接受NULL值。
  • 您选择了正确的数据库和表格。
  • 验证密钥不包含任何尾随空格。

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

您的WHERE条款取决于它。

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

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

I.e。:

$key = $_GET['key'];
$key = trim($key);
  • 如果您的表格仍包含&#34; test&#34; &#34; b5bad6f02c247458e3d888f94b568819&#34;您正在使用的测试密钥。
  • 为了#34; affected_rows()&#34;要真正工作,你需要重新开始为用户提供一个清晰的表格。和&#34;关键&#34;。
  • 所以,在运行新测试之前清除它们。

我也会摆脱这个条件语句if (isset($user) && 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";
}

如果这不适合你,那么我不知道我能说什么或做什么,这将是任何进一步的帮助;对不起,我试过了。

我衷心祝福你,我希望这件事得到解决。