2013-10-12 4 views
4

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

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

function somefunction(){ 
    global $pdo; 

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

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

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

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

+1

Пожалуйста, смотрите http://stackoverflow.com/questions/12445972/stop-using-global-in-php – Achrome

+2

Считают, что вы строите новый дом. Вы ожидали бы, что электрик будет запускать всю проводку в стенах, чтобы вы могли иметь красивые розетки, где бы вы ни хотели. Но теперь представьте себе, что электрик говорит вам: «Вместо того, чтобы прокладывать всю проводку в стенах, я просто использую счетчики и метры удлинителей. Я имею в виду, что в этом плохого? У вас все еще есть электричество». – Mark

ответ

7

Есть ли какие-либо принципиальные недостатки в использовании этого подхода?

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

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

function somefunction(){ 
    global $pdo; 

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

Что делать, если вы хотите, чтобы перейти от MySQL к Монго/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 операций)

  • Мост, который объединяет ваши 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); 
} 
2

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

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

Плюс, это так легко не использовать глобальные переменные ... так почему это

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

EDIT:

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

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

Ну, как я вижу, у меня есть мои страницы, которые вызывают пользователи, такие как show_profile.php или update_settings.php. Эти страницы вызывают функции, которые находятся на моих страницах сценария, которые подключаются к базе данных.На мой взгляд, это отделяет структуру контента от вычислительной логики, которая требуется для подключения и получения/обновления данных базы данных. Наличие моих страниц для вызова функции с параметром $ pdo означает, что они должны каким-то образом взаимодействовать с объектом PDO и, таким образом, это размывает линию между моими пользовательскими страницами и страницами моей базы данных. Или это неправильный способ его использования? – Prusprus

+0

@Prusprus - show_profile.php - ваш контроллер. его предполагается создать соединение с базой данных. загрузите необходимые функции и т. д., затем загрузите представление. см. мое редактирование. – Galen

+0

Galen уже показал простой способ избежать глобальных функций в функциях. Я показал в своем ответе один из подходов OO, которые я использую в любом случае. – Uours

Смежные вопросы