2

I'm using the PDO MySQL driver in my PHP application, and in one of my models I have this:

public function getAllUsers() {
    $this->st = $this->db->query('SELECT name FROM users');
    $this->st->setFetchMode(PDO::FETCH_OBJ);
    $users = array();
    while($row = $this->st->fetch()) {
        array_push($users, $row->name);
    }

    return $users;
}

$this->db is the database handle inherited from the parent class. The problem is, if for some reason $this->db isn't a valid database object I get this fatal error:

Call to a member function query() on a non-object

this is to be expected, but to make it easier for my end user I don't want to make them wrap the method in a try-catch block or do any error checking, I'm wondering how I can catch that fatal error and throw an exception instead (the entire application uses exceptions).

Is there some sort of PDO option that makes it only throw exceptions in cases like these?

Edit: re-read and I should add that I have a lot of code wrapped in a try-catch block further up in the inheritance tree, so if this produced an exception instead of a fatal error I would be able to catch it and terminate the application gracefully.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
James Dawson
  • 5,309
  • 20
  • 72
  • 126
  • What reasons would `$this->db` not be a valid database object? It seems like that should be guaranteed if you are using it to fetch data in this class. Why not just check it first and if it isn't a valid object, throw an exception saying that there is no database connection. – drew010 Oct 10 '12 at 17:09

1 Answers1

3

You can force PDO to throw an exception with this

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

But I don't think this will help for your case since it's not related with PDO it just null object problem.

What you're trying to do is equivalent to this

$a = null;
$a->query();
Rezigned
  • 4,901
  • 1
  • 20
  • 18
  • Hmm, good point. It's just that sometimes the database connection isn't initialized because not all models need a database connection. If a user tries to use this method when they've not loaded the database connection it will through this error. Oh well, looks like I'll have to do some checking before I try to set up `$this->st` after all. – James Dawson Oct 10 '12 at 17:17
  • If you really want to do that you can use the magic method e.g. `__get` – Rezigned Oct 10 '12 at 17:18
  • If you want errors to be handled as exceptions, you can [set a global error handler](http://php.net/manual/en/class.errorexception.php). The built-in `ErrorException` is for this purpose. (See Example #1 on the linked docs page.) – alttag Jul 30 '16 at 16:29