Home > OS >  Properly pass connection to connstructor PDO
Properly pass connection to connstructor PDO

Time:12-01

I have spent several days reading different tutorials posts etc either info is outdated or appreciated.

I have a database connection class very simple

namespace App\Database;

use PDO;
use PDOException;

/**
 * @desc Connection to the database
 **/
class Database
{
    protected string $dbhost = DATABASE_HOST;
    protected string $dbuser = DATABASE_USER;
    protected string $dbpass = DATABASE_PASS;
    protected string $dbname = DATABASE_NAME;

    protected PDO $conn;


    public function __construct()
    {
        // Set DSN
        $dsn = 'mysql:host=' . $this->dbhost . ';dbname=' . $this->dbname . ';charset=' . $this->charset;
        $options = array(
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );

        // Create PDO instance
        try {
            $this->conn = new PDO($dsn, $this->dbuser, $this->dbpass, $options);

        } catch (PDOException $e) {
            echo 'Unable to establish a database connection: ' . $e->getMessage();
            exit();
        }
    }
}

and in my user class I passed it to the constructor

protected Database $conn;


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

but when i write a statement like this

$stmt = $this->conn->prepare($sql);

prepare is high lighted saying Method 'prepare' not found in \App\Database\Database

I would prefer not to use static or singleton

CodePudding user response:

Your variable $conn would probably better be named $db:

protected Database $db;

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

Then, when you understand that the User class has a property called db which in turn has a property called conn, the proper use might make more sense:

$stmt = $this->db->conn->prepare($sql);

However, you've defined $conn as protected, so you can't do that. You could make it public, or make a getter method in Database:

public function getConn(): PDO
{
    return $this->conn;
}

And then do:

$stmt = $this->db->getConn()->prepare($sql);

Better, I'd forget all that and instead have Database extend PDO, then just override the constructor to configure with your custom values:

class Database extends PDO
{
    public function __construct()
    {
        $dsn = sprintf(
            'mysql:host=%s;dbname=%s;charset=%s',
             DATABASE_HOST,
             DATABASE_NAME,
             DATABASE_CHARSET
        );
        parent::__construct(
            $dsn,
            DATABASE_USER,
            DATABASE_PASS,
            [
                PDO::ATTR_PERSISTENT => true,
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            ]
        );
    }
}

Now you have a PDO-compatible database object that is pre-configured, and you can just use it like a regular PDO object:

class User
{
    protected Database $db;

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

    public function whatever()
    {
        $this->db->prepare($sql);
        // ...
    }
}

$db = new Database();
$user = new User($db);
$user->whatever();
  • Related