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

   Каждый раз Вы собираете запрос в отдельную переменную, экранируя все входные данные. непременно забывая это сделать с каким-нибудь числом, ведь кому придет в голову подать вместо ?id=123 что-нибудь вроде ?id=delete from ...

   Выборка из БД это тоже великое свершение. Вы делаете запрос, получаете какой-то непонятный контекст. Это не данные, а всего лишь ссылка на них. неясно, как и где они лежат. После прочтения мануала нам предлагают запустить цикл, и каждую его итерацию получать новую строку из БД.

   В цикле мы также можем выбирать данные различными способами: можем, как объект, тогда к каждому полю обращаемся так $row->id, есть функции которые возвращают ассоциативный массив, тогда обращаемся так $row['id'], а есть те которые просто возвращают массив данных.

   Вы написали программу. Мои поздравления! Она работает. данные крутятся. Вам даже сообщили, что в id можно подавать любые данные, и вы исправили этот баг, в двух местах, конечно забыв про третье. 

   Пришло время протестировать скрипт на хостинге клиента. Страшно сказать, но он ярый противник linux и apache, купил за большие деньги windows хостинг, с IIS и MsSQL. Ну что же, переписываем пару строк, понимаем, что отличий в работе прилично, и пишем все заново...

   Веселая перспектива не правда ли? 

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

<?php 
class a{
public $b = 1;
public function getB(){
	return $this->b;
}
}
$v = new a();
echo $v->b; // что может быть проще
echo $this->getB();// очень длинно, к тому же нам пришлось 
//прописывать у класса дополнительный метод,
// а это еще 3 дополнительные строчки

На фоне такого, простого класса, использование геттера getB кажется избыточным. Предположим, что ситуация изменилась, данные нужно брать не из статики, а из файла.

<?php 
class a{
public $b = 1;
public function getB(){
	return file_get_contents('b.txt');
}
}
$v = new a();
echo $v->b; // везде, где применялась эта конструкция придется переписывать код
echo $this->getB();// в программе ничего не изменилось

Вернемся к работе с БД. Надеюсь Вам стало очевидно, что нужно использовать класс, который, как можно меньше  зависит не только от языка php и его встроенных функций, но  и от самой реализации SQL

Представляю Вам, собранный мной класс для работы с mysqlСсылка на github

<?php
/**
 * @class 		db
 * @author 		leroy <skoder@ya.ru>
 * @site 		http://xdan.ru
 * @version 	1.7
 */
class db{
	public $sql = '';
	public $inq = '';
	public $sqlcount = 0;
	public $pfx = '';
	private $connid = 0;
	
	/**
	 * При инициализации пдключаетсяк MySQL и подключается к нужной БД
	 * 
	 * @param $server название хоста
	 * @param $user логин
	 * @param $password пароль
	 * @param $dbname название бд
	 * @param $pfx префикс таблиц, по умолчанию pfx_, т.е. в любом запросе к названию таблиц 
	 * будет добавлятся pfx_
	 * @param $charset кодировка
	 */
	function __construct( $server, $user, $password,$dbname,$pfx='pfx_',$charset="utf8" ){
		if( $this->connid = @mysql_connect($server, $user, $password) ){
			$this->pfx = $pfx;
			if( mysql_select_db($dbname, $this->connid) ){
				$this->query("SET NAMES '".$charset."'") && $this->query("SET CHARSET '".$charset."'") && $this->query("SET CHARACTER SET '".$charset."'") && $this->query("SET SESSION collation_connection = '{$charset}_general_ci'");
			}
		}else{
			$this->error();
		}
	}
	
	/**
	 * Выполняет SQL запрос, заменяя #_ на заданный в настройках префикс 
	 */
	function query($sql){
		$this->sql = str_replace('#_',$this->pfx,$sql);
		$this->sqlcount++;
		($this->inq = mysql_query($this->sql,$this->connid))||$this->error();
		return $this->inq;
	}
	
	/**
	 * Возвращает последний выполненный запрос
	 */
	function last(){
		return $this->sql;
	}
	
	/**
	 * Возвращает одну запись из БД соответствующую запросу
	 *
	 * @param $sql SQL запрос
	 * @param $field если не задано то возвращается вся запись, иначе возвращается значение поля $field
	 * @example $db->getRow('select * from #_book where id=12'); // вернет array('id'=>12,'name'=>'Tolkien' ...)
	 * @example $db->getRow('select name from #_book where id=12',name); // вернет 'Tolkien'
	 */
	function getRow( $sql,$field='' ){
		$item = mysql_fetch_array($this->query($sql));
		return ($field=='')?$item:$item[$field]; 
	}
	
