Как подключиться к базе данных, используя PDO в нескольких классах?

#php #pdo

#php #pdo

Вопрос:

У меня есть несколько классов, и большинству из них необходимо подключиться к базе данных,

Как я могу установить параметры PDO / host / dbname и т.д. Только один раз, А затем использовать его в каждом классе, имея в виду следующее:

  1. Я не хочу переносить PDO
  2. Мне нужно закрывать PDO-соединение после каждого запроса ( $db=null ), поэтому я просто не могу просто использовать, $db = new PDO(...) а затем передавать $db своим классам

Я хочу пропустить это в каждом классе, которому необходимо подключиться к базе данных:

 <?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());
}
  

Комментарии:

1. I need to close the PDO connection after each query почему?

2. @kuh-chan Из-за проблем с производительностью слишком много посещений в секунду и слишком много запросов, которые нельзя кэшировать, как упоминается в документе PDO: The connection remains active for the lifetime of that PDO object... To close the connection, you need to destroy the object...

3. сколько запросов вы ожидаете в секунду? в любом случае… как насчет статического фабричного метода, который создает новый объект pdo?

4. Если вы каждый раз открываете соединение, похоже, что создание класса для обработки подключения к БД должно немного сократить это. Тогда вы будете повторно использовать одно соединение вместо нескольких. Например, вы могли бы подключаться к базе данных 100 раз по мере запуска вашего приложения. Лучше подключиться 1 раз. Хотя соединения и используются повторно, но, как правило, чище подключаться к одному месту, а затем делиться этой же ссылкой.

5. @kuh-chan В часы пик (возможно, 20-30 минут ежедневно) они ожидают ~ 2-5000 запросов в секунду, в другое время это примерно ~ 500 qps, вот почему я вынужден отказаться от фреймворков и максимально упростить их, я действительно обеспокоен этим, поэтому пытаюсь выполнить поиск и убедиться, что для каждой отдельной строки кода я делаю X_X, который я исследовал, и, по-видимому, закрытие соединения после запроса в PDO помогает…

Ответ №1:

Если вы хотите получить полный контроль над открытием и закрытием соединений, тогда я предлагаю централизовать только переменные $dsn , $user $pass и $options . Я предполагаю, что есть также переменные типа $host , $db и $charset , которые вы нам не раскрыли, но давайте добавим их.

Давайте вызовем этот файл 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,
];
  

Похоже, у нас есть все необходимое, имейте в виду, я это не тестирую, поэтому мы можем получить синтаксическую ошибку или две.

Теперь в наших классах или других файлах php, где мы хотим открыть соединение.

Давайте вызовем эту страницу 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());
        }
    }
}
  

Это должно сработать или, по крайней мере, дать вам общее представление о том, куда двигаться дальше по вашему собственному маршруту. Есть много других способов выполнить подобное, но не нужно все усложнять.

Радуйся!