Почему 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> 

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

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

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

Он не имеет ничего общего с PHP – это просто то, как работает MySQL.

Документация MySQL гласит:

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

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

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

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

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

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

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

Это то, как работает 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 

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