Pull to refresh

Очередной модуль для работы с MySQL

Reading time 4 min
Views 648
Не хватило кармы для помещения в специализированный блог. Но очень интересно обсудить.
Утомили рутинные операции при работе с БД. Решил хоть как-то исправить ситуацию. Потратил порядка получаса на просмотр существующих классов, не нашол ничего подходящего для себя. И решил, что проще будет, написать свой.

Собственно, что хотелось получить:
1. Сберечь свою память.
По работе приходится поддерживать и писать сайты на 4-5 серверных площадках, в разных странах. Постоянно меняются пароли и(реже но все же) сетевые адреса. Поэтому хотелось как-то централизовать настройки подключение и избавить себя от необходимости запоминать десятки адресов и паролей, а просто раскидать один файл по всем серверам и по мере надобности просто использовать нужный сервер БД.

2. Сберечь свое время.
Я ленивый. Меня быстро утомляют куски кода которые приходиться таскать с собой из скрипта в скрипт. Хотелось отдавать запрос и получать массив.

3. Хотелось свободы.
Многие модули которые попались мне на глаза за недолгое время поиска, пытались сами организовывать запросы.
Конечно кому-то это могло показаться удобнее, чем писать запросы самому, но зачастую приходится использовать сложные запросы и тратить время на анализ того как же надо это все написать, чтобы «умный» модуль превратил это все в корректный и оптимальный запрос.

Собственно вот что получилось.
<?php
class db {
private static $flag_one; // флаг сингельтона
//пораметры подключения по умолчанию
private $host = 'localhost';
private $user = 'root';
private $password;
private $database = 'mydb';

private $connect; //хранитель коннекта с базой
private $result; //хранитель коннекта результата запроса
private $server; //имя сервера
public $query_log_mask = 'query%.log'; //маска файла логов
public $debug=0; // включить/выключить логирование всех запросов

Имя сервера сделано на всякий случай. всякий случай случился когда потребовалось чтобы скрипт работал по разному в зависимости от того к какому северу он подключен.
И маска логов, и флаг дебаг доступны для изменения в ходе работы скрипта, что временами бывает весьма полезно.

Думаю не нуждается в комментариях.
public static function one($server = 'local'){
if (!isset(self::$flag_one)) {
$c = __CLASS__;
self::$flag_one = new $c($server);
}
return self::$flag_one;
}


В констракте я решил определить все сервера и специфические параметры подключения к ним.
Также устанавливается соединение с базой и выставляется кодировка.
protected function __construct($server) {
$this->server=$server;
switch ($server) {
case 'server1':
$this->password = 'abcde';
break;
case 'server2':
$this->host='192.168.0.100';
$this->user='someuser';
$this->database='somedb';
$this->password = 'edcba';
break;
default:
$this->password = '';
break;
}
$this->connect = mysql_connect($this->host, $this->user, $this->password) or die(mysql_error());
mysql_select_db($this->database, $this->connect);
$this->query('SET CHARSET cp1251;');
}


Запрещаем дублирование
public function __clone(){
trigger_error('Clone is not allowed.', E_USER_ERROR);
}

закрываем соединение с базой перед удалением класса из памяти.
public function close() {
mysql_close($this->connect);
}
public function __destruct(){
$this->close();
}


Функции для получения имени сервера и базы данных.
public function show_server() {
return $this->server;
}
public function show_db() {
return $this->database;
}


Собственно сердце всего модуля))
Функция делающая запрос к БД, и при необходимости его логирующая.
public function query($query) {
if(this->debug>0) $this->mysql_query_log($query,'debug');
$this->result = mysql_query($query, $this->connect) or $this->mysql_query_log($query);
}


Функция обработки запроса, принимает запрос(или использует результат последнего выполненного) и отдает массив
public function fetch_rows($query = '', $assoc = MYSQL_ASSOC) {
if (!empty($query)) $this->query($query);
$return = array();
mysql_data_seek($this->result, 0);
while($line = mysql_fetch_array($this->result, $assoc)){
$return[] = $line;
}
return $return;
}


Функция для получения числа строк в запросе:
public function num_rows($query = '') {
if (!empty($query)) $this->query($query);
return mysql_num_rows($this->result);
}


Самая сомнительная часть. Функция делает INSERT и возвращает id вставленной записи.
Сомнения вызывает вопрос тот ли Id она возвращает
public function insert($query = '') {
if (!empty($query)){
$this->query($query);
return mysql_insert_id();
}
return -1;
}


Заменяем запрещенные символы
public function add_slashes($value) {
return mysql_real_escape_string($value, $this->connect);
}


Функция логирования запросов, ошибочных(или всех)
private function mysql_query_log($query = '',$type='error') {
$out='';
$error=($type=='error');
if (!empty($query)) {
$out.="#---------------------------------------\r\n";
$out.=$query."\r\n";
if($error){
$out.=mysql_errno($this->connect).': '.mysql_error($this->connect)."\r\n";
$out.=var_export(debug_backtrace(), true)."\r\n";
}
$out.="#---------------------------------------\r\n";
}
$file = fopen(sprintf($this->query_log_mask,$type), 'a+');
fwrite($file,$out);
fclose($file);
if($error) die('Wrong database query.');
}
}
?>


Cкачать модуль можно тут

Если кому то интересно могу привести пару примеров использования.
Очень хотелось бы услышать замечания и предложения по усовершенствованию.
Прошу не судить строго, ибо это мой первый пост на Хабре.
Tags:
Hubs:
-15
Comments 16
Comments Comments 16

Articles