-1

I have what seems like a simple query but I have not found an answer elsewhere. I have 2 classes, one called DB which essentially connects to the database and can then run queries. I instantiate it at the top of the document $db= new DB; and I can then run a series of queries on the database throughout the page. The issue I am having is that I want to use this instance within another class I have called User. I know I can either instantiate again but this does not make sense OR pass the instance of DB when instantiating User, for instance $user = new User($db); but considering the $db instance will be used by most classes I am going to create I am thinking there is a better solution to import it into other classes. I have looked at the global route but I read it is bad practice + I am getting unexpected global error

class User{
    global $db;

    public function __construct()
    {
        var_dump($this-> db);
    }//end constructor
}//end class
Dharman
  • 30,962
  • 25
  • 85
  • 135
user1620090
  • 499
  • 6
  • 19
  • 5
    `global` is in invalid keyword there. You can only use it within functions. And yes, it's a bad idea and `new User($db)` is the best idea. (Whether `User` should have direct access to a database or not is another topic; if you're following the Active Record pattern, then yes, otherwise no.) – deceze Jun 30 '20 at 11:21

2 Answers2

1

Since your DB client will be instantiated once and then used everywhere else my initial thought was to recommend passing it as a constructor parameter (dependency injection), but since you are not fan of this approach, I would recommend making your DB client a singleton class, which means it can only be instantiated once and any subsequent attempt would return the same instance everywhere.

You can see a detailed response about singleton classes in PHP at Creating the Singleton design pattern in PHP5.

As a quick example, your DB would look like similar to this:

final class DB
{
    public static function getInstance()
    {
        static $inst = null;

        if ($inst === null) {
            $inst = new self();
        }

        return $inst;
    }

    private function __construct()
    {
        // your code here ...
    }

    // your code here ...
}

And then, on your User class you would just get the DB class instance:

class User {
    // your code here ...

    public function doSomething() {
        $db = DB::getInstance();

        // your code here ...
    }
}
  • Thank you, I was hoping there would be an easy way to retrieve an instance, I will keeping it to the function so – user1620090 Jun 30 '20 at 13:49
0

PHP does not handle scopes like Javascript does, your $db is undefined.

The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well […] Within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope.

Source: http://php.net/manual/en/language.variables.scope.php

This means that there is only a global scope and a function/method scope in PHP. So, either pass the $db instance into the method as a collaborator

class User{

    public function __construct() {}

    public function getInfo(Database $db) {
        $db->query( /* ... */ );
    }
}

$user = new User();
$db = new Database();
$user->getInfo($db);

or pass it in the constructor (dependency injection)

class User{
    private $db;

    public function __construct(Database $db)
    {
        $this->db = $db;
    }

    public function getInfo() {
        $this->db->query( /* ... */);
    }
}

$db = new Database();
$user = new User($db);
$user->getInfo();
PatricNox
  • 3,306
  • 1
  • 17
  • 25