	/**
	 * Перебирает все записи из запроса и передает их в callback функцию
	 *
	 * @param $sql SQL запрос, с префиксом #_ 
	 * @param $callback функция, вызываемая к каждой записи запроса, 
	 * в параметрах 1) массив, содержащий данные полученной записи 2)указатель на db
	 * @return Возвращает db
	 */
	public function each( $sql,$callback ){
		$this->query($sql);
		if( is_callable($callback) )
			while($item = mysql_fetch_array($this->inq))
				call_user_func($callback,$item,$this);
		return $this;
	}
	
	/**
	 * Изымает лишь запись по ее идентификатору, по умолчанию id
	 *
	 * @param $sTable название таблицы без префикса
	 * @param $id значение идентификатора
	 * @param $fieldname поле по которому производится сравнение, по умолчанию id
	 * @param $field значение поля, которое необходимо вернуть. Если не указано то возвращается вся запись
	 * @return ассоциативный массив либо конкретное значение пи заданном $field
	 * @example $db->getRowById('book',12); // вернет запись о книге с id=12
	 * @example $db->getRowById('book','Tolkien','name'); // вернет запись о книге с названием которое содержит Tolkien
	 * @example $db->getRowById('book',12,'id','name'); // вернет название книги с id=12
	 */
	public function getRowById( $sTable, $id,$fieldname='id',$field='' ) {
		return $this->getRow("SELECT * FROM `#_".$sTable."` WHERE `$fieldname` ='".$this->escape($id)."'",$field);
	}
	
	/**
	 * Проверяет существует ли запись в таблице с таким идентификатором, если существует то возвращает идентификатор
	 * иначе возвращает false
	 *
	 * @param $sTable название таблицы без префикса
	 * @param $id значение идентификатора
	 * @param $fieldname поле по которому производится сравнение, по умолчанию id
	 * @param $allf дополнительные параметры запроса, обычное sql сравнение
	 * @param $field поле которое необходимо вернуть в случае удачи, по умолчанию равно $fieldname
	 * @return При удаче возвращает значение поля $field, иначе false
	 * @example if( $db->exists('book',12) ) echo 'Книга существует';
	 * @example if( $db->exists('book','Tolkien','name')!==false ) echo 'Книга содерщащая Tolkien существует';
	 * @example if( $db->exists('book','Tolkien','name','active="yes" and public="12.09.2008"') ) 
	 *	echo 'Книга содерщащая Tolkien опубликованная 12.09.2008 существует';
	 * @example if( ($name=$db->exists('book','%Tolkien%','name','','izdatel'))!==false ) 
	 *	echo 'Книга содерщащая Tolkien существует ее издал '.$name;
	 */
	public function exists($sTable,$id,$fieldname='id',$allf='',$field = ''){
		if( !$field )
			$field = $fieldname;
		$item = $this->getRow('select '.$field.' from '.$this->pfx.$sTable.' where `'.$fieldname.'`=\''.$this->escape($id).'\' '.$allf);
		return isset($item[$field])?$item[$field]:false;
	}
	
	/**
	 * @deprecated 1.7 Используйте getRows
	 */
	function loadResults( $sql,$field = '' ){
		return $this->getRows($sql,$field);
	}
	/**
	 * Выдает массив всех записей из запроса
	 *
	 * @param $sql SQL запрос, с префиксом #_ 
	 * @param $field если указано это поле, то результирующий массив будет состоять только из значений этого поля
	 * @return Array
	 */
	function getRows( $sql,$field = '' ){
		$inq = $this->query($sql);$items = array();
		while($item = @mysql_fetch_array($inq)) $items[] = ($field=='')?$item:$item[$field]; 
		return $items;
	}
	
	/**
	 * Экранирует значение
	 */
	function escape($sql){
        return mysql_real_escape_string($sql,$this->connid);
    }
		
	/**
	 * Вставка данных в таблицу
	 *
	 * @param $sTable название таблицы без префикса
	 * @param $values либо строка вида id=12,name="Tolkien", 
	 * либо ассоциативный массив вида array('id'=>12,'name'=>'Tolkien')
	 * в случае ассоциативного массива экранировать данные не требуется
	 * @example $db->insert('book','id=12,name="'.$db->escape('Tolkien').'"');
	 * @example $db->insert('book',array('id'=>12,'name'='Tolkien'));
	 */
	function insert( $sTable,$values ){
		$ret = $this->_arrayKeysToSet($values);
		return $this->query('insert into #_'.$sTable.' set '.$ret);
	  return false;
	}
	
	/**
	 * Возвращает значение перичного ключа последней вставленной записи
	 */
	function insertid(){
		return mysql_insert_id($this->connid);
	}
	
