19

This code does not throw an error but the query fails, that is, the execute method returns false. How could that be?

require_once("Abstracts/DBManager.php");
require_once("UI/UI.Package.php");
class BlogDBM extends DBManager
{
     private $table = "blog_records";
     function saveRecord($title,$url,$desc,$feedId,$pubDate)
     {
      $PDO = $this->db->connect();
      try
  {

   $query = $PDO->prepare("
    INSERT INTO ".$this->table."
    (title,url,desc,feed_id,pubdate) VALUES
    (:title,:url,:desc,:feed_id,:pubdate)");
   $query->bindParam(":title", $title);
   $query->bindParam(":url", $url);
   $query->bindParam(":desc", $desc);
   $query->bindParam(":feed_id", $feedId, PDO::PARAM_INT);
   $query->bindParam(":pubdate", $pubDate, PDO::PARAM_INT);
   $query->execute();
   //return $PDO->lastInsertId();


  } catch(PDOException $e)
  {
   echo "Error " . $e->getMessage();

  }
  $PDO = NULL;
     }
}
Simsevu
  • 210
  • 1
  • 2
  • 6
  • @Felix, it's a pity you decided to reopen this question. There are canonical answers for both the title and the particular issue (that isn't of much help for visitors from Google). Why do you all want to make Stack Overflow a collection of sketchy and outdated answers, is amystery to me. – Your Common Sense Jun 23 '19 at 05:11
  • @YourCommonSense As you may or may not be aware, there is currently a [bug](https://bugs.php.net/bug.php?id=77490) in php-src where no exception will be thrown even with error mode set to exception. In that case, using error info is what needs to be done. Do you have a canonical with that in mind? If there is a question with the false not throwing error and a correct answer, I'd be glad to vote as duplicate. I somewhat agree that this question is possibly not the ideal one for that, we could also write an actual canonical. – Félix Adriyel Gagnon-Grenier Jun 23 '19 at 14:59
  • The bug also happens when passing an 1-indexed array of values (instead of 0) or not putting colons in the parameter names of the query. – Félix Adriyel Gagnon-Grenier Jun 23 '19 at 15:04

6 Answers6

40

Just wanted to add to this, had similar frustrations from the lack of an error message.

To stop PDO from silently failing, you can set the error mode on the PDO connection.

$dbh = new PDO();
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

There is also PDO::ERRMODE_WARNING if you want errors but still continue.

WhoIsRich
  • 4,053
  • 1
  • 33
  • 19
  • 3
    Found this on google while searching for a similar (but unrelated problem) and you saved my day. – Chris Sobolewski Sep 16 '10 at 02:55
  • 1
    You, sir, are a hero. (I knew that you could do that but I just didn't think of it!) – Jimbali Feb 27 '14 at 19:46
  • 1
    This is really a good hint. Finally I have set the error mode on the PDO connection and this allowed me to see I forgot to set the value in a foreign key ID. Error "integrity constraint violation: 1452 cannot add or update a child row: a foreign key constraint fails". I was back on this code after a while and I had totally forgot about the foreign key. – Robert Aug 06 '17 at 08:56
19

I'm pretty sure that MySQL chokes on the desc field name - it is a reserved word. You'd have to put it into "`" quotes or, better, change the field name.

As for error reporting, use the errorInfo method. You can make PDO actually output the result of a failed query in the exception, but the default behaviour - I think - is to throw an exception only if the query can't be made at all, but it doesn't fail if the query is faulty.

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • 2
    Ah, good catch. I was focused on the objects. I assume phpMyAdmin strikes again (magically escaping reserved words without your knowledge)! – bdl Mar 25 '10 at 18:59
4

I was also facing that error.

I used print_r($con->errorInfo()); it gives me 0000 in 0th key of array.

Then I matched all column names and figured out that I am using wrong field name.

This saves my day.

عثمان غني
  • 2,786
  • 4
  • 52
  • 79
3

It also happens when you use PDOStatement::bindValue() with PDO::PARAM_BOOL. Solution: just switch to PDO::PARAM_INT.

Jakub Wojnowski
  • 139
  • 2
  • 8
  • Two years on, you just solved me a problem I've been debugging with no `errorInfo(...)`, no exception and no indication whatsoever of what's going wrong! Turns out this is a known bug in PDO... reported in 2006 and still not fixed. https://bugs.php.net/bug.php?id=38546 – Ilmiont Jun 13 '18 at 14:13
0

Similar problems can occur when someone turns/leaves off the DB autoincrement on the main id field.

DragonLord
  • 6,395
  • 4
  • 36
  • 38
0

i struggled with this silent insert fail this week. and here's the solution that worked for me. i was not calling commit on the transaction, so the insert was put into the pending state but was never completed on the database - hence no error. this was trickier because the PDR db wrapper in this project is a static class so it doesn't automatically close

solution: make sure to call commit on the PDO handle after the insert / update / delete actions - or on page close.

$PDO->exec("COMMIT;");

xeo
  • 807
  • 2
  • 7
  • 25
  • Ahaha thank you ... came here going WTF is wrong with my code? only to realise that I had a die/dump inside my transaction so it was all being rolled back :) – GuruBob Jul 15 '19 at 21:18