0

I'm new to using namespaces. In this example I made class, which handles database connection and I'm trying to use it inside the other classes. Can you explain what is wrong?

Connection.php

namespace Database;

class Connection
{
    private static $instance = null;

    private $pdo;

    private function __construct()
    {
        $this->pdo = new PDO("mysql:host=localhost;dbname=database;", "root", "pw");
    }

    public static function get()
    {
        if (is_null(self::$instance))
            self::$instance = new Connection();
        return self::$instance;
    }
}

Auth.php

namespace PHPAuth;

use Database\Connection;

class Auth
{
    protected $dbh;

    public function __construct()
    {
        $this->dbh = Connection::get();
        ...

Thanks in advance.

Edit: Ok, now I included autoloader and including class is now working correctly. But now I'm getting error when using $dbh in Auth like $query = $this->dbh->query("SELECT * FROM...");

Fatal error: Call to undefined method Database\Connection::query() in...

lingo
  • 1,848
  • 6
  • 28
  • 56
  • 3
    How are you loading/including your files? Have you set up any autoloader? Namespaces doesn't automatically load the files. – M. Eriksson Dec 23 '16 at 16:14
  • Btw, in the file with your Connection class, you need to add `use PDO;`, or that class won't be found either, since you are in the `Database` namespace. PHP's core classes are always (there might be exceptions to this?) in the top namespace. – M. Eriksson Dec 23 '16 at 16:16
  • Please include all errors you get when you run your script. Also include information about autoloader you are using (see http://stackoverflow.com/questions/28046052/composer-autoload-full-example). What IDE do you use BTW? PhpStorm underline everything related to "class could not be found". I recomend it. – Northys Dec 23 '16 at 16:35
  • @MagnusEriksson Thanks! So there was a problem with including the class. Now I set up autoloader and it's working, but I'm getting another error. Can you help me? – lingo Dec 23 '16 at 16:41

1 Answers1

1

First issue with class not found

I'll add the answer (which worked for you) for the first issue for reference: "Namespaces doesn't automatically load the files. You need to add an autoloader for that."

Second issue with undefined method

Fatal error: Call to undefined method Database\Connection::query()

The answer is in the error message. You've made the class Database\Connection into a singleton where Database\Connection::get() returns an instance of itself (which doesn't have any ->query() method), and not the actual PDO instance.

If you want that method to return the PDO instance instead, I would do something like this:

namespace Database;

use PDO;

class Connection
{
    private static $pdo;

    private function __construct() 
    {
        // Leave the constructor private so it still becomes
        // a singleton and so we can't instantiate this class.
    }

    public static function get()
    {
        if (is_null(self::$pdo)) {
            self::$pdo = new PDO("mysql:host=localhost;dbname=database;", "root", "pw");
        }

        return self::$pdo;
    }
}

Now the Connection class have become a Factory for the PDO-connection.

Connection::get() will return the same PDO instance over and over and you should be able to call $this->dbh->query("...") from your Auth class.

M. Eriksson
  • 13,450
  • 4
  • 29
  • 40