В последнее время задался вопросом написания php класса для работы с базой данных mysql. Мои требования – удобство формирования запроса к базе данных и возможность сортировки и записи данных через массив, что упрощает работу с БД.

В результате появился вот такой класс:

class Db {

    private $where;
    private $select = '*';
    private $limit;
    private $order_by;
    private $query;
    private $set;

    private function query_string($table){
        $query = ($this->query) ? $this->query : "SELECT $this->select FROM $table WHERE $this->where $this->order_by $this->limit";
        return $query;
    }
    function query($text){
        $this->query = $text;
        return $this;
    }
    function where_text($text){
        $operator = 'AND';
        if (!$this->where){
            $this->where = $text;
        } else {
            $this->where .= $operator." ".$text;
        }
        return $this;
    }
    function order_by_text($text){
        if (!$this->order_by){
            $this->order_by = ' ORDER BY '.$text;
        } else {
            $this->order_by .= ', '.$text;
        }
    }
    function connect($host,$login_mysql,$password_mysql,$baza_name) {
        $db = @mysql_connect("$host", "$login_mysql", "$password_mysql");
        mysql_set_charset('utf8',$db);
        if (!$db) exit("<p>Sorry, not available MySQL server</p>");
        if (!@mysql_select_db($baza_name,$db)) exit("<p>Unfortunately, the database is not available</p>");
    }
    function select($column){
        $this->select = $column;
        return $this;
    }
    function limit($start,$count){
        $this->limit = ' LIMIT '.$start.','.$count;
        return $this;
    }
    function order_by($key){
        if (is_array($key)){
            foreach ($key as $column => $value){
                if (!$this->order_by){
                    $this->order_by = ' ORDER BY '.$column.' '.$value;
                } else {
                    $this->order_by .= ', '.$column.' '.$value;
                }
            }
        } else {
            if (!$this->order_by){
                $this->order_by = ' ORDER BY '.$key;
            } else {
                $this->order_by .= ', '.$key;
            }
        }
        return $this;
    }
    function where($key,$compare = '='){
        $operator = 'AND';
        if (is_array($key)){
            foreach ($key as $column=>$value){
                if (!$this->where){
                    $this->where = $column.$compare."'".$value."' ";
                } else {
                    $this->where .= $operator." ".$column.$compare."'".$value."' ";
                }
            }
        } else {
            $key = explode(',',$key);
            if (!$this->where){
                $this->where = $key[0].$compare."'".$key[1]."' ";
            } else {
                $this->where .= $operator." ".$key[0].$compare."'".$key[1]."' ";
            }
        }
        return $this;
    }
    function search($column,$search){
        $operator = 'AND';
        $search = strtr($search,array(" "=>" +"));
        $search = '+'.$search;
        $w = 'MATCH('.$column.") AGAINST('".$search."' IN BOOLEAN MODE)";
        if (!$this->where){
            $this->where = $w;
        } else {
            $this->where .= $operator." ".$w;
        }
        return $this;
    }
    function lines($table,$ext = true){
        $msql_query = mysql_query($this->query_string($table));
        $line = mysql_fetch_assoc($msql_query);
        if ($ext)$this->exit_function();
        return $line;
    }
    function multiline($table,$ext = true){
        $msql_query = mysql_query($this->query_string($table));
        $multiline = array();
        while($arr = mysql_fetch_assoc($msql_query)) $multiline[] = $arr;
        if ($ext)$this->exit_function();
        return $multiline;
    }
    function num_rows($table,$ext = true){
        $msql_query = mysql_query($this->query_string($table));
        $num_rows = mysql_num_rows($msql_query);
        if ($ext)$this->exit_function();
        return $num_rows;
    }
    function insert($table){
        $query = 'INSERT '.$table.$this->set;
        $q = mysql_query($query);
        $this->exit_function();
        return  $q ? mysql_insert_id() : 'ERROR INSERT MYSQL';
    }
    function update($table){
        $query = 'UPDATE '.$table.$this->set.' WHERE '.$this->where;
        $this->exit_function();
        return mysql_query($query);
    }
    function set($value){
        $operator = ',';
        if (is_array($value)){
            foreach ($value as $column=>$val){
                if (!$this->set){
                    $this->set = ' SET '.$column.'='."'".$val."' ";
                } else {
                    $this->set .= $operator." ".$column.'='."'".$val."' ";
                }
            }
        } else {
            $value = explode(',',$value);
            if (!$this->set){
                $this->set = ' SET '.$value[0].'='."'".$value[1]."' ";
            } else {
                $this->where .= $operator." ".$value[0].'='."'".$value[1]."' ";
            }
        }
        return $this;
    }
    private function exit_function(){
        $this->where = '';
        $this->select = '*';
        $this->limit = '';
        $this->order_by = '';
        $this->query = '';
        return $this;
    }
}


Вот такой класс, а теперь подробнее о функциях.

