Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是什么导致将PHP插入MYSQL数据库错误地将来自其他用户的数据插入到行中?_Php_Mysql_Pdo - Fatal编程技术网

是什么导致将PHP插入MYSQL数据库错误地将来自其他用户的数据插入到行中?

是什么导致将PHP插入MYSQL数据库错误地将来自其他用户的数据插入到行中?,php,mysql,pdo,Php,Mysql,Pdo,我的一个学生正在将她的学习游戏分数保存到MySQL数据库中,但不知何故,另一个人的名字最终被存储在她的数据库行中。这怎么可能?下面是用于插入的PHP // Get Configuration file require "configenzymatic.php"; // Connect to your server $dbh = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass, array(PDO::MY

我的一个学生正在将她的学习游戏分数保存到MySQL数据库中,但不知何故,另一个人的名字最终被存储在她的数据库行中。这怎么可能?下面是用于插入的PHP

// Get Configuration file
require "configenzymatic.php";

// Connect to your server

$dbh = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass, array(PDO::MYSQL_ATTR_FOUND_ROWS => true));

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

///////////////////////////////////////////////////////
// Status Checker
///////////////////////////////////////////////////////
if ($_GET["status"]) {
    echo "online";
    exit;
}

///////////////////////////////////////////////////////
// Upload new score
///////////////////////////////////////////////////////

//set POST data as data to be checked and updated
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$password = $_POST['password'];
$level1right = $_POST['level1right'];
$level1wrong = $_POST['level1wrong'];
$level2right = $_POST['level2right'];
$level2wrong = $_POST['level2wrong'];
$level3right = $_POST['level3right'];
$level3wrong = $_POST['level3wrong'];
$level4right = $_POST['level4right'];
$level4wrong = $_POST['level4wrong'];

// check for email and set hash variable
$stm = $dbh->prepare("SELECT * FROM $tname WHERE email=?");
$stm->bindValue(1, $email, PDO::PARAM_STR);
$stm->execute();

while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
    $hashes = array($row['hash']);
    $hash = $row['hash'];
    $id = $row['id'];
    foreach ($hashes as $hash) {
        // If hash matches password, then...

        if (password_verify($password, $hash)) {
            // Everything is cool -- Insert the data into the database (update)

            $stmt = $dbh->prepare("
UPDATE $tname 
   SET firstname = :firstname
     , lastname = :lastname
     ,  hash = :hash
     , level1right = :level1right
     , level1wrong = :level1wrong
     , level2right = :level2right
     , level2wrong = :level2wrong
     , level3right = :level3right
     , level3wrong = :level3wrong
     , level4right = :level4right
     , level4wrong = :level4wrong 
 WHERE email = :email 
   AND id = :id");
            $stmt->execute(array($firstname, $lastname, $hash, $level1right, $level1wrong, $level2right, $level2wrong, $level3right, $level3wrong, $level4right, $level4wrong, $email, $id));
            $affected_rows = $stmt->rowCount();

            // check if row inserted

            /* Return number of rows that were updated */
            $count = $stmt->rowCount();
            echo "$count";
        }
    }
}

学生输入了她的名字,但插入了其他人的名字。我对此完全感到困惑。有人知道这是怎么发生的吗?今天12:30:44插入姓名代替我的学生添加数据的人,我的学生在13:44:15添加数据。这些数据是如何混合的

我不确定为什么要将更新包装在多个循环中,但完全可能存在具有相同密码哈希的用户,并且(我认为)会解释您看到的行为

您可能希望使用表单中提交的电子邮件和密码更新单个用户?我假设您的表上也有一些限制,以确保电子邮件地址是唯一的。因此,您正在抓取与该电子邮件匹配的单个用户,并检查其密码。如果匹配,则使用相同的数据库ID更新单个记录。无循环

// get password hash
$stm = $dbh->prepare("SELECT id, hash FROM $tname WHERE email=?");
$stm->execute([$_POST["email"]]);

$row  = $stm->fetch(PDO::FETCH_ASSOC);
$hash = $row['hash'];
$id   = $row['id'];
if (!password_verify($_POST["password"], $hash)) {
    // verification failed, do something to present an error to the user
    die();
}
$stmt = $dbh->prepare(
    "UPDATE $tname
        SET firstname=:firstname, lastname=:lastname,
            level1right=:level1right, level1wrong=:level1wrong,
            level2right=:level2right, level2wrong=:level2wrong,
            level3right=:level3right, level3wrong=:level3wrong,
            level4right=:level4right, level4wrong=:level4wrong
        WHERE id=:id"
);
$stmt->execute([
    ":firstname"   => $_POST["firstname"],
    ":lastname"    => $_POST["lastname"],
    ":level1right" => $_POST["level1right"],
    ":level1wrong" => $_POST["level1wrong"],
    ":level2right" => $_POST["level2right"],
    ":level2wrong" => $_POST["level2wrong"],
    ":level3right" => $_POST["level3right"],
    ":level3wrong" => $_POST["level3wrong"],
    ":level4right" => $_POST["level4right"],
    ":level4wrong" => $_POST["level4wrong"],
    ":id"          => $id
]);
$count = $stmt->rowCount();
echo "$count";

还要注意,在PDO中使用命名参数需要使用关联数组。我不知道如果没有它,您的原始代码将如何更新任何内容。

我不知道您的意思,但是
$tname
看起来非常可疑。背后是什么?我希望它不是每个用户的单独表。为什么您的更新在两个循环中?
foreach($hashes as$hash)
?为什么?您只有一个散列。一致使用空格和缩进将使代码更易于阅读;为自己和他人。不相关的注意:您确实希望在MySQL中使用
utf8mb4
而不是
utf8
字符集。感谢您的帮助。我认为我使用循环的原因是因为我没有限制电子邮件是唯一的,所以代码循环遍历所有哈希,并为输入的电子邮件选择与密码匹配的哈希。因此,学生们似乎需要输入相同的电子邮件和密码才能混淆。但是,被搞混的学生有完全不同的电子邮件。脚本没有检查以确保电子邮件和哈希匹配吗?我仍然不确定它怎么会像那样混在一起。当我有更多信息时,我会更新。我也投票给你。谢谢