Классов-оберток для доступа к MySQL написано немеряно. Я хочу заострить внимание только на паре аспектов - автоматическом экранировании строк в запросе и методе Myclass::query с произвольным количеством аргументов. Тут же пример как правильно вызывать метод в качестве callback-функции.
Посмотрим на такой пример из реального движка:
$result = $db->query('SELECT u.*
FROM '.$db->prefix.'users AS u
LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id
WHERE u.id>1
ORDER BY '.$db->escape($order_by).' '.$db->escape($direction));
Не правда ли за*бывает писать эти $db->prefix и $db->escape !!!
Мой пример реально не работает с базой, это заглушка для тестирования указанных фич.
В тексте запроса упоминаются шаблоны подстановки:
"$p_" — префикс таблиц, задается в конструкторе
"$#" — аргумент запроса, по номерам с 1 и до бесконечности. автоматически экранируются апострофы прочая гадость. Вам не придется каждый раз делать это перед вызовом query.
Файл test.php:
<?php
class DBLayer
{
private $prefix;
private $subst;
public function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix)
{
$this->prefix = $db_prefix;
}
// метод, который мы будем использовать как callback
private function subst_callback($matches)
{
if ($matches[1] == '$p_')
return $this->prefix;
else
return $this->subst[intval(substr($matches[1], 1))];
}
// метод с произвольным числом аргументов
// первый считаем текстом запроса, все остальные - параметры для подстановки
// вида $1, $2 и т.д.
public function query()
{
$sql = func_get_arg(0);
$this->subst = array();
if (func_num_args() > 1)
{
for ($i=1; $i<func_num_args(); $i++)
$this->subst[$i] = mysql_escape_string(func_get_arg($i));
}
$sql = preg_replace_callback('#(\$p_|\$\d+)#', array(&$this, 'subst_callback'), $sql);
echo $sql."<br />\n";
}
}
/* —————— */
$db = new DBLayer('localhost', 'superuser', '123456', 'mydb', 'my_');
$db->query('SELECT * FROM $p_table1');
$db->query('SELECT * FROM $p_table2 WHERE id=$1', 205);
$db->query('SELECT \'$2\' AS myname, x.parent_id FROM $p_table3 AS x WHERE x.id=$1 AND x.kind=\'$2\'',
777, 'd\'Artagnan');
Должен выдавать такой результат:
SELECT * FROM my_table1
SELECT * FROM my_table2 WHERE id=205
SELECT 'd\'Artagnan' AS myname, x.parent_id FROM my_table3 AS x WHERE x.id=777 AND x.kind='d\'Artagnan'