Для подключения к базе данных (БД) объявляем класс Db и с помощью функции connect подключаемся к БД. Значения для функции: connect(Хост, Имя пользователя, пароль, имя базы данных);

$db = new Db;
$db->connect('localhost','root','',test);

После подключения можно приступать к работе. Для сортировки с помощью массива объявляю массив, а для записи данных использую функцию where, в которую передаю массив:

$where = array();
$where['status'] = 1;
$where['category'] = 2;
$db->where($where);

Далее функцию where опишу подробнее. А сейчас объявим из каких полей делать выборку, для этого используем функцію select, по умолчанию ее значение — * и ее можно не объявлять.

$db->select('msg,zag');

По умолчанию where использует знак = для сравнения, но если нужно другое значение, например больше или меньше то можно вторым значением передать нужный нам знак сравнения. В функции можно использовать как строчный вариант сравнения, например 'price,1000', так и массив как в примере выше и всему массиву будет подставлен переданный знак.

$db->where('price,1000','>');

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

$order_by = array();
$order_by['price'] = 'DESC';
$order_by['data'] = 'ASC';
$db->order_by($order_by);

Эта функция сформирует такой запрос: ORDER BY price DESC, data ASC. В ORDER BY можно подставлять свои аргументы используя функцию order_by_text():

$db->order_by_text('id DESC');

Теперь функции вывода данных — их три: num_rows, multiline, lines:

$q['num'] = $db->num_rows('data',false);

Функция num_rows показывает количество записей, соответствующих запросу, false — означает, что объявленные данные для сортировки стирать не нужно. Без false все объявленные данные стираются и их нужно объявлять заново. ‘data’ – таблица в БД к которой делаем запрос.

$q['multiline'] = $db->multiline('data',false);

Функция multiline выводит массивы данных соответствующих запросу.

$q['lines'] = $db->lines('data');

Функция lines выводит один первый массив соответствующий запросу.

Функции формируют такой запрос:
SELECT msg,zag FROM data WHERE status='1' AND category='2' AND price>'1000' ORDER BY price DESC, data ASC, id DESC

Функция limit — устанавливает LIMIT в запрос, где 2 — стартовый номер для вывода (т.е. вывод начнется со 2-го элемента соответствующего запросу), 4 — количество элементов в массиве.

$q['multiline'] = $db->select('id')->where($where)->where_text('id IN (1,2,3,4)')->order_by($order_by)->limit(2,4)->multiline('data');

Select, where и order_by объявляем заново, т.к. предыдущая функция lines была без false — это означает, что все данные для сортировки были стерты. Формирует такой запрос:

SELECT id FROM data WHERE status='1' AND category='2' AND id IN (1,2,3,4) ORDER BY price DESC, data ASC LIMIT 2,4

Здесь была использована еще одна функция where_text – она нужна для того, чтобы самому написать запрос в WHERE

Функция search:

$q['search'] = $db->search('test,text','тест поиска')->multiline('data');

Формирует такой запрос: SELECT * FROM data WHERE MATCH(test,text) AGAINST('+тест +поиска' IN BOOLEAN MODE). Ищем в таблице data, в полях test и text совпадения со словами тест и поиска.

Можно и так:

$db->select('id')->where($where)->search('test,text','тест поиска')->order_by($order_by)->multiline('data');

$order_by и $where берутся из предыдущих объявленных переменных и получаем такой запрос:

SELECT id FROM data WHERE status='1' AND category='2' AND MATCH(test,text) AGAINST('+тест +поиска' IN BOOLEAN MODE) ORDER BY price DESC, data ASC

Для записи в базу данных: используем функцию set — передача параметров сохранения массивом и insert — запись в базу данных:

$set['test'] = 'test';
$set['text'] = 'text';
$id = $db->set($set)->insert('data'); 

Функция вернет id записи в переменную $id. Запрос будет выглядеть так: INSERT data SET test='test', text='text'

Для внесения изменений в строку используем функцию update:

$set = array();
$set['category'] = 2;
$set['test'] = 'test change';
$set['text'] = 'text change';
$save = $db->where('id,1')->set($set)->update('data');
$message = $save ? "UPDATE OK" : "ERROR UPDATE"; 

Если запись прошла успешно, $message вернет UPDATE OK иначе ERROR UPDATE. Запрос будет таким:

UPDATE data SET test='test', text='text', category='2', test='test change', text='text change' WHERE id='1'

И еще одна функция query — в ней можно написать свой запрос select полностью:

$q = $db->query("SELECT * FROM data WHERE status='1' AND category='2'")->multiline('data');

Также можно сделать параллельное соединение с другой базой данных:

$db2 = new Db();
$db2->connect('localhost','root','','test');
$q['db2'] = $db2->where('id,2')->lines('wp_posts');
print "<pre>";
print_r ($q);


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

Комментарии (27)