2

Here is my code:

<?php

try{
    // connect to database and select database
    $servername = "localhost";
    $username = "root";
    $password = "";
    $dbname = "spy";
    $dbh_conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $dbh_conn->exec("set names utf8");
    $dbh_conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $dbh_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}
?>

My code works as well. But I seen a similar code which checks the connection like this:

if ( !$dbh_conn ){
    // Something Went Wrong
} else {
    // All Fine
}

Well do I need to this ^ condition? Or using try catch is enough to check db connection?

Martin AJ
  • 6,261
  • 8
  • 53
  • 111
  • 1
    Not sure if try/catch is gonna work that well in this specific situation ... setting PDO::ERRMODE_EXCEPTION is literally the last thing that happens, so if PDO wasn't inclined to throw exceptions before that line, then I'd assume the catch block will just get silently passed over, and you might end up with a falsey `$dbh_conn` in the following lines, if establishing the connection itself didn't work. That you tried to call methods like exec and setAttribute on a non-object will only cause standard error messages, but no exceptions either. – CBroe Sep 07 '17 at 18:54
  • 1
    http://php.net/manual/en/pdo.construct.php#example-1022 – dokgu Sep 07 '17 at 18:57
  • 1
    @uom-pgregorio yeah you're right, it even says it explicitly there on the page, _"PDO::__construct() throws a PDOException if the attempt to connect to the requested database fails."_ - so that would even be the case despite the error mode not being set yet, so an error establishing the connection itself would get caught in the catch block. Not sure if the exec or setAttribute calls could really go wrong after that, but checking their success might be a good idea in any case. You wouldn't want to continue f.e. with a database connection that doesn't have the connection charset set properly. – CBroe Sep 07 '17 at 19:00

1 Answers1

1

It depends on what you set for PDO::ATTR_ERRMODE. In your case, it's set as PDO::ERRMODE_EXCEPTION, so an error will throw an Exception.

$dbh_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

This error mode however is not applied when you connect (i.e., when __constructor() is called in PDO), since a PDOException is always thrown:

PDO::__construct() will always throw a PDOException if the connection fails regardless of which PDO::ATTR_ERRMODE is currently set. Uncaught Exceptions are fatal.

You can read about the different modes here.

ishegg
  • 9,685
  • 3
  • 16
  • 31
  • So my code is fine and no need to that condition, right? – Martin AJ Sep 07 '17 at 19:02
  • That particular bit doesn't need it, since a `PDOException` will be thrown if there's an error regardless, and you're set to catch it were it to happen. However, any further use of you're `$dbo_conn` handler *will* be subject to the `ATTR_ERRMODE`. I would set the `ATTR_ERRMODE` right after creating the connection though, to minimize any uncaught problems that could happen. – ishegg Sep 07 '17 at 19:04
  • 2
    You can even set attributes in an optional array argument to the PDO constructor, right after the user & password. – Bill Karwin Sep 07 '17 at 19:07
  • Right, had forgotten all about it. `$dbh_conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password, [PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);` – ishegg Sep 07 '17 at 19:09
  • You know, still I don't know how should I write my code exactly? Since I don't know what are `PDO::ATTR_EMULATE_PREPARES` and `PDO::ATTR_ERRMODE`. – Martin AJ Sep 07 '17 at 19:10
  • @MartinAJ [something like this](https://3v4l.org/f4IOZ). The first setting is about real vs. emulated prepared statements in your connection. `false` is fine (and better), read about this [here](http://michaelseiler.net/2016/07/04/dont-emulate-prepared-statements-pdo-mysql/). The second setting is about the error mode, which is what you asked about and is answered above. – ishegg Sep 07 '17 at 19:57
  • @MartinAJ `setAttribute()` "_ returns TRUE or FALSE on failure._" (see docs). Validate that too. How to implement connection, see [my answer](https://stackoverflow.com/questions/46014772/return-multiple-response-data-in-one-response/46018999#46018999) (EDIT part). But you should create the PDO instance outside of the db adapter class and pass it as constructor argument to the class. E.g. connect() operation should not exist in the db adapter class. But all other data access methods should. Just for example of complete validations / exception handlings. P.S: I didn't check setAtribute() :-) –  Sep 07 '17 at 22:13