Keir Simmons
Keir Simmons

Reputation: 1684

Ensuring a parent class' constructor is called only for the first instance, in PHP

I am working on a model where I will have one parent class, named database. This will have the methods which will directly work on the database. I will have a few other classes which will extend the database class in order to use its functionality (access the database). However, these classes need to have their own __construct method defined, and the database class will connect to the database in its __construct method.

An example of what I mean is below, the __construct of the user class explicitly calls a query (which will only work if the __construct method of the database class has been invoked).

<?php
    class database {
        private $mysqli;

        function __construct() {
            $this -> mysqli = new mysqli(..login_details..);
        }

        public function query($query) {
            return $this -> mysqli -> query($query);
        }

    }

    class user extends database {

        function __construct() {
            $users = $this -> query("SELECT * FROM users");
            while($u = $users -> fetch_assoc()) {
                print_r($u);
            }
        }

    }

    $user = new user();

?>

One way around it is to explicitly call parent :: __constructor(); in the subclass, but I do not want it to have to re-connect to the database for each inherited class, i.e I only want it to connect the first time a class inherits it. How would I go about doing this? Would I have to do this outside of the database construct?:

private static $mysqli = new mysqli(...);

Or am I going about implementing my model the completely wrong way?

Upvotes: 1

Views: 118

Answers (1)

Bryan
Bryan

Reputation: 3494

I would say go with dependency injection instead of inheritance. Think about the is a relationship inheritance usually implies. For instance a class cat may inherit from class mammal. This makes sense as a cat is a mammal.

This really doesn't make sense in your case. Maybe pass in a database object in the constructor when you instantiate the user class.

class user{
         private $DB = null;

        function __construct(database $DB) {
            $this->DB = $DB;
            $users = $this -> DB -> query("SELECT * FROM users");
            while($u = $users -> fetch_assoc()) {
                print_r($u);
            }
        }

    }
$DB = new database();
$user = new user($DB);

There is more than one way to get the result you want, I just think this is a more appropriate approach. Also you can use the original database object without calling the constructor multiple times.

Upvotes: 1

Related Questions