Nemoj se mučiti sa izmišljanjem tople vode, koristi
PDO. PDO inače nije full DAL, već je njegova apstrakcija na data-access nivou. Popularni ORM-ovi, kao što je Doctrine, se u svom core-u oslanjaju upravo na PDO. Zend_Db komponenta Zend Framework-a na raspolaganje stavlja adaptere takodje bazirane na istoj toj PHP ekstenziji (Zend_Db_Adapter_Pdo_* klase).
A ako baš nameravaš da sam pišeš nešto, a da to stvarno valja i da bude upotrebljivo, onda to ti preporučujem da najpre proučiš malo naprednije stvari koje se tiču dizajna klasa. Najbolje ti je da preuzmeš neku od gore pomenutih biblioteka i vidiš kako su oni realizovali sve te stvari. Pokazalo se da je najbolji pristup za pravljenje database apstrakcije ta neka implementacija zasnovana na
Adapter design pattern-u. Dakle definišeš neki ugovor, u vidu interfejsa, kojeg svaki taj adapter mora da ispunjava da bi sebe nazivao db adapterom, npr. ovako nešto za početak:
Code:
interface DatabaseAdapterInterface
{
public function connect();
public function disconnect();
public function query($sql);
public function fetch();
public function insert($table, array $data);
public function update($table, array $data, $where);
public function delete($table, $where);
public function lastInsertId();
public function quote($value);
}
I posle na osnovu njega gradiš logiku za svaki RDBMS. Evo kako bi npr. izgledale implementacije nekih od metoda tog interfejsa u slučaju MySQL adaptera:
Code:
class MysqlAdapter implements DatabaseAdapterInterface
{
protected $_config = array();
protected $_connection;
protected $_lastResult;
public function __construct(array $config)
{
$this->_config = $config;
}
public function connect()
{
if ($this->_connection === null) {
list($host, $username, $password, $database) = $this->_config;
if (!$this->_connection = @mysqli_connect($host, $username, $password, $database)) {
throw new Exception('An error occurred: ' . mysqli_connect_error());
}
unset($host, $username, $password, $database);
}
return $this->_connection;
}
public function query($sql)
{
$this->connect();
if (!$this->_lastResult = mysqli_query($this->_connection, $sql)) {
throw new Exception('An error occurred: ' . $sql . mysqli_error($this->_connection));
}
return $->_lastResult;
}
public function fetch($mode = MYSQLI_ASSOC)
{
if ($this->_lastResult === null) {
if (($row = mysqli_fetch_array($this->_lastResult, $mode)) === false) {
return $row;
}
}
return null;
}
public function insert($table, array $data)
{
$cols = implode(',', array_keys($data));
$values = implode(',', array_map(array($this, 'quote'), array_values($data)));
$query = 'INSERT INTO ' . $table . ' (' . $cols . ') ' . ' VALUES (' . $values . ')';
$this->query($query);
return $this->lastInsertId();
}
//Update, delete...
public function quote($value)
{
if (!is_numeric($value)) {
$this->connect();
$value = "'" . mysqli_real_escape_string($this->_connection, $value) . "'";
}
return $value;
}
public function lastInsertId()
{
return ($this->_connection !== null) ? mysqli_insert_id($this->_connection) : null;
}
public function disconnect()
{
if ($this->_connection !== null) {
mysqli_close($this->_connection);
$this->_connection = null;
}
}
public function __destruct()
{
$this->disconnect();
}
}
Ovo je naravno daleko od upotrebljivog i predstavlja samo neki osnovni mockup konkretne implementacije.
I opet kažem, nemoj izmišljati toplu vodu...