Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Mysqli::stmt - Подготовленные выражения 
:(
    Опции темы
ksnk
Дата 27.10.2012, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(Fortop @  27.10.2012,  04:37 Найти цитируемый пост)
Объясни логику этого метода?

Вызывается некий общий метод (s_query), которому единственному дозволено вызывать сакральный метод  query  транспортного класса.

По форме - непонятно накой было вызывать его через call_user_func_array. Зачем нужно вписывать _mysqliFetchAssoc. Лучше вписать слово 'select', а в s_query получить этот самый _mysqliFetchAssoc из массива настроек транспорта (их еще нужно вписать).
Так может получится еще забавней - 
Код

public function select()
    {
         return $this->s_query('select', func_get_args());
    }



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Gold Dragon
Дата 27.10.2012, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



Fortop, по первой твоей цитате я уже ответил  smile 
Цитата(Gold Dragon @  25.10.2012,  21:17 Найти цитируемый пост)
ладно, спор тупиковый ;) 


А вот по второй части... можно и нужно поговорить.. Если ты внимательно читал сначала, то я сказал что код не мой и со многим не согласен и что этот код прямая противоположность к чему я привык, да и вообще полная противоположность моему стилю... НО(!) это работает, это полностью удовлетворяем моим потребностям, а значит этот "стиль" уже можно адаптировать "под себя"... Я собрал класс, уже внедрил в свою систему, работает идеально (особенно в совокупности с кэшем, правда файловым)

Цитата(Fortop @  27.10.2012,  05:37 Найти цитируемый пост)
Объясни логику этого метода?
Логику ты и сам видишь, не глупее же паровоза  smile 

Цитата(Fortop @  27.10.2012,  05:37 Найти цитируемый пост)
Вот почему явно не получить параметры в виде массива?
честно говоря, я бы так и сделал. Но начав переделывать использовать, то понял, что иногда это не нужно делать. И как ни странно, мне это понравилось. Конечно во мне до сих пор существует противоречие, которая явно против такого стиля, т. е. я всегда хочу знать что посылаю и что получаю... Но тут есть один нюанс: нам не нужно знать как это будет работать, но нам нужно знать как это нужно отсылать. А значит если класс отлажен то всё равно как он принимает параметры. А для пользователя очень будет удобно делать и так
Код

GDLDatabase::Init()->select("SELECT * FROM ............", $a, $b, $c);

и так
Код

$arr = array($a, $b, $c);
GDLDatabase::Init()->select("SELECT * FROM ............", $arr);

Согласись, очень удобно

Цитата(Fortop @  27.10.2012,  05:37 Найти цитируемый пост)
Почему, опять же явно, не передать их напрямую в s_query?
сам в шоке  smile Я скорее всего к этому и приду, если честно, то я пока не согласился с таким решением. Но пока оставил так лишь с той целью, если вдруг класс будет расширяться, а в select понадобится какое-либо условие...

PS
вот по этому мне и нужна серьёзная критика smile

Добавлено @ 09:33
Цитата(ksnk @  27.10.2012,  10:12 Найти цитируемый пост)
Зачем нужно вписывать _mysqliFetchAssoc. Лучше вписать слово 'select', а в s_query получить этот самый _mysqliFetchAssoc из массива настроек транспорта (их еще нужно вписать).
Да, скорее всего так и переделаю... т.е. нафига столько "транспорта"... нужно напрямую делать вызов


Это сообщение отредактировал(а) Gold Dragon - 27.10.2012, 09:35


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Fortop
Дата 27.10.2012, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(Gold Dragon @  27.10.2012,  09:30 Найти цитируемый пост)
Fortop, по первой твоей цитате я уже ответил

В первой цитате вопрос был к gta4kv, который настолько одарен, что не знает что сигнал распространяется не мгновенно.
И до фейсбука от меня примерно 20 хопов и 130мс соответственно. А до контакта всего 12 и 30мс.
В первом случае коннект идет к серверу в США, во втором случае в России.

К примеру, у нас европейские сервера имеют +0.2+0.4с задержки при обращении к яху, в сравнении с серверами в Техасе.