	/**
	 * Обновление данных в таблице
	 *
	 * @param $sTable название таблицы без префикса
	 * @param $values либо строка вида id=12,name="Tolkien", 
	 * либо ассоциативный массив вида array('id'=>12,'name'=>'Tolkien')
	 * в случае ассоциативного массива экранировать данные не требуется
	 * @param $sWhere условия соответсвия
	 * @example $db->update('book','id=12,name="'.$db->escape('Tolkien').'"','id=5');
	 * @example $db->update('book',array('id'=>12,'name'='Tolkien'),'where name like %Tolkien%');
	 */
	public function update( $sTable, $values, $sWhere=1 ){
		$ret = $this->_arrayKeysToSet($values);
		return $this->query('update '.$this->pfx.$sTable.' set '.$ret.' where '.$sWhere);
	}
	/**
	 * Удаление данных соответствующих словию
	 */
	public function delete( $sTable, $sWhere ){
		return $this->query('delete from '.$this->pfx.$sTable.' where '.$sWhere);
	}
	
	
	private function _arrayKeysToSet($values){
		 $ret='';
		  if( is_array($values) ){
			foreach($values as $key=>$value){
			  if(!empty($ret))$ret.=',';
			  $ret.="`$key`='".$this->escape($value)."'";
			}
		  }else $ret=$values;
		  return $ret;
	}
	private function error(){
		$langcharset = 'utf-8';
		echo "<HTML>\n";
		echo "<HEAD>\n";
		echo "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=".$langcharset."\">\n";
		echo "<TITLE>MySQL Debugging</TITLE>\n";
		echo "</HEAD>\n";
		echo "<div style=\"border:1px dotted #000000; font-size:11px; font-family:tahoma,verdana,arial; background-color:#f3f3f3; color:#A73C3C; margin:5px; padding:5px;\">";
		echo "<b><font style=\"color:#666666;\">MySQL Debugging</font></b><br /><br />";
		echo "<li><b>SQL.q :</b> <font style=\"color:#666666;\">".$this->sql."</font></li>";
		echo "<li><b>MySQL.e :</b> <font style=\"color:#666666;\">".mysql_error()."</font></li>";
		echo "<li><b>MySQL.e.№ :</b> <font style=\"color:#666666;\">".mysql_errno()."</font></li>";
		echo "<li><b>PHP.v :</b> <font style=\"color:#666666;\">".phpversion()."\n</font></li>";
		echo "<li><b>Data :</b> <font style=\"color:#666666;\">".date("d.m.Y H:i")."\n</font></li>";
		echo "<li><b>Script :</b> <font style=\"color:#666666;\">".getenv("REQUEST_URI")."</font></li>";
		echo "<li><b>Refer :</b> <font style=\"color:#666666;\">".getenv("HTTP_REFERER")."</li></div>";
		echo "</BODY>\n";
		echo "</HTML>";
		exit();
	}
}

Как использовать

Подключение к БД

include "class.db.php";
$db = new db('localhost','root','','test_bd','');

Простой SQL запрос

$db->query('update #_book set hits=hits+1 where id=12');

Тоже, но менее зависимо от SQL реализации

$db->update('book','hits=hits+1','id=12');

Выборка всех записей из таблицы

$db->getRows('select id from #_book');// вернет массив array(array('id'=>12),array('id'=>13)...)
$db->getRows('select id from #_book','id');// вернет массив array(12,13,...)

 Выборка одной записи

$db->getRow('select id from #_book where id=12');// вернет array('id'=>12)

Вставка  записи

$db->insert('book',array('name'=>'пушкин'));
$db->insert('book',array('name'=>'лермантов'));
$db->insert('book','izdatel="'.$db->escape('гоголь').'"');

Просмотр последнего SQL запроса 

$db->insert('book',array('name'=>'лермонтов'));
echo $db->last();// 'insert into pfx_book set name="лермонтов"'

Идентификатор последней вставленной записи

$db->insert('book',array('name'=>'лермонтов'));
echo $db->insertid();// 145

Сообщение об ошибке

$db->query('select * from #_ebook');
MySQL Debugging

  • SQL.q : select * from pfx_ebook
  • MySQL.e : Table 'codedb.pfx_ebook' doesn't exist
  • MySQL.e.№ : 1146
  • PHP.v : 5.3.13
  • Data : 25.03.2013 13:47
  • Script : /index.php
  • Refer : http://k8/

Ну и еще одна функция на грани фантастики, вызов для каждой записи из выборки callback функции:

$db->each('select id from #_book',function($item,$db){
	$db->update('book','hits=hits+id','id='.$item['id']);
});

Как использовать решайте сами, метод на мой взгляд, очень полезный.

Вот и все, надеюсь скрипт сделает Вашу жизнь чуть проще.

Рассказать друзьям

Добавить комментарий


Защитный код
Обновить

Комментарии   

0
Дима
# Дима 18.02.2015 00:21
класс наверное не плохой...только бы разобраться как с ним пользоваться не могу...
0
Leroy
# Leroy 18.02.2015 09:16
А что конкретно не понятно?
0
Дима
# Дима 23.04.2015 22:02
конкретные примеру нужны... не доганяю :sigh: новичок
0
Дима
# Дима 23.04.2015 22:18
на примере какой нибудь таблицы