如何在多个类中使用PDO连接到数据库?

I have multiple classes and most of them need to connect to database,

How can I set PDO options/host/dbname etc only once and then use it in every class while having the following in mind:

  1. I don't want to wrap PDO
  2. I need to close the PDO connection after each query ($db=null), so I simply cannot just use $db = new PDO(...) and then pass $db to my classes

I want to skip having this in every class that needs to connect to the database:

<?php

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
try {
     $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

If you want complete control over opening and closing connections then I suggest we only centralise the $dsn, $user, $pass and $options variables. I'm assuming there are also variables like $host, $db and $charset which you did not reveal to us but lets add them.

Lets call this file global_db.php:

<?php
$host = "127.0.0.1";
$db = "mydb";
$charset = "UTF-8";
$user = "root";
$pass = "";
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

That looks like we have all the goods there, keep in mind I am not testing this so we might get a syntax error or two.

Now in our classes or other php files where we want to open a connection.

Lets call this page fooClass.php

<?php
require_once 'global_db.php';

class FooClass {
    public function __construct() {
        try {
            $pdo = new PDO(
                    $GLOBALS['dsn'],
                    $GLOBALS['user'],
                    $GLOBALS['pass'],
                    $GLOBALS['options']);
        } catch (\PDOException $e) {
            throw new \PDOException($e->getMessage(), (int)$e->getCode());
        }
    }
}

That should do the trick or at least give you a general idea on where to go from here on your own route. There are many other ways to accomplish similar but no need to overcomplicate things.

nJoy!