Admin писал(а):Сорри Димка, у тебя Скайп был выключен пару дней, я с SHW, решил поправить текущие баги и зарелизить новую версию, как говориться небольшой подарок к Новому Году пользователям )
Пле, скайп обновился и вылетел из автозапуска ... Я последнюю неделю фактически не дома был, в стационар ложусь, подлечиться. Бегал в поликлинику (из за разных юридических проволочек, дабы лечение бесплатно получить), и в конце дня уже просто не обращал внимания что он выключен.
shw писал(а):Префиксы добавить к запросам -это в принципе легко, но если хочешь действительно поломать голову -
Ну я ж говорю, если просто так, то да - легко. Но это усложнит текущий скрипт установки, не позволит просто так выдавать файлы с sql обновлениями и прочим.
Поэтому я заморочился, написал класс, который является расширением PDO и первично перехватывает все запросы в БД, может их обрабатывать, и соотв. заменяет названия таблиц. Т.е. текущий код в модуле менять не надо вообще. Потом правда в гугле нашел почти идентичное решение, позаимсвовал оттуда код для остальных функций.
Вот, смотри сам:
Читать дальше
Код: Выделить всё<?php
if (preg_match ("/mysql.php/", $_SERVER['PHP_SELF']))
{
//header ("Location: /index.php");
exit;
}
$dbhost ='localhost';
// username and password to log onto db SERVER
$dbuser ='root';
$dbpass ='';
// name of database
$dbname='';
//en - Prefix must be min 1 symbol, max 5 symbols, with _ at the end. Only a-z, A-Z and numbers allowed. For example: $dbprefix = 'msfc_';
//ru - Префикс должен быть не менее 1 и не более 5 символов, в конце префикса должен быть символ _. Разрешены только английские буквы и цифры.
//Для примера: $dbprefix = 'msfc_';
$dbprefix = 'gs_';
$sqlchar = 'utf8';
//$db = new PDO ( 'mysql:host=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
class MyPDO extends PDO
{
var $prefix;
var $sqls;
var $count;
private $pattern = array();
private $replacement = array();
private $matches;
public function __construct($dsn, $user = null, $password = null, $driver_options = array(),$dbprefix = null)
{
$this->count = 0;
$this->sqls = array();
if (preg_match("/[a-zA-Z0-9]{1,5}_/i", $dbprefix, $this->matches)) {
$this->prefix = $this->matches[0];
} else {
$this->prefix = 'msfc_';
}
$this->pattern = '/(col_medals|col_players|col_rating_tank|col_tank|config|tabs|top_tanks|tanks|users|gk)/';
$this->replacement = $this->prefix.'$1';
parent::__construct($dsn, $user, $password, $driver_options);
}
public function prepare($statement, $driver_options = array())
{
$this->count += 1;
$statement = preg_replace($this->pattern, $this->replacement, $statement);
$this->sqls[$this->count] = $statement;
return parent::prepare($statement, $driver_options);
}
public function query($statement)
{
$this->count += 1;
$statement = preg_replace($this->pattern, $this->replacement, $statement);
$this->sqls[$this->count] = $statement;
$args = func_get_args();
if (count($args) > 1) {
return call_user_func_array(array($this, 'parent::query'), $args);
} else {
return parent::query($statement);
}
}
public function exec($statement)
{
$this->count += 1;
$statement = preg_replace($this->pattern, $this->replacement, $statement);
$this->sqls[$this->count] = $statement;
return parent::exec($statement);
}
}
try {
$db = new MyPDO ( 'mysql:host=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass, array() ,$dbprefix);
} catch (PDOException $e) {
//echo $e->getMessage();
die(show_message($e->getMessage()));
}
$db->query ( 'SET character_set_connection = '.$sqlchar );
$db->query ( 'SET character_set_client = '.$sqlchar );
$db->query ( 'SET character_set_results = '.$sqlchar );
?>
Паралельно повилось несколько удобных фич, в виде того что можно подсчитать количество запросов к базе, ну и посмотреть все запросы в бд.
Подводный камень в том, что он меняет все такие значения. Например в базу заноситься таб gk.php как prefix_gk.php. Так что надо внимательно проследить не только за названием таблиц, но и названием переменных и их содержимым. Я пока что больше таких замен в переменных/их значениях не нашел. А проблема с вкладкой решается переименованием из gk.php в например blocked.php.
Ну и в коде, пару запросов show tables like надо подправить, или добавить вначале % или сам префикс из $db->prefix, таких запросов всего пару штук, так что не критично.
Ну и нельзя использовать $db->execute() с передаваемыми параметрами в сам execute, но в модуле такого нет вообще, все идет через prepare()
Можно в место preg_replace использовать sprintf а все префиксы в запросы добавить в виде %1$s - но это как ручная правка запросов, и не отменяет проблем с установкой
shw писал(а):Вот тебе список проблем:
1) Как прикрутить единый интерфейс? (ведь подразумевается, что с одной странички с помощью какого-то переключателя идет выбор текущего клана из списка)
2) Как разделять кэш для кланов?
3) Как делать запуск крона в этом ракурсе, если хостингер например чаще всего обрезает из крона все, что после "?", т.е. параметр php страничке не передать толком?
1) Пфф. Элементарно. Все решается добавлением поля clan_id во все таблицы. И изменение запросов с добавлением where clan_id = ''. Ну кроме таблицы с танками, она то может быть одна на все кланы. Так что это скорее рутинная работа на дописание запросов, и проверок на изменение айди, если человек бегает из клана в клан.
А если ты о отображении клана, можно заранее вбить список кланов, отображаемое название и его айди. И при получении конфига проверять адресную строку на предмет $_POST или $_GET уникального, и если он задан, и в списке кланов, просто в самом коде менять например дефолтное значение на переданное в адресной строке. Страницу же постоянно обновлять не надо. А для аякс запросов просто добавить опять же параметр с айди клана.
Ну и формы обновить, добавить hidden атрибут с айди нужного клана.
В общем с точки зрения логики реализации это не так сложно.
2) Ваапще элементарно. Добавлять айди клана к названию кэша. Оно и уникально, и легко доступно в коде.
Код: Выделить всё$cache->clear($config['clan'].'_get_last_roster');
3) Несколько задач крона, или даже более хитрый запуск задач крона - каждые пять-десять минут в течении одного часа. Создаешь таблицу в бд, со всеми используемыми id клана, напротив id клана - дата последнего обновления данных в timestamp. Их тебе человек сам напишет, когда будет добавлять кланы. И при запуске крона брать один, который обновлялся позднее всего, max() и min() в sql запросах никто не отменял. И обновляешь именно этот клан. При успешном обновлении просто обновляешь это время (ну и никто не отменял проверку на разницу между последним обновлением и заданным интервалом в админке).
Да если на то пошло, можно заставить крон выполнять файл каждые 10 минут, в течении дня, и просто смотреть на разницу между последним обновлением и настройкой в админке. Будут "холостые" запуски. Серверу и скрипту пофиг, холостые запуски ресурсы сервера не забирают.