0

I recently started to update my Api code on an Apache server by using more inheritance. As I was a bit careful to use it in the past due to inexperience.
The thing is I noticed that for each Model instance a new database connection is set. So I created an alternative connection on a Static variable to pass to each Model. My question is will multiple database connection on each new Model instance cause problems if I create a connection such in my example below using __construct?

     class ApiEnterprises {
        protected $db;

        private $table;
        public function __construct(){
            $this->messager = new Messager();
            $this->table = 'enterprisetable';
            $this->db = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
            if ($this->db === NULL || !$this->db) {
                // set response code
                echo $this->messager->databaseFailed();
            }
        }
    }

    class ApiUsers {
        protected $db;

        private $table;
        public function __construct(){
            $this->messager = new Messager();
            $this->table = 'usertable';
            $this->db = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
            if ($this->db === NULL || !$this->db) {
                // set response code
                $this->messager->databaseFailed();
            }
        }
   }

Alternatively will a Static variable be safer? As I can remove it in the Controller __destruct method.

    class Database {
        static $connect;

        protected static function conn() {
             self::$connect = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
            return self::$connect;
        }
    }

    class ApiUserController extends Database {
        private $user_model;
        private $enterprise_model;
        public $connection;
        public function __construct($data){
            $this->connection =  parent::conn();
            //pass connection to models
            $this->user_model = new ApiUsers($this->connection);
            $this->enterprise_model = new ApiEnterprises($this->connection);
        }
    }

Dharman
  • 30,962
  • 25
  • 85
  • 135
Hmerman6006
  • 1,622
  • 1
  • 20
  • 45
  • 2
    It may be worth looking at dependency injection (https://stackoverflow.com/questions/10064970/php-dependency-injection for example) and inject the database connection. This makes testing a lot easier (amongst other things). – Nigel Ren Dec 20 '20 at 15:45

1 Answers1

2

What you need is IoC container, but before you get there you need to design your models in a such a way that they accept the database instance as a parameter in the constructor. This is called dependency injection. All dependant instances are injected into the new object at the time of instantiation.

Since your Database is useless I would not recommend to use it, but you should write some database abstraction library or use one that is already available on the web. e.g. EasyDB

Here is an example of a single dependency injection:

class ApiEnterprises {
    protected $db;
    protected $messager;

    private $table = 'enterprisetable';

    public function __construct(mysqli $db, Messager $messager) {
        $this->db = $db;
        $this->messager = $messager;
    }
}

// mysqli connection somewhere at the start of your application
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
$mysqli->set_charset('utf8mb4'); // always set the charset

// instantiate the model and pass mysqli as an argument
$enterprise = new ApiEnterprises($mysqli, $messager);
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Why do you say the Database class is useless? Of my two examples the second one uses `dependency injection` as you can clearly see that the connection instance is passed to the Models. `//pass connection to models $this->user_model = new ApiUsers($this->connection); $this->enterprise_model = new ApiEnterprises($this->connection);`. Also thank you for your answer as I now know that the second example is the better of the two. – Hmerman6006 Dec 20 '20 at 19:01
  • 2
    Yes, your second example uses dependancy injection, but the controller class inherits from database class. Unheritance should happen when a subclass is a specific case of the general case, e.g. Volvo truck inherits from Vehicle. A controller is not a database class so it should not inherit. Also, it looks like your database class doesn't do anything. Remember that mysqli is a class on its own, you don't need to wrap it unless you are going to extend it with additional functionality. – Dharman Dec 20 '20 at 19:14