Цитата(Gold Dragon @  27.10.2012,  09:30 Найти цитируемый пост)
Согласись, очень удобно

Я пользуюсь IDE поэтому phpDoc решает вопрос с числом параметров.
А вот явное указание их для меня  уменьшает вероятность случайной ошибки => я могу сосредоточить внимание на более важных моментах.

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



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
Gold Dragon
Дата 28.10.2012, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



Цитата(Fortop @  27.10.2012,  23:03 Найти цитируемый пост)
Я пользуюсь IDE поэтому phpDoc решает вопрос с числом параметров.
А вот явное указание их для меня  уменьшает вероятность случайной ошибки 
Ну а кто же не пользуется IDE и phpDoc smile
А что касается ошибок, то в данном случае первый параметр всегда запрос, всё остальное - параметры smile



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Fortop
Дата 29.10.2012, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(Gold Dragon @  28.10.2012,  07:19 Найти цитируемый пост)
Ну а кто же не пользуется IDE и phpDoc

Тогда непонятно удобство.
Наоборот лишняя чехарда, массив или список параметров...
Вообще я за список.
Массив плохо поддается контролю со стороны IDE
А городить отдельный класс параметров для этого случая.... ну можно, но лениво.

Цитата(Gold Dragon @  28.10.2012,  07:19 Найти цитируемый пост)
А что касается ошибок, то в данном случае первый параметр всегда запрос, всё остальное - параметры 

Это для использования.
А для модификации этого класса?



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
Gold Dragon
Дата 29.10.2012, 07:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



Цитата(Fortop @  29.10.2012,  01:24 Найти цитируемый пост)
Это для использования.
А для модификации этого класса?
Согласен, мне понадобилось послать отдельный параметр для кэширования, а в данном случае нужно менять код полностью или посылать команду отдельно. 

Списком передавать хорошо, но вот только их количество всегда разное


Это сообщение отредактировал(а) Gold Dragon - 29.10.2012, 07:17


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
ksnk
Дата 29.10.2012, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(Gold Dragon @  29.10.2012,  07:17 Найти цитируемый пост)
Согласен, мне понадобилось послать отдельный параметр для кэширования, а в данном случае нужно менять код полностью или посылать команду отдельно. 

Что-то я не догоняю.
Идет  речь про вот такое?
Код

public function select()
    {
         ... func_get_args()...
    }


Fortop, утверждает, что это плохо и неудобно, так как фиг его знает какие параметры указывать, а IDE даже и не сможет подсказать. Ну так можно написать так
Код

/**
 * @param string $query - строка запроса
 * @return array $args - параметры - ассоциативный массив для bind'а
 *  
 */
public function select($query, $args)
    {
         ... func_get_args() ...
    }

ничего не меняя внутри метода и IDE будет доволен.

Дополнять ассоциативный массив новыми фичами для кэширования можно сколько угодно и каким угодно дополнитеным количеством параметров.



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Gold Dragon
Дата 29.10.2012, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



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

Но суть в другом.. У меня есть метод для кэширования результатов запросов
Код

    /**
     * Получить результат кэширования SQL-запроса
     *
     * @return mixed - данные
     * @throws GDLException
     *
     * @example
     *      string $params[0]      - метод класса БД
     *      string $params[1]      - строка SQL-запроса
     *      array  $params[2]..[n] - array $method - метод класса БД
     */
    public function getCacheSql()
    {
        // Получаем аргументы переданные в функцию
        $params = func_get_args();

        // метод класса БД
        $method = $params[0];
        unset($params[0]);

        // строка SQL-запроса
        $sql = $params[1];
        unset($params[1]);

        // путь до кэша
        $path = _GDL_PATH_CACHE . '/sql_cache/' . md5($method . $sql . serialize($params)) . $this->ext;

        // Создаём каталог если его ещё нет
        if (!is_dir($this->dir . '/sql_cache')) {
            mkdir($this->dir . '/sql_cache', 0777);
        }

        if(method_exists('GDLDatabase',$method)){

            if (is_readable($path) and _config('caching')) {
                $stat = stat($path);
                if (($stat['mtime'] + $this->time) > time()) {

                    // Если время ещё не истекло, получаем из файла
                    return unserialize(file_get_contents($path));
                } else {

                    // Если время истекло, делаем запрос в БД
                    $rows = GDLDatabase::Init()->$method($sql, $params);
                    file_put_contents($path, serialize($rows), LOCK_EX);
                    return $rows;
                }
            } else {

                // Если файла кэша не существует, делаем запрос в БД
                $rows = GDLDatabase::Init()->$method($sql, $params);
                file_put_contents($path, serialize($rows), LOCK_EX);
                return $rows;
            }
        }else{
            // Если нет метода
            throw new GDLException(sprintf("Метода %s в классе %s не существует", $method, 'GDLDatabase'));
        }
    }


