2014-10-07 3 views
2

У меня есть веб-служба PHP, которая использует один класс API для вызова методов веб-службы. У меня есть определенные классы для каждого модуля в моем приложении: сообщения, пользователи, Логин и т.д. Мой класс API это что-то вроде:PHP: использование соединений MySQL в одиночном классе

class API{ 

    private static $api; 
    private $database; 
    private $post; 
    private $user; 

    public function __construct(){ 
     $this->database = new DataBase(); 
     $this->post = new Post(); 
     $this->user = new User(); 
    } 

    public static function getInstance(){ 
     if(empty(self::$api)){ 
      self::$api = new API(); 
     } 
     return self::$api; 
    } 
} 

Таким образом, чтобы получить мои сообщения пользователя, я бы назвал $api->post->getPosts() внутри класса API , или API::getPosts() вне класса API. Класс API - это фасад. Каждый дочерний класс имеет свой собственный экземпляр DataBase. Например, Post и User имеет следующее:

class User{ 
    private $database; 

    public function __construct(){ 
     $this->database = new DataBase(); 
    } 
} 

Мой DataBase конструктор что-то вроде:

public function __construct() { 
    try{ 
     $this->db = new \PDO(
       "mysql:host=$this->host;dbname=$this->base;", 
       $this->user, $this->pass, 
       array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'") 
     ); 
    }catch(\PDOException $e){ 
     echo "<b>Error:</b> {$e->getMessage()} in <b>{$e->getFile()}</b> on line <b>{$e->getLine()}</b>"; 
     die(); 
    } 
} 

Проблема заключается в том: каждый запрос использует до пяти соединений MySQL для создания ответа. Например: регулярный запрос включает проверку входа, получение информации о пользователе, получение сообщений и т. Д. Мне было интересно, могу ли я передать экземпляр DataBase с фасада API на классы детей. Я пытался что-то вроде:

public static function getDatabase(){ 
    $api = self::getInstance(); 
    return $api->database; 
} 

Но каждый раз, когда я называю API::getDatabase() из классов детей, я получаю MySQL слишком много соединений ошибки, потому что этот метод вызывает API __construct() и создает новый экземпляр DataBase.

Любая идея, как я могу утилизировать мой экземпляр DataBase или соединения, чтобы избежать траты соединений?


UPDATE

Как предлагается ниже, я использовал зависимость шаблон инъекции передать мой DataBase объект из API фасада к своим детям:

public function __construct(){ 
     $this->database = new DataBase(); 
     $this->post = new Post($this->database); 
     $this->user = new User($this->database); 
    } 
+1

вы» re уже использует одноэлемент в одном классе. почему бы не сделать ваше соединение с БД одним синглом? Существует редко причина открывать соединение с БД каждый раз, когда вы выполняете операцию db. Единственные два обычных оправдания - это подключение к совершенно другим серверам баз данных или подключение к другим учетным данным. –

+0

@MarcB Может ли класс singleton 'DataBase' снизить производительность моих запросов? Я объясню, что я читал, что PHP и MySQL обрабатывают все запросы в одном потоке. Таким образом, использование одноэлементного класса DataBase будет создавать очередь запросов, где каждый запрос должен ждать выполнения предыдущего. – bodruk

+1

Блок запросов базы данных, а PHP не многопоточен. –

ответ

0

(Для того, чтобы принять это из «Без ответа».)

Комментирующие предлагают Тэд и OP проверено:

Используйте шаблон инъекции зависимостей, чтобы передать объект DataBase от API фасада к своим детям: (. На самом деле private был предложен, но не подтвержден)

private function __construct(){ 
    $this->database = new DataBase(); 
    $this->post = new Post($this->database); 
    $this->user = new User($this->database); 
} 

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