База данных и ООП практики в PHP - PullRequest
0 голосов
/ 11 ноября 2009

Сложно объяснить эту ситуацию, но, пожалуйста, посмотрите пример.

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

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

Пример

class sms {

    function log_sms($message, $db) {

        $sql = "INSERT INTO `smslog` SET
            `mesasge` = '$message'
            ";
        $db->query($sql);

        if ($db->result)
            return true;
        return false;
    }

}

тогда на главной странице ..

$db = new db(username,pass,localhost,dbname);

$sms = new sms;

$sms->log_sms($message, $db);

Есть ли лучший подход, чем этот?

Ответы [ 4 ]

8 голосов
/ 11 ноября 2009

Есть несколько вариантов решения проблемы зависимостей (для объекта A требуется объект B):

конструктор инъекций

  class Sms { 
        function __construct($db) ....
  }

  $sms = new Sms (new MyDbClass);

сеттер впрыска

  class Sms { 
        protected $db;
  }
  $sms = new Sms;
  $sms->db = new MyDbClass;

шаблон 'реестра'

 class Registry {
     static function get_db() {
          return new MyDbClass;
 }}

 class Sms {
      function doSomething() {
          $db = Registry::get_db();
          $db->....
  }}

шаблон 'service locator'

 class Loader {
     function get_db() {
          return new MyDbClass;
 }}

 class Sms {
      function __construct($loader) {
         $this->loader = $loader;

      function doSomething() {
          $db = $this->loader->get_db();
          $db->....
  }}

  $sms = new Sms(new Loader);

автоматизированное внедрение зависимостей на основе контейнера, см., Например, http://www.sitepoint.com/blogs/2009/05/11/bucket-is-a-minimal-dependency-injection-container-for-php

   interface DataSource {...}
   class MyDb implements DataSource {...}

    class Sms {
        function __construct(DataSource $ds) ....


    $di = new Dependecy_Container;
    $di->register('DataSource', 'MyDb');
    $sms = $di->get('Sms');      

чтобы назвать несколько;)

также статья Фаулера, которую я дал вам прежде, действительно стоит прочитать

2 голосов
/ 11 ноября 2009

Для начала вы можете создать защищенную переменную $ db в каждом из ваших классов, которые должны использовать базу данных. Затем вы можете передать $ db в конструктор класса. Вот обновленный код:

$db = new db(username,pass,localhost,dbname);
$sms = new sms($db);
$sms->log_sms($message);

class sms {

    protected $db;

    public function __construct($db) {
        $this->db = $db;
    }

    public function log_sms($message) {
        $sql = "INSERT INTO `smslog` SET
                `mesasge` = '$message'
                ";
        $this->db->query($sql);

        if ($this->db->result)
                return true;
        return false;
    }
}

Этот пример в PHP 5.

1 голос
/ 11 ноября 2009

Синглтон также является хорошей практикой в ​​разработке приложений. Они очень полезны, чтобы избежать повторных запросов или вычислений во время одного вызова. Передача объекта базы данных каждому методу или конструктору не очень хорошая идея, вместо этого используйте Singleton.

расширить базу данных или вставить статический метод в ваш класс БД. (Я бы также вызвал для config внутри метода конструктора БД)

class database extends db
{
    public static function instance()
    {
        static $object;

        if(!isset($object))
        {
            global $config;

            $object = new db($config['username'],$config['pass'],$config['localhost'],['dbname']);
        }

        return $object;
    }
}

сделайте ваш метод статичным

class sms {

    public static function log($message) {

        $sql = "INSERT INTO `smslog` SET `mesasge` = '$message'";

        database::instance()->query($sql);

        return (bool) database::instance()->result;
    }
}

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

sms::log($message);
0 голосов
/ 11 ноября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...