суть в том, что напрямую я передать не могу, т.к. у меня первым идёт сам запрос. а дальше данные для постановки. И чтобы добавить мне какой-либо параметр, мне нужно всем методам сказать, что есть ещё один параметр... Т.е. это не проблема, но гибкость меняется..

Вот по этому мне пришлось написать новый метод.. Хотя может оно и лучше...

Т.е. вызов будет с кэшированием такой
Код

$rows = GDLDatabase::Init()->getCacheSql('select', 'SELECT * FROM table WHERE id=?', 15);

а без кэширование такой
Код

$rows = GDLDatabase::Init()->select('SELECT * FROM table WHERE id=?', 15);



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
ksnk
Дата 29.10.2012, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Код

$rows = GDLDatabase::Init()->select('SELECT * FROM table WHERE id=?', array(15,'cache_from'=>'select'));

может так? Насколько умный алгоритм расшивающий параметры в строке sql?



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Gold Dragon
Дата 29.10.2012, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



Цитата(ksnk @  29.10.2012,  13:40 Найти цитируемый пост)
может так? Насколько умный алгоритм расшивающий параметры в строке sql?
алгоритма пака нет.. но мысль интересная, хотя уже будет вносить путаницу, т.е. нужно помнить что должно быть в массиве для того или иного



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Fortop
Дата 30.10.2012, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(ksnk @  29.10.2012,  09:37 Найти цитируемый пост)
ничего не меняя внутри метода и IDE будет доволен.

Ну и смысл тогда в func_get_args и прочем? Я про это и говорю.


Цитата(ksnk @  29.10.2012,  12:40 Найти цитируемый пост)
может так? 

Массив тут крайне неинтересен поскольку плохоинформативен и начинает содержать неоднородные параметры (одни для подстановки в запрос, другие для кеширования)
Я из-за похожей методики туго перевариваю Yii - он заставляет помнить кучу ненужного материала или постоянно лезть в мануал.

Подошел бы такой вариант, 
Цитата(Fortop @  29.10.2012,  00:24 Найти цитируемый пост)
А городить отдельный класс параметров для этого случая.... ну можно, но лениво.

но он трудоемок (хотя если код не консистентный, то можно сделать только для этого случая, а в других местах использовать что-то другое).





--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
ksnk
Дата 30.10.2012, 07:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(Fortop @  30.10.2012,  00:41 Найти цитируемый пост)
Ну и смысл тогда в func_get_args и прочем? Я про это и говорю.

Смысл? Процедура транспортного уровня - приватная и как она устроена - никого не должно волновать. Так что пусть получает один параметр - массив. Почему бы и нет? Зачем многократно перекладывать из массива в параметры и обратно, как это было в коде ? Обсуждаемая функция (select) - просто обертка над транспортом. Она должна выглядеть удобно для писателя, а внутренняя - удобно для исполнения. 

Цитата(Fortop @  30.10.2012,  00:41 Найти цитируемый пост)
Массив тут крайне неинтересен поскольку плохоинформативен и начинает содержать неоднородные параметры

В принципе - согласен. 

Можно предложить еще один способ "впихнуть невпихуемое".
Код

$rows = GDLDatabase::Init(array('cache'=>'select'))->select('SELECT * FROM table WHERE id=?', 15);

к инстанцируемому объекту привязывается опция. 

