2013-03-30 2 views
0

В настоящее время у меня есть несколько классов, все из которых зависят от одного класса - класса Database. Каждый класс требует, чтобы экземпляр класса базы данных функционировал, и с этим я немного обеспокоен.PHP OOP ~ Несколько классов требуют того же класса

Прежде чем преобразовать весь свой процессуальный код в объектно-ориентированный код, мне нужно понять это. I В настоящее время у меня есть одно соединение с базой данных для всей программы. Однако из того, что я понимаю, когда я конвертирую свой код в ООП, у меня будет несколько классов с открытыми подключениями к базе данных в одной программе. (все эти классы будут включены в основной файл программы).

Как это реализовать правильно? Я предполагаю наличие 5 открытых подключений к базе данных в одной программе, конечно, не так.

+0

вы можете найти эту тему отношения: http://stackoverflow.com/questions/11369360/how-to-properly-setting-up-pdo-connection –

ответ

0

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

Передача соединения с базой данных в конструктор

class Foo { 

    private $database = null; 

    public function __construct(&$database) { 
     $this->database = $database; 
    } 
} 
$connection = mysql_connect(..); 
$bar = new Foo($connection); 

Singleton

class DatabaseConnection { 

    private static $instance = null; 

    private function __construct() { 
    } 

    public static function &getInstance() { 
     if (DatabaseConnection::$instance == null) { 
      DatabaseConnection::$instance = new DatabaseConnection(); 
     } 
     return DatabaseConnection::$instance; 
    } 
} 

$mysql_query("...", DatabaseConnection::getInstance()); 

& означает передачу по ссылке, так что будет только один экземпляр объекта базы данных, даже если он используется в нескольких разных файлах, классах или функциях. См. http://php.net/manual/en/language.references.pass.php для получения дополнительной информации.

+0

Это, безусловно, отвечает на мой вопрос. Это то, что я ожидал сделать. Однако это кажется таким нечистым. Необходимо прибегнуть к статической переменной для хранения экземпляра класса. Ну что ж. Спасибо! –

+0

Шаблон дизайна Singleton хорошо известен, хотя и не нравится многим, так как он, как вы говорите, так нечист. –

+0

@SteffanLong, в случае, если вы скопировали код, в методе getInstance() был заблудившийся восклицательный знак, хотя теперь он исправлен. –

0

Совет Jakobs по использованию агрегации Singleton + является обоснованным советом. К этому я бы добавил Doctrine ORM/DBAL, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html

Избегайте сочетания одноплодной экземпляр непосредственно в объекты, используя их внутри класса «Foo», но скорее передать одноэлементный экземпляр конструктору. Таким образом, у вас больше развязки и, следовательно, больше свободы.

+0

Спасибо за ваш совет. –

+0

Добро пожаловать. metal_fan: s ответ тоже замечательный, Dependency Injection - это то, что вы должны использовать, но вам, вероятно, придется хранить зависимости приложений в виде реестра для вашего приложения - я бы сохранил EntityManager или DB-handle там и затем реализуйте какое-то приложение -> getInstance() -> getDependency («DB»). В качестве альтернативы, если вы решили использовать MVC, вы всегда можете передать DB-дескриптор вашему контроллеру «за саксофоном». Btw, если у вас есть привилегия использования PHP5.3, используйте последнее статическое привязку: http://stackoverflow.com/questions/5152085/php-late-static-binding-in-singleton – Centril

+0

Это может быть очень хорошо так что, но просто заявив, что «singleton NEVER good advice» не является ни тем, ни другим. Если вы предъявляете такое требование, по крайней мере, поддержите его. Мое мнение о синглтоне заключается в том, что его следует избегать - иногда это зло. Мой взгляд на это прагматичен. Кроме того, в моем совете я также поднял развязку и доктрину ... – Centril

1

Если у вас есть классы, которые зависят от абстракции базы данных, то Инъекция зависимостей - это путь.

class PDOProvider extends PDO 
{ 
    public function __construct() 
    { 
     try { 

      parent::__construct(...); 
      $this->setAttribute(....); 

     } catch(PDOException $e){ 
      die($e->getMessage()); 
     } 
    } 
    // ... 
} 

class Users 
{ 
    private $provider; 

    public function __construct(PDOProvider $provider) // <- Injecting class dependency 
    { 
     $this->provider = $provider; 
    } 

    public function insert(array $stuff) 
    { 
     try { 

     $this->provider->prepare("INSERT ..."); 
     $this->provider->execute(array(..)); 

     } catch(PDOException $e){ 
      //... 
     } 
    } 
} 
+0

В этом случае использование инъекции зависимостей, как вы показали, замечательно. Однако не так хорошо, чтобы модель узнала о базе данных ... Она должна считаться уровнем обслуживания и быть отделена от модели. Что делать, если вы хотите изменить свой уровень сервиса модели на что-то еще? Тогда у вас проблемы! – Centril

+0

Вот некоторые соображения: http://stackoverflow.com/questions/5863870/how-should-a-model-be-structured-in-mvc/5864000#5864000 – Centril

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