Не хватило кармы для помещения в специализированный блог. Но очень интересно обсудить.
Утомили рутинные операции при работе с БД. Решил хоть как-то исправить ситуацию. Потратил порядка получаса на просмотр существующих классов, не нашол ничего подходящего для себя. И решил, что проще будет, написать свой.
Собственно, что хотелось получить:
1. Сберечь свою память.
По работе приходится поддерживать и писать сайты на 4-5 серверных площадках, в разных странах. Постоянно меняются пароли и(реже но все же) сетевые адреса. Поэтому хотелось как-то централизовать настройки подключение и избавить себя от необходимости запоминать десятки адресов и паролей, а просто раскидать один файл по всем серверам и по мере надобности просто использовать нужный сервер БД.
2. Сберечь свое время.
Я ленивый. Меня быстро утомляют куски кода которые приходиться таскать с собой из скрипта в скрипт. Хотелось отдавать запрос и получать массив.
3. Хотелось свободы.
Многие модули которые попались мне на глаза за недолгое время поиска, пытались сами организовывать запросы.
Конечно кому-то это могло показаться удобнее, чем писать запросы самому, но зачастую приходится использовать сложные запросы и тратить время на анализ того как же надо это все написать, чтобы «умный» модуль превратил это все в корректный и оптимальный запрос.
Собственно вот что получилось.
Имя сервера сделано на всякий случай. всякий случай случился когда потребовалось чтобы скрипт работал по разному в зависимости от того к какому северу он подключен.
И маска логов, и флаг дебаг доступны для изменения в ходе работы скрипта, что временами бывает весьма полезно.
Думаю не нуждается в комментариях.
В констракте я решил определить все сервера и специфические параметры подключения к ним.
Также устанавливается соединение с базой и выставляется кодировка.
Запрещаем дублирование
закрываем соединение с базой перед удалением класса из памяти.
Функции для получения имени сервера и базы данных.
Собственно сердце всего модуля))
Функция делающая запрос к БД, и при необходимости его логирующая.
Функция обработки запроса, принимает запрос(или использует результат последнего выполненного) и отдает массив
Функция для получения числа строк в запросе:
Самая сомнительная часть. Функция делает INSERT и возвращает id вставленной записи.
Сомнения вызывает вопрос тот ли Id она возвращает
Заменяем запрещенные символы
Функция логирования запросов, ошибочных(или всех)
Cкачать модуль можно тут
Если кому то интересно могу привести пару примеров использования.
Очень хотелось бы услышать замечания и предложения по усовершенствованию.
Прошу не судить строго, ибо это мой первый пост на Хабре.
Утомили рутинные операции при работе с БД. Решил хоть как-то исправить ситуацию. Потратил порядка получаса на просмотр существующих классов, не нашол ничего подходящего для себя. И решил, что проще будет, написать свой.
Собственно, что хотелось получить:
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качать модуль можно тут
Очень хотелось бы услышать замечания и предложения по усовершенствованию.
Прошу не судить строго, ибо это мой первый пост на Хабре.