【问题标题】:MySQL update query is executed but no change in data for some rowsMySQL 更新查询已执行,但某些行的数据没有变化
【发布时间】:2022-01-15 01:06:09
【问题描述】:

很遗憾,没有错误消息。这是我的更新查询,它的工作原理是它总是在execute() 之后到达echo 语句。奇怪的是它没有反映 some 行的更新(某些行确实得到了更新),即使在网络有效负载上发送了正确的数据。另一个奇怪的事情是,这完全适用于 localhost,但不适用于实时服务器。

include_once("../connections/db.inc.php");
if(isset($_POST['id'])) {
  try {
    $value = $_POST['value'];
    $column = $_POST['column'];
    $id = $_POST['id'];
    $sql = "UPDATE `users` SET $column = :value WHERE md5(userId) = :id OR userId =:id LIMIT 1";
    $stmt = $db->prepare($sql);
    $stmt->bindParam(":id", $id, PDO::PARAM_INT);
    $stmt->bindParam(":value", $value);
    if (!$stmt->execute()) {
      print_r($stmt->errorInfo());
    }
    echo "y";
  }
  catch (PDOException $e) {
    echo $e->getMessage();
  }
}

目前正在使用简单循环检索id

while ($row = $stmt->fetch()) {
$id = md5($row['userId']);
...

并且这些字段是内联可编辑的

<td>
 <div contenteditable="true" onBlur="updateValue(this, 'userLevel', '<?php echo $id;?>')">
  <?php echo $userLevel; ?>
 </div>
</td>

用jquery ajax将数据发送到上面的php文件中

function archiveRow(id) {
  $.ajax({
    url: 'archiveusers.php',
    type: 'post',
    data: {
      id: id
    },
    success: function(php_result) {
      console.log(php_result);
    }
  });
}

【问题讨论】:

  • 如果这个pdo还是mysqli?
  • 这很容易受到 SQL 注入攻击。您不能参数化列名,但为了减轻这种情况,您绝对 100% 需要将它们列入白名单
  • PDO 不会抛出异常,除非你告诉它...见php.net/manual/en/pdo.error-handling.php
  • 您尝试过什么解决问题的方法? AJAX 请求是否包含预期的数据? PHP 是否正确处理请求?如果只有 一些 更新执行受到影响:是否存在工作/不工作请求的模式?

标签: php jquery mysql


【解决方案1】:

假设你的代码正常工作,你的比较是有缺陷的:

WHERE md5(userId) = :id OR userId = :id

md5函数返回一个字符串,:idPDO::PARAM_INT。在 MySQL 中,字符串与数字的比较保证会产生意想不到的结果:

select '912ec803b2ce49e4a541068d495ab570' = 912 -- 1
select '912ec803b2ce49e4a541068d495ab570' = 913 -- 0

你的php代码应该是这样的:

$sql = "... WHERE md5(userId) = :id_str OR userId = :id_int";

$stmt->bindParam(":id", $id_str, PDO::PARAM_STR);
$stmt->bindParam(":id", $id_int, PDO::PARAM_INT);

不过,这对我来说仍然不正确。解决方案是检查 $_POST['id'] 是否包含 md5 哈希或整数(使用 filter_inputFILTER_VALIDATE_INTFILTER_VALIDATE_REGEXP)然后基于此构建查询 + 参数。

【讨论】:

  • 我为userId 完全删除了md5(),现在可以了。 md5 似乎非常不一致,尽管它在 localhost 中 100% 的时间都有效
  • 它可能 100% 的时间更新了错误的行 :)
猜你喜欢
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 2017-12-28
相关资源
最近更新 更多