Запрос на обновление MySQL выполняется, но данные для некоторых строк не изменяются

#php #jquery #mysql

#php #jquery #mysql

Вопрос:

К сожалению, сообщения об ошибке нет. Это мой запрос на обновление, и он работает при условии, что он всегда достигает echo оператора после execute() . Странно то, что он не отражает обновление некоторых строк (некоторые строки обновляются), даже если в сетевой полезной нагрузке отправляются правильные данные. Еще одна странность заключается в том, что это полностью работает на 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);
    }
  });
}
 

Комментарии:

1. Если это pdo или mysqli?

2. Это уязвимо для атак с использованием SQL-инъекций. Вы не можете параметризовать имена столбцов, но чтобы смягчить это, вам абсолютно на 100% необходимо внести их в белый список

3. PDO не будет генерировать исключения, если вы не укажете ему … см php.net/manual/en/pdo.error-handling.php

4. Что вы пытались решить проблему? Содержит ли запрос AJAX ожидаемые данные? Правильно ли PHP обрабатывает запрос? Если затрагиваются только некоторые выполнения обновлений: существует ли шаблон для рабочих / нерабочих запросов?

Ответ №1:

Предполагая, что ваш код работает, ваше сравнение ошибочно:

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

md5 Функция возвращает строку и :id является PDO::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);
 

Однако это по-прежнему кажется мне неправильным. Решение roper состоит в том, чтобы проверить, $_POST['id'] содержит ли он хэш md5 или целое число (используя filter_input с FILTER_VALIDATE_INT и FILTER_VALIDATE_REGEXP ), а затем построить запрос параметры на основе этого.

Комментарии:

1. Я md5() полностью удалил для userId и теперь все в порядке. md5 кажется очень непоследовательным, хотя он работает 100% времени в localhost

2. Возможно, в 100% случаев были обновлены неправильные строки 🙂