1

What is 'best practice' regarding accessing the database when you have multiple classes with methods that do queries?

Global $db variable:

$db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

class Item {
    private $id;

    function __construct($id) {
        $this->id = $id;
    }

    public function remove() {
        global $db;

        // queries and stuff.
    }
}

Or maybe, passing the $db to the constructor?

$db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

$item = new Item(5,$db);

class Item {
    private $id;
    protected $db;

    function __construct($id,$db) {
        $this->id = $id;
        $this->id = $db;
    }

    public function remove() {
        // queries and stuff.
    }
}

Or maybe another way is better than both of these?

kgongonowdoe
  • 425
  • 3
  • 16

2 Answers2

0

The constructor injection is the better way. The class clearly states, that it needs access to the database. This will help in maintainig the app in the long run. You can use a Dependency Injection Container (DI or IOC) to automatically fill in the needed services. The are numerous good blog posts available on using deoendency injection in PHP. The Symfony documentation does a good job on explaining the benefits.

Globals are considered bad practice in OOP and should be omitted completely.

A third possibility would be the use of a singleton (not considered a best practice) or of a static facade like the older Laravel versions. Static facades are a hot topic in discussion. You can find more on them in the Laravel documentation.

Markus Müller
  • 2,611
  • 1
  • 17
  • 25
0

For global objects which can potentially be used anywhere I personally prefer singleton classes:

class DBConnection {

     private static $instance = null;

     private $db;
     private function __construct() {
         $this->db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
     }

     public static function getDB() {
           if (self::$instance === null) { 
               self::$instance = new self();
           }
           return self::$instance->db;
     }    
}

This way you can just call: DBConnection::getDB() anywhere you need to, and this can also work with auto-loading.

kgongonowdoe
  • 425
  • 3
  • 16
apokryfos
  • 38,771
  • 9
  • 70
  • 114