Почему PDO rowCount() возвращает 0 после UPDATE таблицы без изменения существующих данных?

Я читаю учебник о том, как вставлять и обновлять данные в таблицу MySQL с помощью PHP, код приведен ниже. Моя проблема в том, что когда я нажимаю обновление, но я не изменял никаких данных, rowCount() возвращает 0 и разбивает код.

Мой вопрос: если я просто обновляю базу данных теми же значениями, которые находятся в базе данных, почему rowCount() возвращает ноль? Мои мысли состояли в том, что, хотя это были те же самые данные, они были бы вставлены в любом случае и возвращены счет обновленных строк? Я предполагаю, что он проверяет данные перед тем, как попробовать обновление? Может ли кто-нибудь пролить свет на это для меня и предложить обходной путь? Я часами рассказывал о коде и не мог ничего придумать, спасибо.

<?php
require_once('../includes/connection.inc.php');
// initialize flags
$OK = false;
$done = false;
// create database connection
$conn = dbConnect('write', 'pdo');
if (isset($_GET['article_id']) && !$_POST) {
    // prepare sql query
    $sql = 'SELECT article_id, title, article FROM blog WHERE article_id = ?';
    $stmt = $conn->prepare($sql);
    // bind the results
    $stmt->bindColumn(1, $article_id);
    $stmt->bindColumn(2, $title);
    $stmt->bindColumn(3, $article);
    // execute query by passing array of variables
    $OK = $stmt->execute(array($_GET['article_id']));
    $stmt->fetch();
}
// if form has been submitted, update record
if (isset($_POST['update'])) {
    //prepare update query
    $sql = 'UPDATE blog SET title = ?, article = ? WHERE article_id = ?';
    $stmt = $conn->prepare($sql);
    // execute query by passing array of variables
    $stmt->execute(array($_POST['title'], $_POST['article'], $_POST['article_id']));
    $done = $stmt->rowCount();
}
// redirect page on sucess or if $_GET['article_id'] not defined
if ($done || !isset($_GET['article_id'])) {
    header('Location: http://localhost/PHP_Solutions/admin/blog_list_pdo.php');
    exit();
}
// store error message if query fails
if (isset($stmt) && !$OK && !$done) {
    $error = $stmt->errorInfo();
    if (isset($error[2])) {
        $error = $error[2];
    }
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Update Blog Entry</title>
<link href="../styles/admin.css" rel="stylesheet" type="text/css">
</head>

<body>
<h1>Update Blog Entry</h1>
<p><a href="blog_list_pdo.php">List all entries </a></p>
<?php if (isset($error[2])) {
    echo "<p class='warning'>Error: $error[2]</p>";
    echo '<pre>';
    print_r($_POST);
    print_r($error);
    echo '</pre>';
}
if ($article_id == 0) { ?>
    <p class="warning">Invalid request: record does not exist.</p>
<?php } else { ?>
<form id="form1" method="post" action="">
    <input name="article_id" type="hidden" value="<?php echo $article_id; ?>">
  <p>
    <label for="title">Title:</label>
    <input name="title" type="text" class="widebox" id="title" value="<?php echo htmlentities($title, ENT_COMPAT, 'utf-8'); ?>">
  </p>
  <p>
    <label for="article">Article:</label>
    <textarea name="article" cols="60" rows="8" class="widebox" id="article"><?php echo htmlentities($article, ENT_COMPAT, 'utf-8'); ?></textarea>
  </p>
  <p>
    <input type="submit" name="update" value="Update Entry" id="update">
  </p>
</form>
<?php } ?>
</body>
</html>

Ответы

Ответ 1

Мой вопрос: если я просто обновляю базу данных теми же значениями, которые находятся в базе данных, почему rowCount() возвращает ноль?

rowCount подсчитывает затронутые строки по запросу. Поскольку вы ничего не изменили, есть нулевые затронутые строки.

PDOStatement- > rowCount - возвращает количество строк, затронутых последним оператором SQL

Ответ 2

Это не имеет ничего общего с PHP - это то, как работает MySQL.

Документация MySQL говорит:

Для операторов UPDATE значение по умолчанию - это количество строк, которые были изменены. Если вы указываете флаг CLIENT_FOUND_ROWS на mysql_real_connect() при подключении к mysqld, значение затронутых строк - это количество строк "найдено"; т.е. соответствует условию WHERE.

Ответ 3

Когда вы используете инструкцию UPDATE и отправляете те же значения, что и в базе данных, она всегда возвращает ноль, потому что она не влияет на какую-либо строку.

Способ решения этой проблемы:

$done = $stmt !== false ? true : false;

Что я сделал? Я сделал это:

if($stmt !== false){
    $done = true;
} else{
    $done = false;
}

Потому что если rowCount() равно нулю, но $stmt выполнил без ошибок, $stmt выполненный, но ничего не изменил.

Ответ 4

Как работает MySQL и не имеет ничего общего с расширением PDO; выполнение обычного запроса mysql даст одинаковые результаты. Обходной путь, который я нашел, используя функции mysql, хотя я не уверен, что вы можете сделать что-либо подобное с объектом PDO.

$q = 'UPDATE etc...';
$r = mysql_query($q, $con);
$info = mysql_info(); // Returns info about last query.

list($matches, $changed, $warnings) = sscanf($matched, "Rows matched: %d Changed: %d Warnings: %d");

if ($matches > 0) {} // etc

Надеюсь, это поможет немного.