2013-05-29 2 views
8

У меня возникла проблема с пониманием этого. Я хотел бы начать переписывать старый код функции MySQL PDO. Образом она была создана, в том, что внешний файл, содержащий эту линию (среди прочего):PDO включение в класс

// db.php file 

$DB = new dbConnect(SERVER,DB,USER,PASSWORD,3306); 

function my_autoloader($class) 
{ 
    require_once ($_SERVER['DOCUMENT_ROOT']."/includes/".'class.' . $class . '.php'); 
} 

spl_autoload_register('my_autoloader'); 

Какой бы создать подключение к моей базе данных. Это включено в самую верхнюю часть моих страниц, а также загружать все мои классы. Теперь, если я хочу, чтобы создать новое соединение с использованием PDO, я хотел бы сделать следующее:

$conn = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD); 

Однако, я не могу эту строку кода в отдельном файле и вызвать PDO внутри класса, как следующее:

require_once 'db.php'; 
class info 
{ 

    protected $ID; 

    public function __construct($id) 
    { 
     $this->ID = $id; // 
    } 

    public function getName() 
    { 
     $query = "SELECT * FROM job"; 
     $q = $conn->query($query); 
     $data = $q->fetch(PDO::FETCH_ASSOC); 
      //do something with $data 

    } 
} 

Означает ли это, что мне нужно установить соединение в конструкторе посредством агрегации, как показано ниже?

require_once 'db.php'; 
class info 
{ 
    protected $ID; 
    protected $pdo; 

    public function __construct($id) 
    { 
     $this->ID = $id; // 
     $this->pdo = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD); 
    } 

    public function getName() 
    { 
     $query = "SELECT * FROM job"; 
     $q = $this->pdo->query($query); 
     $data = $q->fetch(PDO::FETCH_ASSOC); 
     // do something 
    } 
} 

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

+4

+1 за то, что вы решили переписать свои функции mysql_ *! –

+0

Возможный дубликат [Как правильно настроить соединение PDO] (http://stackoverflow.com/questions/11369360/how-to-properly-setting-up-pdo-connection) –

ответ

3

Вместо создания соединения с базой данных внутри конструктора, то лучше сделать его зависимость:

public function __construct(PDO $db, $id) 
{ 
    $this->pdo = $db; 
    $this->ID = $id; 
} 

Чтобы использовать его, вы могли бы сделать:

// $db = new PDO('mysql:host='.SERVER.';dbname='.DB.';charset=utf8',USER, PASSWORD); 
$info = new info($db, '123'); 
echo $info->getName(); 

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

+0

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

+0

@Dimitri Не уверен, что это применимо к вам, но вы можете создать суперкласс, который принимает как db, так и id (protected) в конструкторе ... тогда все ваши классы расширяются от этого. –

+0

@ Dimitri Кроме того, я не вижу, как создание db-соединения внутри каждого конструктора работает меньше, чем передача db-соединения с каждым конструктором. –

0

При создании соединения с базой данных вы должны сделать это в одноэлементном классе. Вы только хотите открыть одно соединение с базой данных. Например:

public class database 
{ 
    static $instance; 

    public static function getInstance() 
    { 
      if($self::$instance == null) 
      { 
       $self::$instance = new PDO(); // string value here. 
      } 
      return $instance; 
    } 
} 

Затем вы можете вызвать метод database::getInstance() из любого места в классе, и вам не нужно держать переписывание коды подключения.

PS: Я знаю, что этот синглтон не является потокобезопасным. Я просто пытался выделить концепцию OP.

+0

Это интересно. Сможете ли вы создать рабочий пример с реализацией и как его использовать? Я просто пытаюсь увидеть полную картину здесь ... Метод агрегирования собирался создать тысячи подключений, если бы я запускал экземпляр в цикле ... – Dimitri

+0

@ Крис: да, но не забывайте, что PDO - это класс, поэтому вместо того, чтобы иметь класс-оболочку, вы можете расширить его. Выполнение этого способа означает, что все методы PDO будут наследоваться «базой данных», вместо того, чтобы добавлять методы-оболочки в дочерний элемент. – halfer

+1

@dimitri Я думаю, что, наверное, лучше, если вы попытаетесь реализовать его самостоятельно, а также посмотрите на комментарий халфера, который очень важен! – christopher

0

вот моя первая попытка:

class database extends PDO { 

     protected static $instance; 

     protected function __construct(){} 

     public static function getInstance() 
     { 
      if(empty(self::$instance)) 
      { 
       $db_info = array(
           "db_host" => SERVER, 
           "db_port" => PORT, 
           "db_user" => USER, 
           "db_pass" => PASSWORD, 
           "db_name" => DB); 

       self::$instance = new Database("mysql:host=".$db_info['db_host'].';port='.$db_info['db_port'].';dbname='.$db_info['db_name'], $db_info['db_user'], $db_info['db_pass']); 

      } 
      return self::$instance; 
     } 
} 

class info 
{ 
    protected $ID; 
    protected $pdo; 

    public function __construct($id) 
    { 
     $this->ID = $id; // 
     $this->pdo = database::getInstance(); 
    } 

    public function getName() 
    { 
     $query = "SELECT * FROM job"; 
     $q = $this->pdo->query($query); 
     $data = $q->fetch(PDO::FETCH_ASSOC); 
     // do something 
    } 
} 

Я не совсем уверен, что это правильно, поскольку у меня нет никаких способов проверить это на данный момент. Это будет считаться правильным?

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