0

This is my code:

class DB {
static $instance;

function get() {
    if (self::$instance === null) {
        self::$instance = new PDO('mysql:host=localhost;dbname=forum', 'root', 'root');
    }
    return self::$instance;
}

function getAllUsers() {
    $users = array();
    $sql = "SELECT * FROM users";
    foreach (self::get()->query($sql) as $row) {
        $users[] = new User($row);
    }
    return $users;    
}
}

And now I'm calling the getAllUsers function in here:

class App {
function showUsers() {
    $users = DB::getAllUsers();
}

Except its giving me an error:

Warning: Invalid argument supplied for foreach()

When I'm doing var_dump on self::get im getting a bool(false)

Can someone tell me what I'm doing wrong?

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
Moose Moose
  • 267
  • 5
  • 13
  • I would like to point out that var_dump(self::get()) displays object(PDO)#2 (0) { } – Moose Moose Dec 15 '12 at 20:45
  • Why aren't you [`try/catch`ing and raising exceptions](http://stackoverflow.com/questions/8343141/whats-the-correct-way-to-use-a-new-pdo-in-a-class-context)? You don't give your class any route to fail gracefully here. – Jared Farrish Dec 15 '12 at 20:47
  • If you call your class instance using `self::get()`, then `get()` should be declared `static`. – Tchoupi Dec 15 '12 at 20:48
  • My initial thought was that the error was hiding, as I have not created the database yet. But I've surrounded it with a try/catch and it's still not giving me a PDOException – Moose Moose Dec 15 '12 at 20:49
  • The class should be static yea im well aware of that. But for some reason it's still working without the static keyword. I'm getting a pdo object back – Moose Moose Dec 15 '12 at 20:50
  • Have you tried http://php.net/manual/en/pdo.errorinfo.php? – Tchoupi Dec 15 '12 at 20:50
  • Ok it's fixed now that I've created the tabel and database. Still I'm finding it quite weird that 1. even though the function get is not static, I'm still able to call it, and 2. even when try/catching the pdo->query I was still not getting errors. Anyway it's fixed now – Moose Moose Dec 15 '12 at 20:51
  • Yes it works, check out http://stackoverflow.com/questions/13435405/accessing-private-variable-in-php-pdo/13435539#13435539 and http://stackoverflow.com/questions/2439036/does-static-method-in-php-have-any-difference-with-non-static-method – Tchoupi Dec 15 '12 at 20:54
  • Static class methods may be accessed as long as they do not try to access something in one it's own instantiated objects. See: http://codepad.org/BhrBiXPE It's always been this way. If you're intending to use a method as static, *label* it as static so you don't accidentally overlook it and do something you shouldn't *actually* do. – Jared Farrish Dec 15 '12 at 20:59

1 Answers1

7

PDO::query returns a PDOStatement object only if it is successful in sending the query to the database and getting back a valid response (i.e. there were no SQL errors returned by the driver). However, in the event that it fails it will return false. So you must check for this in order to handle errors. Also, you can optionally put PDO into Exception Mode to have it throw an exception any time it encounters an error. That way you can use try/catch to handle errors whenever call on PDO objects. See the example below...

With PDO's default error mode (silent):

if ($result = self::get()->query($sql)) {
    /* Iterate here */
    foreach ($result as $row) {
        /* Do whatever you want with $row */
    }
} else {
    /* Handle errors here */
    echo "There was an error with the query!";
    var_dump(self::get()->errorInfo());
}

With PDO in Exception Mode:

/* Put PDO Into Exception Mode */
self::get()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
    foreach (self::get()->query($sql) as $row) {
        /* Do whatever you want with $row */
    }
} catch(PDOException $e) {
    /* If PDO fails we handle it here */
    echo "Your query failed: " . $e->getMessage();
}
Sherif
  • 11,786
  • 3
  • 32
  • 57