[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Класс для работы с базой SQLite
Страницы: 1, 2
te0203
В последнее время при создании сайта столкнулся с одной проблемой, обычно сайты созданные на php используют базы данных MySQL, это самая популярная база и простая в применении. Но на некоторых хостингах для предотвращения перегрузки серверов введены ограничения по количеству запросов в секунду. При создании современного сайта для построении страницы приходится выполнять не один запрос к базе а несколько, а если у вас не один посетитель, а одновременно десять , то количество запросов превышает ограничения и хостинг мирно блокирует ваш сайт на некоторое время.

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

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

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


//Путь к корню сайта
if(!defined('ROOT')){define ('ROOT', $_SERVER['DOCUMENT_ROOT']);}
//Путь к файлу куда будем писать ошибки
define ('LOG_FILE', ROOT.'/logo/error.txt');
//Путь к файлу базы данных
define ('DB_FILE', ROOT.'/db/database.db');

class SQLite{
private static $_instance = NULL;
private static $DBH;

//При создании объекта конектимся с базой данных.
private function __construct(){
try{
//Создаём или подключаемся к базе
$this->DBH = new PDO("sqlite:".DB_FILE);
//Уровень ошибок
$this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
//Запись ошибок в лог
self::Log($e->getMessage());
}
}


//Вызов объекта через эту функцию.
//Это стандартный паттерн для того что бы на странице был только один объект этого класса

public static function getInstance(){
if(self::$_instance == NULL){
self::$_instance = new SQLite();
}
return self::$_instance;
}

//Выборка из базы одной записи
public function SelectOne($data){
try{
$STMT = $this->DBH->query($data);
$result = $STMT->fetch(PDO::FETCH_LAZY);
return $result;
}catch(PDOException $e){
try{//При ошибке
self::Log('SELECTOne вторая попытка');
$STMT = $this->DBH->query($data);
if(!$STMT){
self::Log('Ошибка второй попытки SELECTOne');
}
$result = $STMT->fetch(PDO::FETCH_LAZY);
return $result;
}catch(PDOException $e){
self::Log($e->getMessage());
}
}
}


//Выборка из базы несколько записей
public function Select($data){
try{
$STMT = $this->DBH->query($data);
return $STMT;
}catch(PDOException $e){
try{
self::Log('SELECT вторая попытка');
$STMT = $this->DBH->query($data);
if(!$STMT){
self::Log('Ошибка второй попытки SELECT');
}
return $STMT;
}catch(PDOException $e){
self::Log($e->getMessage());
}
}
}


//Подсчёт количества строк по SELECT
public function SelectCount($data){
$data = explode('FROM', $data);
$data = explode('ORDER', $data[1]);
$data = 'SELECT COUNT(*) FROM '.$data[0];
$STMT = $this->DBH->query($data);
$result = $STMT->fetch(PDO::FETCH_LAZY);
$result = $result['COUNT(*)'];
return $result;
}

//Вставка в базу
public function Insert($data){
try{
$result = $this->DBH->exec($data);
return $result;//Количество затронутых строк.
}catch(PDOException $e){
try{
self::Log('INSERT вторая попытка');
unset($this->DBH);
//Создаём или подключаемся к базе
$this->DBH = new PDO("sqlite:".DB_FILE);
//Уровень ошибок
$this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$result = $this->DBH->exec($data);
if(!$result){
self::Log('Ошибка второй попытки INSERT');
}
return $result;//Количество затронутых строк.
}catch(PDOException $e){
self::Log($e->getMessage());
}
}
}


//Изменение в базе
public function Update($data){
try{
$result = $this->DBH->exec($data);
return $result;//Количество затронутых строк.
}catch(PDOException $e){
try{
self::Log('UPDATE вторая попытка');
unset($this->DBH);
$this->DBH = new PDO("sqlite:".DB_FILE);
$this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$result = $this->DBH->exec($data);
if(!$result){
self::Log('Ошибка второй попытки UPDATE');
}
return $result;//Количество затронутых строк.
}catch(PDOException $e){
self::Log($e->getMessage());
}
}
}


//Удалеие из базы
public function Delite($data){
try{
$result = $this->DBH->exec($data);
return $result;//Количество затронутых строк.
}catch(PDOException $e){
try{
self::Log('DELETE вторая попытка');
unset($this->DBH);
$this->DBH = new PDO("sqlite:".DB_FILE);
$this->DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$result = $this->DBH->exec($data);
if(!$result){
self::Log('Ошибка второй попытки DELETE');
}
return $result;//Количество затронутых строк.
}catch(PDOException $e){
self::Log($e->getMessage());
}
}
}


//Запись ошибок
public function Log($str){
$d = date("H:i:s");
$ip = explode('.', $_SERVER['REMOTE_ADDR']);
$ip = str_pad($ip[0], 3).'.'.str_pad($ip[1], 3).'.'.str_pad($ip[2], 3).'.'.str_pad($ip[3], 3);
$size = filesize (LOG_FILE);
if(!isset($_SERVER['HTTP_REFERER'])){
$_SERVER['HTTP_REFERER'] = '';
}
file_put_contents(LOG_FILE, "$d | ".$ip.$_SESSION['login'].urldecode($str).
" | ".urldecode($_SERVER['REQUEST_URI'])." | ".urldecode($_SERVER['HTTP_REFERER']).
" | ".$_SERVER['HTTP_USER_AGENT']."\r\n".file_get_contents(LOG_FILE));
if($size > 50000){
$file = fopen(LOG_FILE, 'r+');
ftruncate ($file, 50000);
fclose($file);
}
}


//Закрытие соединения при уничтожении объекта.
public function __destruct(){
$DBH = null;
}
}



Вы наверное заметили, что во всех методах при добавлении или выборке из базы при ошибке я пытаюсь повторно запросить запись, а в некоторых методах даже после ошибки разрываю соединение и заново подключаюсь к базе. Это вызвано не очень большой скоростью работы этой базы данных. Я конечно только начал работать с ней и досконально не знаю всё, но вначале когда я установил эту базу каждый второй запрос выдавал ошибку блокировки базы. Разрыв соединения и повторное подключение помогло убрать 90% ошибок. Я на многих форумах описывал эту проблему но внятного ответа или метода исправления этой ошибки не получил.
Если кто то знает как ускорить работу базы и убрать ошибки и  переподключения, и поделиться со мной своими идеями, я буду очень благодарен за помощь.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.