Вообще, считаю что у Котерова была замечательная идея в DBSimple про то, что нужно явно указывать способ приведения параметров к типу прямо в SQL запросе - макроподстановки при пустом параметре и  макры типа ?d, ?#, ?a . Правда использование "массивных" макр не совершенно, иногда приходится выписывать лишние array_keys и array_values  
Код

$user = array('user_id' => 101, 'user_name' => 'Rabbit', 'user_age' => 30);
$newUserId = $DB->query(
    'INSERT INTO user(?#) VALUES(?a)', 
    array_keys($row), 
    array_values($row)
);
 а если `insert in duplicate values update` - то вообще 2 раза их вставлять...
У pdo есть не менее замечательная идея, что можно использовать "именованные" параметры в строке sql. А вот для указания типа параметра прямо в запросе - не догадались, приходится городить отдельный бинд каждого параметра с указанием типа.
Так что если объединить пару идей, то может получится что-то близкое к совершенству.  smile Останется только со всем этим добром взлететь...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
ksnk
Дата 30.10.2012, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Придумалось, что новый огород городить смысла нет, можно воспользоваться "шаблонными" идеями. Из твига, например. При этом элегантно решается проблема использования вопросиков в неожиданных местах запроса.
Код

$DB->query(
    'INSERT INTO user({{?1|keys}}) VALUES({{?1|val}})', 
    $row
);

Это будет - вставить первый параметр, проверить на "массивность". Обычный вопросик без цифры - следующий по порядку параметр.
Код

$DB->query(
    'INSERT INTO user({{row|keys|noescape}}) VALUES({{row|val}})', 
    array('row'=>$row)
);

Это - именованный параметр. "фильтры" видятся в таком наборе 
- key, value - массивные строковые списки с дефолтным escape'ом строковых параметров у keys
- int, float - проверка параметра на целость - дробность, без escape
- noescape - не ескейпить параметры
Макры для условной генерации
Код

$rows = $DB->select('
        SELECT *
        FROM goods
        WHERE 
            category_id = ?
          {% if ? %} AND activated_at > {{?|int}} {% endif %}
        LIMIT ?d
    ',
    $categoryId,
    $_POST['activated_at'],
    $pageSize
);


Хотя с IF'ом, вероятно, несколько перегружено, есть ли необходимость в еще каких-нибудь контрольных операторах? 


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
baldina
Дата 30.10.2012, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(Gold Dragon @  22.10.2012,  13:48 Найти цитируемый пост)
мне нужен не монстр, а маленький, удобный, понятный, простой класс

 smile 
PM MAIL   Вверх
ksnk
Дата 30.10.2012, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Ну, про немонстра, вероятно, действительно несбыточное желание. А вот про маленького монстрика - вполне.

Что-то написалось. На мой взгляд - довольно гибко и прилично.
Вот кусочек юнит тестов
Код

    function test_ArrayTemplate()
    {
        $sql=new sql_template();
        $func=$sql->parse('insert into xxx ({{?|keys|join(",")}}) values ({{?1|values|join(",")}}) ;');
        $this->assertEquals("insert into xxx ('one','two') values ('one_value','two_value') ;", $func(
            array('one'=>'one_value','two'=>'two_value')));
    }
    function test_IntTemplate()
    {
        $sql=new sql_template();
        $func=$sql->parse('select * from index where {{?|int}}<`field`;');

        $this->assertEquals("select * from index where 25<`field`;", $func(25));
    }



Смысл шаблонизатора - строка sql-twig шаблона, парсится в строку и из нее собирается функция с помощью create_function. Функция САМА эскейпит параметры и всячески над ними издевается.

Способ работы с ней, вероятно, какой-то такой 
Код

function select($sql,arg1,arg2,...) {
  $func=   $sql_template->parse($sql) ;
  $arg= array_shift(func_get_args());
  $result=mysql_query(call_user_func_array($func,$arg));
  ...
}


Сейчас поддерживаются только ?\d* параметры, без именования.

Писано за пару часов, так что не обессудьте. Но вдруг кого заинтересует...
https://github.com/Ksnk/sql_template


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0811 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.