4

I'm tweaking a legacy database class written for PHP/5.2 that was designed to connect to MySQL and hide all errors. I've configured the PDO instance to throw exceptions:

 new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION))

Now I need to adjust my code accordingly to handle the case where functions can throw an exception where they wouldn't before so I head to the manual.

In some cases the manual is explicit, e.g. PDO::prepare:

If the database server successfully prepares the statement, PDO::prepare() returns a PDOStatement object. If the database server cannot successfully prepare the statement, PDO::prepare() returns FALSE or emits PDOException (depending on error handling).

In other cases it's kind of vague, e.g. PDO::commit:

Returns TRUE on success or FALSE on failure.
Throws a PDOException if there is no active transaction.

(Can it fail for some other reason and simply return false?)

And there're cases when exceptions are not even mentioned, e.g. PDO::bindValue:

Returns TRUE on success or FALSE on failure.

... even though it's clear to verify that it does throw PDOException on error (at least, on certain errors).

Do I still need to check the return value of methods that return false on error when the manual doesn't say otherwise?

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • @RyanVincent Are you talking about normal error conditions that happen on regular operation (an example would be great) or those subtle bugs that spice PHP development now and then? – Álvaro González May 26 '16 at 14:53
  • You are correct, On normal operations it is very reliable. However, imo, `emulates = false` and wrong parameter hints can confuse PDO. I suggest you try it with 'emulates prepares' set to 'true'. You don't lose anything except a couple of minutes? – Ryan Vincent May 26 '16 at 14:56
  • imo, I suggest that you don't specify parameter types unless `BLOB` types are being used. And only for the 'blob' columns. – Ryan Vincent May 27 '16 at 19:44

3 Answers3

3

No, when you set PDO::ERRMODE_EXCEPTION there will be always exception for any errors

nospor
  • 4,190
  • 1
  • 16
  • 25
  • 1
    I upvoted this since I *think* it's correct. From my experience thus far, I've tried the following: connect to MySQL via PDO in exception mode. Then I forcibly drop the connection on the MySQL side by killing it, then I tried to prepare a statement via PHP - if not in exception mode, it returns false. If in exception mode, it throws an exception (exception was "MySQL server has gone away"). Same happened for `query` method, transactions etc. As I said, this is from experience, but the documentation suggests that this answer is correct. – N.B. May 26 '16 at 11:13
  • may I add that this is true for 'emulates_prepares' when `true` as far as I am aware. It is also true when `emulates` is false and all the binding types are correct or, i suspect, using default binding types. imo, It can get confused if the binding types are incorrect. It may not throw an exception sometimes. ;-/ – Ryan Vincent May 27 '16 at 16:36
0

When you have exceptions enabled and there is an error happening in your code, the code directly stops executing from that function, so it wont return anything.

So to be blund, you don't need to check the return values but if you don't you cannot error anything specific and you would rely fully on PDO to error correctly.

When I created my database system, I take advantage of both if I see an error upcoming, I throw it myself instead. For example $pdo->prepare('') is very much valid but will error upon binding.

Then there are other functions such as fetch that wont error if there are no results in the database, not checking the results from that would be silly.

Now for committing to fail, I believe there is 1 scenario that would cause it to return false without throwing an exception and that is when the connection to the server drops after connecting to the database and before calling PDO::commit, quite good to know if you have a remote database server.

So to answer your question, yes it can fail without throwing an exception, but its timing has to be very specific even more so if you have a local database.

Xorifelse
  • 7,878
  • 1
  • 27
  • 38
  • I'd need to test that but I recall having obtained PDOExceptions in the past with *MySQL server has gone away* as message, though probably in other methods. – Álvaro González May 26 '16 at 12:21
  • @ÁlvaroGonzález did you test it yet? – Xorifelse Jun 06 '16 at 16:09
  • I can confirm that I've been getting entries in my logs with "MySQL server has gone away", "Too Many Connections" and "Lost connection to MySQL server at 'reading initial communication packet', system error: 111" messages that come from `PDOException` (and none from checking return codes). My gut feeling is that it's only a documentation issue but I guess the only way to be 100% sure is to browse the C source code of the PHP version that runs on my server :) – Álvaro González Jun 06 '16 at 16:15
-5

Try this one

 try {
   $db = new PDO("mysql:host=localhost;dbname=dbname", "username", "password");
}catch( PDOException $Exception ) {  $Exception->getMessage( )  ;  }
srinivas
  • 109
  • 12