Класс для PHP+MySQLУстаревший (не объектный) стиль работы с таблицами MySQL из PHP не безопасен (есть опасность внедрения в запросы хакерских данных), не удобен (чего стоит одна только функция mysql_real_escape_string) и не переносим (а если я хочу перевести свои базы, например, на PostgreSQL)? | | Автор статьи: romix Последняя редакция №1 от 17.11.06 URL: http://kb.mista.ru/article.php?id=416 | |
Ключевые слова: PHP, MySQL, PostgreSQL, класс, объектный, внедрение SQL
Ниже приведен класс для PHP+MySQL, который позволяет:
а) Удобно использовать SQL-запросы в объектном стиле
б) Избежать внедрения SQL (не нужны mysql_real_escape_string, get_magic_quotes_gpc() и т.п.).
в) Можно без затруднений переходить на другую БД (например, PostgreSQL) без переделки основного кода.
г) Не нужно отслеживать ошибки в каждой второй строке кода (класс генерит исключение при ошибках).
Пример использования класса:
//загружаем файл с нашим классом (см. ниже)
require("t_sql.php");
//создаем объект
$q = new T_SQL();
//Подготовка запроса (реальные данные пока заменены на ?)
$q->prepare("INSERT INTO articles (title,description,updated_datetime,created_datetime, text) VALUES (?, ?, NOW(), NOW(), ?)");
//Прикрепляем данные (они будут вставлены на место символов ?)
$q->bind($_POST['f_title']);
$q->bind($_POST['f_description']);
$q->bind($_POST['f_text']);
//Выполняем SQL-запрос
$q->query($q->getsql());
Содержимое файла t_sql.php
<?php
class T_SQL {
var $query;
var $a;
var $result;
///////////////////////////////////////////////////////////////////////
//Конструктор класса
function T_SQL()
{
$this->a = array();
$hostname = "localhost";
$username = "root";
$password = "";
$dbname = "vk1c";
mysql_pconnect($hostname,$username,$password);
$error = mysql_error();
if ($error) throw new Exception($error);
mysql_select_db($dbname);
$error = mysql_error();
if ($error) throw new Exception($error);
mysql_query('set names "cp1251"');
$error = mysql_error();
if ($error) throw new Exception($error);
}
///////////////////////////////////////////////////////////////////////
//Задает шаблон для SQL-запроса (данные следует заменить на ?
function prepare($s)
{
$this->query=$s;
}
///////////////////////////////////////////////////////////////////////
//Заменяет следующий знак ? в шаблоне запроса на прослешенную строку данных
function bind($s)
{
$this->a[]=$s;
}
///////////////////////////////////////////////////////////////////////
// Функция экранирования переменных
function quote_smart($value)
{
// если magic_quotes_gpc включена - используем stripslashes
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
// Если переменная - число, то экранировать её не нужно
// если нет - то окружем её кавычками, и экранируем
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}
///////////////////////////////////////////////////////////////////////
//Возвращает SQL-запрос с учетом bind
function getsql()
{
$aq = explode('?', $this->query);
if(count($aq) != (count($this->a)+1)){
throw new Exception("Не совпадает шаблон prepare() и количество вызовов bind()");
}
$q = '';
for($i=0; $i<count($aq)-1; $i++){
$q .= $aq[$i] . $this->quote_smart($this->a[$i]);
}
$q .= $aq[$i];
return $q;
}
///////////////////////////////////////////////////////////////////////
//Выполняет SQL-запрос
function query($s)
{
$r=mysql_query($s);
$err=mysql_error();
if ($err){
throw new Exception($err);
}
$this->result=$r;
return $r;
}
///////////////////////////////////////////////////////////////////////
//Получает запись из выборки
function fetch()
{
$row = mysql_fetch_object($this->result);
return $row;
}
///////////////////////////////////////////////////////////////////////
//Освобождает результат запроса
function free()
{
mysql_free_result($this->result);
}
}//class
?> |