sushibrain
sushibrain

Reputation: 2780

PDO namespace not found, while doing it correctly

So namespacing and PDO, with the experience that I'm having now, I see it as hell.

Warning: include_once(C:/xampp2/htdocs\application\classes\class.pdo.php): failed to open stream: No such file or directory in C:\xampp2\htdocs\application\bootstrap.php on line 18

Warning: include_once(): Failed opening 'C:/xampp2/htdocs\application\classes\class.pdo.php' for inclusion (include_path='.;C:\xampp2\php\PEAR') in C:\xampp2\htdocs\application\bootstrap.php on line 18

Fatal error: Class 'C_Red\Storage\PDO' not found in C:\xampp2\htdocs\application\classes\class.database.php on line 13

How is this happening if I'm connecting like this:

public static function init()
    {
        global $_CONFIG;
        try
        {
            self::$conn = new \PDO('mysql:hostname=127.0.0.1;dbname=c_red,root,123',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
        }
            catch(PDOException $e)
        {
            throw new PDOException ($e->getMessage);
        }
        date_default_timezone_set('Europe/Amsterdam');
    }

Is it not the job of the \ in front of PDO to set that it's not in the namespace that I'm working in?

How is this error possible?

Thanks.

Upvotes: 2

Views: 718

Answers (1)

Michael Berkowski
Michael Berkowski

Reputation: 270617

It isn't merely the new \PDO() constructor which must be namespaced, but also references to its constants and exceptions. You declare PDO attributes later in the constructor, but don't namespace them with a backslash:

// First fix the namespacing...
self::$conn = new \PDO('mysql:hostname=127.0.0.1;dbname=c_red,root,123',array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION));
//--------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

So the error message lead you to look to new PDO() but PHP is actually complaining about PDO::ATTR_ERRMODE in the same line.

Same goes for the catch block:

 catch(\PDOException $e)
 {
     throw new \PDOException ($e->getMessage);
 }

Second: You are missing a closing quote on the DSN string, before the username and password. The constructor should look fully like:

// user, password are 2nd, 3rd arguments to constructor!
self::$conn = new \PDO('mysql:hostname=127.0.0.1;dbname=c_red', 'root', '123', array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION));

... where 'root' and '123' are separate arguments to the constructor, not part of the DSN string.

Note about using the use keyword after comments:

You could import PDO into your namespace with

use \PDO;

which would allow you to utilize PDO and its constants without prefixing them with a backslash. However, you would also have to use \PDOException because the exception is not within a PDO namespace (there is no such namespace). Both exist at the global namespace, so there may not be much to gain by importing them with use. My opinion and preference would be to continue prefixing them as \PDO and \PDOException.

Upvotes: 2

Related Questions