PHP PDO-MYSQL: how to use database connection in different classes

I am new to PDO with MYSQL, here are my two files:

I have a connection class that I use to connect to the database:

class connection{ private $host = 'localhost'; private $dbname = 'devac'; private $username = 'root'; private $password =''; public $con = ''; function __construct(){ $this->connect(); } function connect(){ try{ $this->con = new PDO("mysql:host=$this->host;dbname=$this->dbname",$this->username, $this->password); $this->con->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); }catch(PDOException $e){ echo 'We\'re sorry but there was an error while trying to connect to the database'; file_put_contents('connection.errors.txt', $e->getMessage().PHP_EOL,FILE_APPEND); } } } 

I have an account_info class that I use to query data from a database:

 class account_info{ function getAccountInfo(){ $acc_info = $this->con->prepare("SELECT * FROM account_info"); $acc_info->execute(); $results = $acc_info->fetchAll(PDO::FETCH_OBJ); foreach ($results as $key) { $results->owner_firstname; } } } 

I include both of these files in the index.php page:

 include_once 'classes/connection.class.php'; include_once 'classes/accountinfo.class.php'; $con = new connection(); $info = new account_info(); $info->getAccountInfo(); 

I just can't get it to work. I am not getting any conclusion, I think it has something to do with the scope, but I don’t know if it is right to fix it, as I am new to this PDO and OOP. Thanks in advance.

+4
source share
2 answers

Solution 1

Replace class account_info { with class account_info extends connection {

Replace

 $con = new connection(); $info = new account_info(); 

with

 $info = new account_info(); 

and it should work.

Decision 2 (proposed)

I highly recommend you solve your problem with dependency injection in this case. Just replace the class of your account:

 class account_info { private $con; public function __construct(connection $con) { $this->con = $con->con; } public function getAccountInfo(){ $acc_info = $this->con->prepare("SELECT * FROM account_info"); $acc_info->execute(); $results = $acc_info->fetchAll(PDO::FETCH_OBJ); foreach ($results as $key) { $results->owner_firstname; } } } 

and use it in index.php as follows:

 include_once 'classes/connection.class.php'; include_once 'classes/accountinfo.class.php'; $con = new connection(); $info = new account_info($con); $info->getAccountInfo(); 

Explanation

As a general correct rule: always specify the scope keyword for functions (public, protected or private).

The first solution is called inheritance, and basically we extended the account class with the connection class to inherit all the methods and properties from the connection class and easily use them. In this case, you should keep track of naming conflicts. I suggest you take a look at class inheritance in the PHP manual.

The second solution is called dependency injection, and it is a wildly encouraged design pattern that forces your classes to accept other classes in their constructor to explicitly define the class dependency tree (in this case, the account is connection-dependent and we cannot execute the account without connection).

Another, out of thousands of possible solutions, will be the one published below, which is a design pattern called Singleton. However, this patter has been recently rated as an anti-pattern and should not be used.

+10
source

A common method is to use a singleton in your database class.

Something like that:

 class connection { private static $hInstance; public static function getInstance() { if (!(self::$hInstance instanceof self)) { self::$hInstance = new self(); } return self::$hInstance; } /* your code */ } 

Then you can just use

 $database = connection::getInstance(); $database->con->prepare(....) 

etc.

+7
source

All Articles