Сохранение моего соединения PDO в качестве глобальной переменной

Задавая еще несколько вопросов о запросах PDO, мне сказали, что сохранение моего объекта соединения PDO как глобального для использования его в моих различных функциях, вызывающих запросы к моей базе данных, обычно является плохой практикой.

Вот как я обычно использую свой объект PDO:

function somefunction(){ global $pdo; $statement = $pdo->prepare("some query"); $statement->execute(); } 

Аргументы, которые я прочитал, больше касаются обслуживания и отладки кода, где трудно отследить, кто изменил объект PDO и где в коде он будет. Другие люди просто отвергают использование глобальных переменных для хранения объекта PDO, но не могут действительно объяснить, почему глобальные переменные являются плохим подходом.

Тем не менее, для проектов с небольшим размером с одной базой данных действительно ли недостаток в использовании глобальной переменной? Обычно у меня есть сценарий подключения и сценарий моих функций отдельно, где скрипт функций требует require_once () сценарий подключения, где создается мой объект PDO. Таким образом, мое соединение всегда устанавливается, и все изменения в объекте PDO выполняются в моем сценарии подключения.

Существуют ли какие-либо фундаментальные недостатки в использовании этого подхода?

Существуют ли какие-либо фундаментальные недостатки в использовании этого подхода?

Самое первое, что вам нужно понять, это то, что $pdo является частью логики хранения . Это означает, что он должен использоваться только внутри классов, которые занимаются абстрактным доступом к данным , будь то таблица SQL или коллекция.

Давайте посмотрим на ваш код,

 function somefunction(){ global $pdo; $statement = $pdo->prepare("some query"); $statement->execute(); } 

Что делать, если вы хотите переключиться с MySQL на Mongo / MSSQL / PgSQL, в будущем? Тогда вам придется переписать много кода.

И для каждого поставщика базы данных вам нужно будет создать отдельный файл с другой переменной. Именно так

 function somefunction(){ global $mongo; return $mongo->fetch(...); } 

Используя глобальное состояние, вы получаете дублирование массового кода , потому что вы не можете передавать параметры и, следовательно, не можете изменять поведение функции во время выполнения.

Теперь давайте посмотрим на это,

 function somefunction($pdo){ $statement = $pdo->prepare("some query"); $statement->execute(); } 

Здесь $pdo передается как аргумент, поэтому глобального состояния нет. Но проблема все еще остается, вы в конечном итоге нарушаете принцип единой ответственности

Если вы действительно хотите что-то поддерживаемое, чистым и очень читаемым, лучше придерживаться DataMappers . Вот пример,

 $pdo = new PDO(...); $mapper = new MySQL_DataMapper($pdo); $stuff = $mapper->fetchUserById($_SESSION['id']) var_dump($stuff); // Array(...) // The class itself, it should look like this class MySQL_DataMapper { private $table = 'some_table'; private $pdo; public function __construct($pdo) { $this->pdo = $pdo; } public function fetchUserById($id) { $query = "SELECT * FROM `{$this->table}` WHERE `id` =:id"; $stmt = $this->pdo->prepare($query); $stmt->execute(array( ':id' => $id )); return $stmt->fetch(); } } 

Вывод

  • Неважно, если ваш проект небольшой или большой, вы всегда должны избегать глобального состояния во всех его формах (глобальные переменные, статические классы, синглтоны) – ради удобства обслуживания кода

  • Вы должны помнить, что $pdo не является частью вашей бизнес-логики. Это часть логики хранения. Это означает, что прежде чем вы начнете что-то делать с бизнес-логикой, например, тяжелые вычисления, вы должны действительно абстрагировать доступ к таблице (включая операции CRUD)

  • Мост, который объединяет вашу computation logic data access abstraction и computation logic , обычно называется службой

  • Вы всегда должны передавать функции функции в качестве параметров

  • Вам лучше перестать беспокоиться о своем коде и начать думать об уровнях абстракции.

  • И, наконец, прежде чем вы начнете делать какие-либо вещи, сначала инициализируйте все свои службы в bootstrap.php а затем начните запрашивать хранилище в соответствии с вводом пользователя ( $_POST или $_GET ).

Как,

 public function indexAction() { $id = $_POST['id']; // That could be $this->request->getPost('id') $result = $this->dataMapper->fetchById($id); return print_r($result, true); } 

Для крошечного крошечного проекта не будет много вреда для использования глобального. Когда размер проекта начинает расти, когда ситуация начинает ухудшаться.

если ваша somefunction() имела в ней 300 строк с использованием 5 глобальных переменных, кто-то, смотрящий на ваш код, не знал бы, что функция использует внешние переменные, если только они не прошли через нее, ища глобальные переменные.

Кроме того, так легко не использовать глобальные переменные … так зачем это делать

 function somefunction( PDO $pdo ){ $statement = $pdo->prepare("some query"); $statement->execute(); } 

РЕДАКТИРОВАТЬ:

show_profile.php – ваш контроллер. Контроллер собирает все данные для представления и загружает представление. Это очень упрощенная версия.

 require( 'functions.php' ); $db = new PDO(); $user = get_user( $db, $user_id ); require( 'view.php' );