OO PHP - Как создать «общий» объект базы данных? - PullRequest
1 голос
/ 27 июля 2011

Продолжая свой путь к более сложному ОО, я пытаюсь найти лучший способ создания класса под названием database, который может с радостью использовать устаревшие команды mysql_,библиотеку mysqli_ и, возможно, еще дальше, другие разновидности базы данных.

Я бы хотел, чтобы мой вызывающий код выглядел примерно так, для простоты:

$db = new database("MYSQL", $host,$user,$password,$databaseName); 
$db->query("SELECT myField FROM myTable");

while ($ROW = $db->fetch_assoc($QRY)) {
  echo $ROW['myField'] . "<br/>";
}

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

Я ценю, что смог достичь именно того, что хочу, реализовав switch блоки в каждом методе database:

class database() {

  function __construct($type,$host,$user,$password,$databaseName) { 

    $this->dbType = $type; 

    switch ($type) {

      case "mysql":
        mysql_dao::connect($host,$user,$password,$databaseName);
        break;

      case "mysqli":
        mysqli_dao::connect($host,$user,$password,$databaseName);
        break;

      case "mssql":
        mssql_dao::connect($host,$user,$password,$databaseName);
        break;

      //other cases
    }

  }

  function query($SQL) {  
    switch ($this->dbType) { 
       case "mysql": mysql_dao::query($SQL); break;
       case "mysqli": mysqli_dao::query($SQL); break; 
       case "mssql": mssql_dao::query($SQL); break;
    }
  }

  function fetch_assoc($SQL) {  
    switch ($this->dbType) { 
       case "mysql": mysql_dao::fetch_assoc($SQL); break;
       case "mysqli": mysqli_dao::fetch_assoc($SQL); break; 
       case "mssql": mssql_dao::fetch_assoc($SQL); break;
    }
  }

  //other methods....

}

... Но это кажется невероятно грязным.Каждый раз, когда вызывается метод database, код проверяет его тип и вызывает метод из другого объекта.

Так что моим следующим решением было просто опустить database и простоиспользуйте вызывающий код, который выглядит следующим образом:

$db = new mysql_dao($host,$user,$password,$databaseName); 
$db->query("SELECT myField FROM myTable");

while ($ROW = $db->fetch_assoc($QRY)) {
  echo $ROW['myField'] . "<br/>";
}

... и поэтому мы просто вызываем объект доступа к базе данных для типа базы данных, которую мы используем, но мне это тоже не нравится, если яЯ хотел перенести весь проект с mysql на mysqli, мне нужно было бы найти все эти ссылки на объекты и изменить их.Хотя это довольно тривиально в современном редакторе PHP, он все еще не чувствует, что это должен быть лучший способ (сейчас я начинаю получать теоретическое, а не практическое!)

Итак, наконец, я 'Я надеялся, что я смогу создать класс database с помощью одного оператора switch:

class database {

    function __construct($type,$host,$user,$pass,$db) {    

        switch ($type) {

            default:
            case "MYSQL":
                return new mysql_dao($host,$user,$pass,$db);
                break;

            case "MYSQLI":
                return new mysqli_dao($host,$user,$pass,$db);
                break;

            case "MSSQL":
                return new mssql_dao($host,$user,$pass,$db);
                break;    
        }    

    }

}

... и затем просто реализовать интерфейс со всеми другими методами, находящимися в классах для отдельных типов баз данных.,К сожалению, это тоже не работает, потому что, хотя конструктор для database возвращает экземпляр другого объекта, я не могу вызвать database->query, потому что метод не существует в объекте базы данных.

КакНасколько я мог понять, расширение классов database с помощью mysql_dao / mysqli_dao и т. д. тоже было неправильным, так как вы должны вызывать расширенный класс, чтобы использовать его методы, и я хочу вызвать родительский класс, ноиспользовать методы дочернего класса.Таким образом, это говорит о том, что database должен расширить dao классы, но вы не можете иметь один дочерний класс с несколькими потенциальными родителями (не так ли?)

В заключение - я почти уверен, что что-то упустили что то, что я хочу сделать, должно быть возможным и довольно простым, и я просто не подумал о правильном пути - кто-нибудь может дать мне указатель?

Ответы [ 4 ]

4 голосов
/ 27 июля 2011

Несмотря на то, что вы изобретаете велосипед заново (взгляните на PDO), в общем, для таких случаев вы можете использовать что-то вроде фабричного шаблона .

В базовом псевдокоде:

$db = Database::create('mysql', $host, ...); // gets a MySQLDatabase object
$db = Database::create('mysqli', $host, ...); // gets a MySQLiDatabase object
3 голосов
/ 27 июля 2011

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

0 голосов
/ 27 июля 2011

Чтобы функциональность была функциональной, вам нужно будет передать и вернуть параметр в качестве ссылок, как в следующем примере:

 public function &Query($sql){
     $var = mysql_query($sql, $this->connection);
     return $var;
 }

 public function Fetch(&$cur){
     return mysql_fetch_array($cur);
 }

«&» представляет ссылку на переменную, а не просто копию для дополнительной документации: http://www.php.net/manual/en/language.references.pass.php

То, что вы пытаетесь сделать, работает хорошо. Я создал интерфейс для работы с базой данных MySQL, но я уверен, что вы найдете способ создать объект для другого типа БД.

0 голосов
/ 27 июля 2011

В такой ситуации я обычно:

  • Определим некоторые DAOInterface с помощью таких методов, как connect, query, fecthAll, ...
    • все классы, которые подключаются к базе данных, должны будут реализовать этот интерфейс
    • , что означает, что ваши mysql_dao, mysqli_dao, ... будут реализовывать этот интерфейс

Затем, при работе с этими классами, основное преимущество:

  • Вы будете позже создавать экземпляр переменной $db, либо mysql_dao, либо mysqli_dao,но всегда получайте объект, который реализует DAOInterface
  • Это означает, что вы будете уверены, что сможете вызывать все эти методы для вашего $db объекта


После этого, будет только одно место, где вам придется выбирать между mysql_dao и mysqli_dao: это когда вы создаете один из этих двух экземпляров, присваивая результат $db.

Тогда, как вы знаетенаверняка, что $db является объектом, который реализует DAOInterface, вы точно знаете, что всегда сможете вызвать tТе же методы на этом объекте.

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