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

Поиск:

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


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


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

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



Читаю литературу и везде один и тот же пример.. Общую теорию освоил:
- т.е. мы готовим запрос ->prepare() с вопросительными знаками
- далее связываем типы с данными ->bind_param()
- и выполняем запрос ->execute()

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

Допустим у меня есть "обёртка" MySQLi. Где-то в начале я подключаюсь в базе..  Далее при необходимости я делаю два вызова метода класса обёртки: первый - формирую сам запрос, второй - то что хочу получить.

Например
Код

$db->setQuery('SELECT * FROM table WHERE id_cat = ? AND name = ?', 'is', array('2','имя'));

Т.е. отправляю запрос, строку с типами (число и строка) и массив с данными

Следующим запросом я хочу получить допустим ассоциативный массив с объектами в формате
Цитата

[0]
   id_cat->X 
   name->Y
[1]
   id_cat->X 
   name->Y
[2]
   id_cat->X 
   name->Y

И соответственно делаю запрос
Код

$db->getObjectArray();

И тут возникают проблемы.. 
Во-первых, в bind_param нужно перечислять переменные, а значит массив не покатит.
Во-вторых, не совсем понятно как мне доставать результат.

Кто уже активно работает с этим прошу научить ;) а если есть готовая обёртка, то буду просто рад

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


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


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

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



Или я не очень понял сути, или все зависит от фреймворка, не?
PM MAIL WWW ICQ Skype   Вверх
Gold Dragon
Дата 22.10.2012, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Я делаю CMS в том числе сейчас пишу обёртку для MySQLi. Вернее у меня уже есть класс для работы с mysqli, но хочу её переделать чтобы использовать mysqli_stmt. Но что-то пока не могу понять как этим вообще пользоваться. На простых примерах всё просто, а вот сделать что-то универсальное пока не получается. Т.е. когда не известно сколько и каких данных поступает в запросе и в каком формате выдать результат



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


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

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



У Котерова в книге PHP5 можно прочитать про placeholders, впервые я это увидел там (еще до появления многих фрейморков). Вообще не очень понятно зачем что-то возвращать, или имеется ввиду внутренний механизм? Если так, то там просто идет замена ? на значения массива.
PM MAIL WWW ICQ Skype   Вверх
Gold Dragon
Дата 22.10.2012, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Может не совсем понятно объяснил... В общем чтобы получить какой-либо результат мне нужно вызвать два метода "обёртки"
Первый формирует сам запрос, т.е. всё подставляет: меняет префиксы таблицы в соответствии с настройками движка, проверяет входные данные на соответствие и т.п. и т.д. Сейчас использую простое экранирование для строк (mysqli_real_escape_string). А вот этот подход должен меня избавить от подобного и сам запрос будет безопаснее, да и работать с ним проще.

А вот второй метод (вернее их множество) должен возвращать данные в том виде в котором я их хочу получить. Допустим, только первую строку или весь результат в ассоциативном массиве или же объектом или только первое значение первой строки и т.п.


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


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


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

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



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

PS
документации по mysqli_stmt практически вообще нет :(


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


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


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

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



Цитата(Gold Dragon @  22.10.2012,  08:19 Найти цитируемый пост)
 а если есть готовая обёртка, то буду просто рад

Вообще-то она есть, и называется PDO. Во всяком случае- методы именно оттуда. В нем есть, разной степени удобства, механизм подстановки параметров. Вместе с bindParam или прямо в execute массивом. Именованные параметры или вопросики по порядку и так далее...

Другое дело, если ли в этом pdo поддержка mysqli_stmt?


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


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


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

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



Цитата(ksnk @  22.10.2012,  14:40 Найти цитируемый пост)
Вообще-то она есть, и называется PDO
мне нужен не монстр, а маленький, удобный, понятный, простой класс smile
В принципе DbSimple это то что мне нужно, но немного не то что я хочу получить в идеале.. попробую сначала его поломать и посмотреть... 



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


Эксперт
****


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

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



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

в итоге вы родите монстра, но для вас он останется маленьким, удобным и пушистым. потому что понятным.
PM MAIL   Вверх
Gold Dragon
Дата 22.10.2012, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(baldina @  22.10.2012,  15:02 Найти цитируемый пост)
в итоге вы родите монстра, но для вас он останется маленьким, удобным и пушистым. потому что понятным. 
пусть будет так smile Но мне сейчас очень хочется вообще понять принцип этого всего



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


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


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

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



Цитата(Gold Dragon @  22.10.2012,  13:48 Найти цитируемый пост)
В принципе DbSimple это то что мне нужно

Если не смущают конструкции типа 
Код

$object =& new $class($parsed);

на которые ругается синтаксически анализатор, начиная с 5-го php, то почему бы и нет.  smile 

А вообще, вместе с Котеровской debugConsole - достаточно удобная штука. Хотя я от нее недавно отказался в пользу класса из instantCMS. Он там совсем никакой, даже сам не эскейпит параметры и его еще нужно допиливать, зато маленький и понятный  smile 


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


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


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

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



а разве его (DbSimple) не допилили до 5-й? А вообще. я уже не рассматриваю всё что ниже PHP5.3


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


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


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

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



В общем нашёл обёртку, практически то что мне нужно.. сделана как утверждает автор на основе DbSimple.
Правда стиль написания очень своеобразный: всё на ссылках, вызовах пользовательских функций и callback.. Да и как-то наследуемый класс получается вспомогательным для основного.. Очень не привычно... Честно говоря пока очень путаюсь...

Но главное всё работает и отлично работает

вот SVN
http://code.google.com/p/simple-mysqli-class/

Выборку можно делать как так
Код

$query=$db->select('SELECT * FROM test WHERE id =? AND id_cat =?', 2, 3);

так и вот так
Код

$query=$db->select('SELECT * FROM test WHERE id =? AND id_cat =?', array(2, 3));


Основные выборки

    Выборка строки: selectRow()
    Выборка ячейки: selectCell()
    Выборка столбца: selectCol()
    Выборка всего: select()
    Вставка данных: insert()
    Удаление: delete()
    Замена: replace()

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

Это сообщение отредактировал(а) Gold Dragon - 23.10.2012, 18:11


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


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


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

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



В общем вот собрал класс-обёртку. Прошу посмотреть, оценить, покритиковать, дополнить, улучшить... в общем вы всё знаете сами smile
Постарался всё полностью прокомментировать.
Код

class GDLDatabase
{
    /** @var string - префикс для таблиц */
    private $_db_prefix;

    /** @var null|object - интерфейс */
    protected static $_resource = null;

    /** @var \mysqli - MySQLi object */
    protected $db_resource;

    /** @var \mysqli_stmt - MySQLi_STMT object */
    protected $stmp;

    /** @var string - имя метода для подготовленного запроса */
    protected $returnMethod;

    /** @var array - ассоциациативный массив
     *      [affected_rows] - Количество строк, затронутых последним запросом
     *      [insert_id]     - ID, сгенерированный предыдущей операцией INSERT,
     *      [num_rows]      - Число строк в результате запроса
     *      [field_count]   - Число полей в заданном выражении
     *      [sqlstate]      - SQLSTATE ошибка последнего запроса
     */
    public $queryInfo;

    /***************************************************************************
     * Magic methods
    /***************************************************************************/

    /**
     * Конструктор
     * Защищаем от создания через new
     */
    private function __construct()
    {

        // Проверка существует ли вообще функция подключения
        if (!function_exists('mysqli_connect')) {
            throw new GDLException(_EXC_MYSQLI_MODULE_NOT);
        }

        // Создаём объект базы
        $this->db_resource = new mysqli(_config('db_host'), _config('db_user'), _config('db_password'), _config('db_name'), _config('db_port'), _config('db_socket'));

        // Устанавливаем кодировку
        $this->db_resource->set_charset('utf8');

        if ($this->db_resource->connect_error) {
            throw new GDLException(_EXC_ERROR_CONNECT_DB);
        }

        // записываем логи запросов
        if (_config('db_debug')) {
            $this->db_resource->query('set profiling=1');
            $this->db_resource->query('set profiling_history_size=100');
        }

        // запоминаем префикс таблиц
        $this->_db_prefix = _config('db_prefix');
    }

    /**
     * Защищаем от создания через клонирование
     */
    private function __clone()
    {
    }

    /**
     * Защищаем от создание через unserialize
     */
    private function __wakeup()
    {
    }

    /**
     * @static Подключение класса
     *
     * @return object
     */
    public static function Init()
    {
        if (!is_object(self::$_resource)) {
            $class_name = __CLASS__;
            self::$_resource = new $class_name;
        }

        return self::$_resource;
    }


    /***************************************************************************
     * Private methods
    /***************************************************************************/

    /**
     * Передаёт параметры в подготовленный запрос
     *
     * @param  array  $bindVars - значения для заметы
     * @param  array  $params   - параметры
     *
     * @return mixed
     */
    private function _bindParams($bindVars, &$params)
    {
        $params[] = $this->_getParamTypes($bindVars);
        foreach ($bindVars as $key => $param) {
            $params[] = &$bindVars[$key]; // pass by reference, not value
        }

        return call_user_func_array(array($this->stmp, 'bind_param'), $params);
    }

    /**
     * Связывает результат с запросом
     *
     * @param  $data
     *
     * @return mixed
     */
    private function _bindResult(&$data)
    {
        $this->stmp->store_result();
        $variables = array();

        $meta = $this->stmp->result_metadata();

        while ($field = $meta->fetch_field()) {
            $variables[] = &$data[$field->name];
        }

        return call_user_func_array(array($this->stmp, 'bind_result'), $variables);
    }

    /**
     * Возвращает полный результат запроса
     *
     * @param  string $data - строка запроса
     *
     * @return array|bool - двухмерный массив с результатом запроса
     */
    private function _mysqliFetchAssoc(&$data)
    {
        $i = 0;
        $array = array();
        while ($this->stmp->fetch()) {
            $array[$i] = array();
            foreach ($data as $k => $v) {
                $array[$i][$k] = $v;
            }
            $i++;
        }

        return $array;
    }

    /**
     * Возвращает первый столбец запроса
     *
     * @param string $data - строка запроса
     *
     * @return array|bool - возвращаемые значения
     */
    private function _mysqliFetchCol(&$data)
    {
        $i = 0;
        $array = array();
        while ($this->stmp->fetch()) {
            $array[$i] = array();
            foreach ($data as $v) {
                $array[$i] = $v;
                break;
            }
            $i++;
        }

        return $array;
    }

    /**
     * Возвращает первую строку запроса
     *
     * @param string $data - строка запроса
     *
     * @return array - возвращаемые значения
     */
    private function _mysqliFetchRow(&$data)
    {
        $this->stmp->fetch();

        return $data;
    }

    /**
     * Возвращает первую ячейку первой строки запроса
     *
     * @param string $data - строка запроса
     *
     * @return string - возвращаемые значения
     */
    private function _mysqliFetchCell(&$data)
    {
        $this->stmp->fetch();

        return $data[key($data)];
    }

    /**
     * Возвращает откомпелированную строку для связи с параметрами
     *
     * @param  $arguments
     *
     * @return string
     */
    private function _getParamTypes($arguments)
    {
        unset($arguments[0]);
        $retval = '';
        foreach ($arguments as $arg) {
            $retval .= $this->getTypeByVal($arg);
        }

        return $retval;
    }

    /**
     * Замена префикса в SQL-запросе
     *
     * @param $sql
     *
     * @return mixed
     */
    private function _replacePrefix(&$sql)
    {
        $sql = str_replace('#__', $this->_db_prefix, $sql);
    }
    /***************************************************************************
     * Protected methods
    /***************************************************************************/

    /**
     * Выполнение запроса
     *
     * @param array $arguments - данные запроса
     *
     * @return bool
     */
    protected function query($arguments)
    {
        $this->prepareQuery($arguments);
        $query = $arguments[0];

        if ($this->stmp) {
            $this->stmp->close();
        }

        $this->stmp = $this->db_resource->prepare($query);
        if (!$this->stmp) {
            return false;
        }

        if (count($arguments) > 1) {
            $bindVars = $arguments;
            unset($bindVars[0]);
            $params = array();
            $binding = $this->_bindParams($bindVars, $params);
            if (!$binding) {
                return false;
            }
        }

        return true;
    }

    /**
     * Метод для запросов SELECT-подобных
     *
     * @return array|string|bool
     *      array: select, selectCol, selectRow
     *      string: selectCell
     *      bool: false при ошибке
     */
    protected function s_query()
    {
        $data = null;
        $arguments = func_get_args();
        $this->query($arguments);
        if (!$this->stmp) {
            return false;
        }

        $execute = $this->stmp->execute();
        if (!$execute) {
            return false;
        }

        $result = $this->_bindResult($data);
        if (!$result) {
            return false;
        }

        $returnPrepareMethod = $this->returnMethod;
        $rows = $this->$returnPrepareMethod($data);
        $this->setQueryInfo();

        return $rows;
    }

    /**
     * Метод для запросов INSERT/DELETE-подобных
     *
     * @return bool|MySQLi_STMT
     */
    protected function i_query()
    {
        $arguments = func_get_args();
        $this->query($arguments);
        if (!$this->stmp) {
            return false;
        }

        $execute = $this->stmp->execute();
        if (!$execute) {
            return false;
        }
        $this->setQueryInfo();

        return true;
    }

    /**
     * Сохранение дополнительной информации
     *
     * @return void
     */
    protected function setQueryInfo()
    {
        $info = array('affected_rows' => $this->stmp->affected_rows, 'insert_id' => $this->stmp->insert_id, 'num_rows' => $this->stmp->num_rows, 'field_count' => $this->stmp->field_count, 'sqlstate' => $this->stmp->sqlstate,);
        $this->queryInfo = $info;
    }

    /**
     * Extended placeholder %s (array)<br>
     *
     * @param  $arguments
     *
     * @return void
     */
    protected function prepareQuery(&$arguments)
    {
        $sprintfArg = array();

        // замена префикса
        $this->_replacePrefix($arguments[0]);

        // Строка запроса
        $sprintfArg[] = $arguments[0];
        foreach ($arguments as $pos => $var) {
            if (is_array($var)) {
                $insertAfterPosition = $pos;
                $replaceWith = array();
                unset($arguments[$pos]);
                foreach ($var as $arrayVar) {
                    array_splice($arguments, $insertAfterPosition, 0, $arrayVar);
                    $insertAfterPosition++;
                    $replaceWith[] = '?';
                }
                $sprintfArg[] = implode(',', $replaceWith);
            }
        }
        $arguments[0] = call_user_func_array('sprintf', $sprintfArg);
    }

    /**
     * Определяет тип данных (int,float or string)
     *
     * @param  string $variable - значение
     *
     * @return string - тип
     */
    protected function getTypeByVal($variable)
    {
        switch (gettype($variable)) {
            case 'integer':
                $type = 'i';
                break;
            case 'double':
                $type = 'd';
                break;
            default:
                $type = 's';
        }
        return $type;
    }

    /***************************************************************************
     * Public methods
    /***************************************************************************/

    /**
     * Возвращает полный результат запроса
     *
     * @param  string $query - строка запроса
     *
     * @return array|bool - двухмерный массив с результатом запроса
     */
    public function select($query)
    {
        $this->returnMethod = '_mysqliFetchAssoc';
        $arguments = func_get_args();

        return call_user_func_array(array($this, 's_query'), $arguments);
    }

    /**
     * Возвращает первый столбец запроса
     *
     * @param string $query - строка запроса
     *
     * @return array|bool - возвращаемые значения
     */
    public function selectCol($query)
    {
        $this->returnMethod = '_mysqliFetchCol';
        $arguments = func_get_args();

        return call_user_func_array(array($this, 's_query'), $arguments);
    }

    /**
     * Возвращает первую ячейку первой строки запроса
     *
     * @param string $query - строка запроса
     *
     * @return string - возвращаемые значения
     */
    public function selectCell($query)
    {
        $this->returnMethod = '_mysqliFetchCell';
        $arguments = func_get_args();

        return call_user_func_array(array($this, 's_query'), $arguments);
    }

    /**
     * Возвращает первую строку запроса
     *
     * @param string $query - строка запроса
     *
     * @return array|bool - возвращаемые значения
     */
    public function selectRow($query)
    {
        $this->returnMethod = '_mysqliFetchRow';
        $arguments = func_get_args();

        return call_user_func_array(array($this, 's_query'), $arguments);
    }

    /**
     * Выполнение UPDATE
     *
     * @param  string $query - строка запроса
     *
     * @return bool
     */
    public function update($query)
    {
        $arguments = func_get_args();

        return call_user_func_array(array($this, 'i_query'), $arguments);
    }

    /**
     * Выполнение INSERT
     *
     * @param  string $query - строка запроса
     *
     * @return bool
     */
    public function insert($query)
    {
        $arguments = func_get_args();

        return call_user_func_array(array($this, 'i_query'), $arguments);
    }

    /**
     * Выполнение REPLACE
     *
     * @param  string $query - строка запроса
     *
     * @return bool
     */
    public function replace($query)
    {
        $arguments = func_get_args();

        return call_user_func_array(array($this, 'i_query'), $arguments);
    }

    /**
     * Выполнение DELETE
     *
     * @param  string $query - строка запроса
     *
     * @return bool
     */
    public function delete($query)
    {
        $arguments = func_get_args();

        return call_user_func_array(array($this, 'i_query'), $arguments);
    }

    /**
     * Старт транзакции
     * @return void
     * @example:
    *      $db=GDLDatabase::Init();
     *      $db->transactionStart();
     *      $db->insert('INSERT INTO `test` set testval=?',20);
     *      $db->insert('INSERT INTO `test` set testval=?',10);
     *      $db->insert('INSERT INTO `test` set testval=?',123);
     *      $db->transactionCommit();
     */
    public function transactionStart()
    {
        $this->db_resource->autocommit(false);
    }

    /**
     * Остановка транзацкии
     *
     * @return void
     */
    public function transactionCommit()
    {
        // фиксирует текущую транзакцию
        $this->db_resource->commit();

        // Включает автоматическую фиксацию изменений базы данных
        $this->db_resource->autocommit(true);
    }

    /**
     * Откат текущей транзакции
     *
     * @return void
     * @example:
     *      $db=GDLDatabase::Init();
     *      $db->transactionStart();
     *      $db->insert('INSERT INTO `test` set testval=?',20);
     *      $db->insert('INSERT INTO `test` set testval=?',10);
     *      $db->insert('INSERT INTO `test` set testval=?',123);
     *      $db->transactionRollBack();
     *      $db->transactionCommit();
     */
    public function transactionRollBack()
    {
        $this->db_resource->rollback();
    }

    /**
     * @param string $query - Простое выполнение запроса
     *
     * @return bool|mysqli_result
     */
    public function simpleQuery($query = '')
    {
        return $this->db_resource->query($query);
    }

    /**
     * Возвращает ошибку
     *
     * @return string
     */
    public function getError()
    {
        return $this->db_resource->error;
    }

    /**
     * Возвращает номер ошибки запроса
     *
     * @return int
     */
    public function getErrno()
    {
        return $this->db_resource->errno;
    }

    /**
     * Возвращает обьект класса mysqli для нереализованных операций
     *
     * @return mysqli
     */
    public function getObject()
    {
        return $this->db_resource;
    }

    public function __destruct()
    {
        $this->db_resource->close();
    }
}


Класс пишу для конкретного проекта, так что основные настройки получаю через псевдо-функцию по типу такой
Код

function _config($key = ''){
     return Config::$config->$key;
} 


Это сообщение отредактировал(а) Gold Dragon - 24.10.2012, 10:40


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


Эксперт
****


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

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



Цитата(Gold Dragon @  24.10.2012,  10:33 Найти цитируемый пост)
function _config($key = ''){
     return Config::$config->$key;


Вопрос. как ты планируешь обращаться к свойству класс с именем ''?


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


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


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

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



Цитата(Fortop @  25.10.2012,  02:31 Найти цитируемый пост)
Вопрос. как ты планируешь обращаться к свойству класс с именем ''? 

НУ это я чисто для примера привёл, т.е. в этой функции заложено получение переменных конфигурации...

Функция это всего лишь короткая форма. Так что в классе все "непонятные" значение превратятся в NULL, т.е. в расширенной версии и функции и класса всё это предусмотрено.

 

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


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


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


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

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




Так что по Классу скажите?


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


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


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

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



Цитата(Gold Dragon @  25.10.2012,  07:37 Найти цитируемый пост)
Так что по Классу скажите?

Класс на 400 строк с экрана оценить?  smile 

На первый взгляд - там слишком много завязок на stmt реализацию. Вроде бы сам класс достаточно гибок, чтобы подключать к нему и другой транспорт. Просто прикинуть, как будет выглядеть это-же при pdo или нормальном mysql и выкинуть частные функции в транспортный класс или в отдельный массив настроек.


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


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


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

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



Цитата(ksnk @  25.10.2012,  10:41 Найти цитируемый пост)
Класс на 400 строк с экрана оценить?  
Ну там большая часть комментарии smile

А почему плохо что лишком много завязок на stmt реализацию?


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


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


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

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



Цитата(Gold Dragon @  25.10.2012,  09:46 Найти цитируемый пост)
А почему плохо что лишком много завязок на stmt реализацию? 

Тем, что стандартный (для меня) класс - mysql. Иногда нужен mysqli. Один раз встречался pdo. 
Если привыкать к какому-то единому интерфейсу, то лучше, чтобы класс минимальными телодвижениями превращался в то что нужно, без правки окружающего кода. В идеале - просто конфигурацией .


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


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


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

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



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

Цитата(ksnk @  25.10.2012,  12:34 Найти цитируемый пост)
Тем, что стандартный (для меня) класс - mysql. Иногда нужен mysqli. 
Так MySQL давно уже устарел smile

Добавлено @ 12:11
чуть изменил один метод.. Добавил обработку исключений когда количество маркеров в запросе не совпадает с количеством входных данных
Код

    protected function query($arguments)
    {
        $this->prepareQuery($arguments);
        $query = $arguments[0];

        if ($this->stmp) {
            $this->stmp->close();
        }

        $this->stmp = $this->db_resource->prepare($query);
        if (!$this->stmp) {
            return false;
        }

        if (count($arguments) > 1) {
            $bindVars = $arguments;
            unset($bindVars[0]);
            $params = array();
            if(substr_count($query,'?') == count($bindVars)){
                $binding = $this->_bindParams($bindVars, $params);
                if (!$binding) {
                    return false;
                }
            }else{
                throw new Exception('Количество маркеров в SQL-строке не совпадает с количеством данных');
            }
        }
        return true;
    }



Это сообщение отредактировал(а) Gold Dragon - 25.10.2012, 12:13


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


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


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

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



Цитата(Gold Dragon @  25.10.2012,  12:02 Найти цитируемый пост)
Так MySQL давно уже устарел

Скажете это фейсбуку и вконтакту? "а мужики-то не знают..."   smile 


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


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


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

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



ну так у нас ВАЗ до сих пор 7-ку выпускает  smile 

Для меня вообще-то это не авторитеты.. Да это достаточно мощные и супер раскрученные системы. Но с точки зрения движка - я бы не сказал что уж супер-пупер

Добавлено через 3 минуты и 8 секунд
да и если создавать CMS с нуля, то уж лучше сразу ориентироваться на самое новое


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


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

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



Цитата(Gold Dragon @  25.10.2012,  14:34 Найти цитируемый пост)
Для меня вообще-то это не авторитеты.. 

[holywar]А кто тогда для вас авторитеты?[/holywar]
PM MAIL WWW ICQ Skype   Вверх
Gold Dragon
Дата 25.10.2012, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Вот когда я ставлю тебе плюс в репу, вот тогда ты для меня авторитет ;) Думаю мысль мою понял...


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


Walking around mad.
***


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

Репутация: 4
Всего: 91



Цитата

Для меня вообще-то это не авторитеты.. Да это достаточно мощные и супер раскрученные системы. Но с точки зрения движка - я бы не сказал что уж супер-пупер


Смешно...
PM MAIL   Вверх
Gold Dragon
Дата 25.10.2012, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



что именно?


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


Walking around mad.
***


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

Репутация: 4
Всего: 91



Смешно, что не показатель. Смешно и это:
Код

Но с точки зрения движка - я бы не сказал что уж супер-пупер


А что вы о них знаете? А вообще о построение систем из тысяч серверов? Что с ними не так? 

Особенно контакт, кстати, страницы открываются - моментально. Чем фейсбук не может похвастаться. 
PM MAIL   Вверх
Gold Dragon
Дата 25.10.2012, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



ну хотя бы потому
Цитата
Цитата(Gold Dragon @  25.10.2012,  12:02 Найти цитируемый пост)
Так MySQL давно уже устарел

Скажете это фейсбуку и вконтакту?

Если даже сами разработчики говорят отказаться от использования MySQL

Добавлено через 1 минуту и 54 секунды
Цитата(gta4kv @  25.10.2012,  21:14 Найти цитируемый пост)
Особенно контакт, кстати, страницы открываются - моментально. Чем фейсбук не может похвастаться. 
кстати, поставить супер сервера (т.е. железо) это ещё не говорит что сам движок шустрый

Добавлено через 6 минут и 10 секунд
ладно, спор тупиковый ;) Лучше класс посмотри.. 

Если нужны примеры как использовать класс, то могу выложить...

Кстати, я ещё ещё сделал возможность кэшировать результаты, правда отдельным классом, но в качестве эксперимента могу отдельным методом в этот подцепить

Это сообщение отредактировал(а) Gold Dragon - 25.10.2012, 20:18


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


Эксперт
****


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

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



Цитата(gta4kv @  25.10.2012,  20:14 Найти цитируемый пост)
Особенно контакт, кстати, страницы открываются - моментально. Чем фейсбук не может похвастаться.

Смешно...
Я бы даже сказал обхохочешься.
Что вы знаете о топологии интернета и инфраструктуре контакта и фейсбука?



Gold Dragon, 
Код

  public function select($query)
    {
        $this->returnMethod = '_mysqliFetchAssoc';
        $arguments = func_get_args();
        return call_user_func_array(array($this, 's_query'), $arguments);
    }


Объясни логику этого метода?
Вот почему явно не получить параметры в виде массива?
Почему, опять же явно, не передать их напрямую в s_query?



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
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   Вверх
Gold Dragon
Дата 30.10.2012, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



ksnk, а вот впихнуть кэширование в инициализацию - мысль очень даже интересная. Можно что угодно докручивать кстати. Вот только ...

Цитата(ksnk @  30.10.2012,  08:45 Найти цитируемый пост)
и  макры типа ?d, ?#, ?a . 
да, идея интересная, но с другой стороны, а не излишняя?

Цитата(ksnk @  30.10.2012,  10:12 Найти цитируемый пост)
Придумалось, что новый огород городить смысла нет, можно воспользоваться "шаблонными" идеями.
вникал, вникал, вникнул.. по моему перебор кажется smile усложняешь

Цитата(ksnk @  30.10.2012,  14:36 Найти цитируемый пост)
Писано за пару часов, так что не обессудьте. Но вдруг кого заинтересует...
Точно за пару??? Час сижу и не могу мыси собрать во едино... smile наверное вечер... Попробую завтра ещё осмыслить.. а может просто реальных примеров не хватает



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


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


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

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



Цитата(Gold Dragon @  30.10.2012,  18:38 Найти цитируемый пост)
Точно за пару??? Час сижу и не могу мыси собрать во едино...

30.10.2012, 09:12 - первый пост, начало мысли, а в 30.10.2012, 13:36 уже проект на гитхабе. Не пара, конечно, но все равно довольно быстро.  Ну и допиливал понемногу  в течении дня.

Сейчас, кстати, он сравнивается с pdo и не особенно значительно проигрывает в скорости. По большому счету - можно пренебречь...
А в удобстве, imho, будет превосходить.
 
Цитата(Gold Dragon @  30.10.2012,  18:38 Найти цитируемый пост)
а может просто реальных примеров не хватает

Там в test/spl_templaterTest.php есть немножко примеров традиционных запросов. Это части phpUnit, но понять что и как исользуется - можно.
Код

        $func = $sql->parse('SELECT name FROM tbl WHERE id IN({{?|join(\',\')}})');
        $this->assertEquals("SELECT name FROM tbl WHERE id IN(1,101,303)", $func(
            array(1, 101, 303)));


Код

$sql->setval('prefix','mixnfix') ;
        $func = $sql->parse('SELECT * FROM {{prefix}}_user LIMIT 10 ');
        $this->assertEquals("SELECT * FROM mixnfix_user LIMIT 10 ", $func(
            array('one' => 'one_value', 'two' => 'two_value')));


Код

$func = $sql->parse('insert into xxx set {{?|pair}} ;');
        $this->assertEquals("insert into xxx set `one`=\"one_value\",`two`=\"two_value\" ;", $func(
            array('one' => 'one_value', 'two' => 'two_value')));


Код

$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')));


Код

$func = $sql->parse('select * from index where {{?|int}}<`field`;');

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



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


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


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

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



ты фанат шаблонов smile и чувствую вошёл в азарт.... сегодня уже не способен осознать.  Завтра резюмирую свой класс и выкладываю на GIT... и буду осознавать...


ksnk, а не получится так что к твоему творчеству придётся справочник писать? Ты практически новый язык придумал


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


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


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

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



Цитата(Gold Dragon @  30.10.2012,  21:35 Найти цитируемый пост)
Ты практически новый язык придумал 

Синтаксис от Твига. Точнее от Django-template. Так что если есть опыт использования таких темплейтов - нет ничего сложного, просто пару новых слов запомнить ;) Несколько непривычно для twig'а используется знак вопросика, но это остаточек от традиционного sql-плейсхолдинга, вроде должно быть относительно привычно.
Вот насчет условных операторов сложнее, если их использовать, то оттранслировать это с помощью только строковых операций уже не удастся, получится тяжелее и дольше по времени трансляции. Хотя IF'ы, в принципе, не помешали бы. Да и циклам нашлось бы применение для монтажа простыней из insert values... Впрочем, обойдусь, пока. ;)

Пока я попробую наладить и потестировать систему перехвата ошибок трансляции, она там пока просто никакая.

А вообще-то получилось забавно, и вроде, вполне работоспособно...  smile 


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


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


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

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



кстати, по ходу... не могу отловить исключение при создании объекта 
Код

$this->db_resource = new mysqli(
          _config('db_host'), 
          _config('db_user'), 
          _config('db_password'), 
          _config('db_name'), 
          _config('db_port'), 
          _config('db_socket')
);


знаний не хватает.  Вылетает варнинг по типу
Цитата

...mysqli::mysqli(): (HY000/145)......


А нужно чтобы всё грамотно было типа так
Код

throw new Exception(_EXC_ERROR_CREATING_MYSQLI);


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


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


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


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

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



А что перехватывать-то надо? Неправильные параметры в _config? или проблемы с созданием объекта mysqli? Вроде в php.net про это какие-то примеры есть. не подойдет?


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


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


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

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



Цитата(ksnk @  31.10.2012,  12:26 Найти цитируемый пост)
А что перехватывать-то надо? Неправильные параметры в _config? 
Ну да, если ошибка в пароле, пользователе, названии базы....

Т.е. не чтобы ошибка вылетала, а именно исключение


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


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


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

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



Код

<?php

class foo_mysqli extends mysqli {
    public function __construct($host, $user, $pass, $db) {
        parent::__construct($host, $user, $pass, $db);

        if (mysqli_connect_error()) {
            die('Connect Error (' . mysqli_connect_errno() . ') '
                    . mysqli_connect_error());
        }
    }
}

$db = new foo_mysqli('localhost', 'my_user', 'my_password', 'my_db');

echo 'Success... ' . $db->host_info . "\n";

$db->close();
?>

вот, довольно кошерный пример по моей ссылке. Там еще есть разной степени применимости.


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


Эксперт
****


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

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



Цитата(Gold Dragon @  31.10.2012,  07:31 Найти цитируемый пост)
А нужно чтобы всё грамотно было типа так
throw new Exception(_EXC_ERROR_CREATING_MYSQLI);

Код

mysqli_report (MYSQLI_REPORT_STRICT);
try {
  $this->db_resource = new mysqli(
          _config('db_host'), 
          _config('db_user'), 
          _config('db_password'), 
          _config('db_name'), 
          _config('db_port'), 
          _config('db_socket')
  );
} catch (mysqli_sql_exception $ex) {
  echo $ex->getMessage();
}

PM MAIL   Вверх
Gold Dragon
Дата 31.10.2012, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



baldina, а разве несколько раз можно объявлять подобную конструкцию? Просто у меня это класс  уже в этой констукции.... т.е. в index.php

Добавлено через 4 минуты и 34 секунды
ksnk, что-то как-то не то... В том то и дело что всё остальное отлично ловит исключения, и даже после new, но вот если ошибка в new, то выдаёт и ошибку и исключение на connect_error друг за другом

Это сообщение отредактировал(а) Gold Dragon - 31.10.2012, 20:34


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


Эксперт
****


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

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



Цитата(Gold Dragon @  31.10.2012,  20:34 Найти цитируемый пост)
а разве несколько раз можно объявлять подобную конструкцию?

какую именно?

Добавлено через 3 минуты и 40 секунд
если try...catch, то сколько угодно. поймается исключение там, где первый блок catch соответствует по типу.
но вообще стратегию ловли исключений продумывать надо, это же часть архитектуры.
исключения хороши там, где требуется обработать ошибку не на том уровне, где она возникла, плюс управлять обработкой: не нужно тащить вверх коды ошибок, не нужно лишних if

Добавлено через 7 минут и 33 секунды
вообще, как я понял, проблема была не в обработке исключений, а что они не генерятся. решение - mysqli_report (MYSQLI_REPORT_STRICT);
PM MAIL   Вверх
Gold Dragon
Дата 5.11.2012, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Так, всё закачал на GitHub
https://github.com/GoDr/GDLDatabase

Попытался всё здраво описать... (wiki пока не создавал)

в файле index.php приведены все примеры

Вот описание всех методов


Дамп тестовой таблицы

Код

CREATE DATABASE IF NOT EXISTS `dbase`;
USE `dbase`;

CREATE TABLE IF NOT EXISTS `table` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `name` varchar(50) DEFAULT '0',
    `date` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

INSERT INTO `table` (`id`, `name`, `date`) VALUES
    (1, 'Иван', '2012-11-04'),
    (2, 'Степан', '2012-11-06'),
    (3, 'Пётр', '2012-11-07');


select() - Вывод всех значений
Цитата


Пример:
$result = GDLDatabase::Init()->select("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", 1, 'Степан');
или
$result = GDLDatabase::Init()->select("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", array(1, 'Степан'));

Результат:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Иван
            [date] => 2012-11-04
        )

    [1] => Array
        (
            [id] => 2
            [name] => Степан
            [date] => 2012-11-06
        )

)


selectRow() - Вывод первой строки
Цитата


Пример:
$result = GDLDatabase::Init()->selectRow("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", 1, 'Степан');
или
$result = GDLDatabase::Init()->selectRow("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", array(1, 'Степан'));

Результат:

Array
(
    [id] => 1
    [name] => Иван
    [date] => 2012-11-04
)


selectCol() - Вывод первого столбца запроса
Цитата


Пример:
$result = GDLDatabase::Init()->selectCol("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", 1, 'Степан');
или
$result = GDLDatabase::Init()->selectCol("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", array(1, 'Степан'));

Результат:

Array
(
    [0] => 1
    [1] => 2
)


selectCell() - Вывод первой ячейки первого столбца запроса
Цитата


Пример:
$result = GDLDatabase::Init()->selectCell("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", 1, 'Степан');
или
$result = GDLDatabase::Init()->selectCell("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", array(1, 'Степан'));

Результат:

1


update() - Обновление записи
Цитата


Пример:
$result = GDLDatabase::Init()->update("UPDATE `#__table` SET `date`=? WHERE `id`=? AND `name`=?", array('2012-11-07', 3, 'Пётр'));
или
$result = GDLDatabase::Init()->update("UPDATE `#__table` SET `date`=? WHERE `id`=? AND `name`=?", '2012-11-07', 3, 'Пётр');


insert() - Вставка записи
Цитата


Пример:
$result = GDLDatabase::Init()->insert("INSERT INTO `#__table` (`id`, `name`, `date`) VALUES (?, ?, ?);", array(4, 'Антон', '2012-11-07'));
или
$result = GDLDatabase::Init()->insert("INSERT INTO `#__table` (`id`, `name`, `date`) VALUES (?, ?, ?);", 4, 'Антон', '2012-11-07');


replace() - Перезапись записи
Цитата


Пример:
$result = GDLDatabase::Init()->replace("REPLAСE INTO `#__table` (`id`, `name`, `date`) VALUES (?, ?, ?);", array(4, 'Антон', '2012-11-07'));
или
$result = GDLDatabase::Init()->replace("REPLAСE INTO `#__table` (`id`, `name`, `date`) VALUES (?, ?, ?);", 4, 'Антон', '2012-11-07');


delete() - Удаление записи
Цитата


Пример:
$result = GDLDatabase::Init()->delete("DELETE FROM `#__table` WHERE `id`=? AND `name`=?", array(4, 'Антон'));
или
$result = GDLDatabase::Init()->delete("DELETE FROM `#__table` WHERE `id`=? AND `name`=?", 4, 'Антон');


getCacheSql() - Вывод всех значений (метод selectRow) при использовании кэширования
Цитата


Пример:
$result = GDLDatabase::Init()->getCacheSql("selectRow", "SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", 1, 'Степан');
или
$result = GDLDatabase::Init()->getCacheSql("selectRow", "SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", array(1, 'Степан'));

Результат:

Array
(
    [id] => 1
    [name] => Иван
    [date] => 2012-11-04
)


Транзакция
Цитата

Использование транзакции:

$db=GDLDatabase::Init();
$db->transactionStart();
$db->insert('INSERT INTO `#__table` set testval =?',20);
$db->insert('INSERT INTO `#__table` set testval =?',10);
$db->insert('INSERT INTO `#__table` set testval =?',123);
$db->transactionCommit();

Откат текущей транзакции:

$db=GDLDatabase::Init();
$db->transactionStart();
$db->insert('INSERT INTO `#__table` set testval =?',20);
$db->insert('INSERT INTO `#__table` set testval =?',10);
$db->insert('INSERT INTO `#__table` set testval =?',123);
$db->transactionRollBack();
$db->transactionCommit();


simpleQuery() - Простое выполнение запроса
Цитата


Пример:
$result = GDLDatabase::Init()->simpleQuery("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`=? OR `name`=?", 1, 'Степан');

Результат:

mysqli_result Object
(
    [current_field] => 0
    [field_count] => 3
    [lengths] => 
    [num_rows] => 2
    [type] => 0
)


getQueryInfo() - Получение дополнительной информации о последнем запросе
Цитата


Пример:
GDLDatabase::Init()->insert("INSERT INTO `#__table` (`name`, `date`) VALUES (?, ?);", array('Елена', '2012-10-07'));
$result1 = GDLDatabase::Init()->getQueryInfo();

GDLDatabase::Init()->select("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id`>?, 6);
$result2 = GDLDatabase::Init()->getQueryInfo();

Результат:

Array
(
    [affected_rows] => 1
    [insert_id] => 15
    [num_rows] => 0
    [field_count] => 0
    [sqlstate] => 00000
)
Array
(
    [affected_rows] => 3
    [insert_id] => 0
    [num_rows] => 3
    [field_count] => 3
    [sqlstate] => 00000
)


getError() - Описание ошибки последнего запроса
Цитата


Пример:
GDLDatabase::Init()->select("SELECT `id`, `names`, `date` FROM `#__table` WHERE `id`>?", 6);
$result = GDLDatabase::Init()->getError();

Результат:

Unknown column 'names' in 'field list'


getErrno() - Описание номера ошибки последнего запроса
Цитата


Пример:
GDLDatabase::Init()->select("SELECT `id`, `names`, `date` FROM `#__table` WHERE `id`>?", 6);
$result = GDLDatabase::Init()->getErrno();

Результат:

1054


showProfiles() - Показать профилирование запросов
Цитата


Пример:
GDLDatabase::Init()->select("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id` >= ?", 3);
GDLDatabase::Init()->select("SELECT `id`, `name`, `date` FROM `#__table` WHERE `id` < ?", 3);
$result = GDLDatabase::Init()->showProfiles();

Результат:

Array
(
    [0] => Array
        (
            [0] => 12
            [1] => 0.00015675
            [2] => SELECT `id`, `name`, `date` FROM `table` WHERE `id` >= ?
        )

    [1] => Array
        (
            [0] => 13
            [1] => 0.00013650
            [2] => SELECT `id`, `name`, `date` FROM `table` WHERE `id` < ?
        )

)


getObject() - Возвращает обьект класса mysqli для нереализованных операций
Цитата


Пример:
$result = GDLDatabase::Init()->getObject();

Результат:

mysqli Object
(
    [affected_rows] => 13
    [client_info] => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $
    [client_version] => 50010
    [connect_errno] => 0
    [connect_error] => 
    [errno] => 0
    [error] => 
    [error_list] => Array
        (
        )

    [field_count] => 3
    [host_info] => localhost via TCP/IP
    [info] => 
    [insert_id] => 0
    [server_info] => 5.1.65-community-log
    [server_version] => 50165
    [stat] => Uptime: 27891  Threads: 1  Questions: 2722  Slow queries: 0  Opens: 148  Flush tables: 1  Open tables: 1  Queries per second avg: 0.97
    [sqlstate] => 00000
    [protocol_version] => 10
    [thread_id] => 187
    [warning_count] => 0
)



Добавлено через 6 минут и 19 секунд
Жду обсуждений по этому классу... 

Это сообщение отредактировал(а) Gold Dragon - 5.11.2012, 16:23


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


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


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

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



Чуть изменил метод getQueryInfo(). Теперь может выводит как ассоциативный массив с дополнительной информацией, так и значение конкретного ключа если передать имя ключа

Например:
Код

$id = GDLDatabase::Init()->getQueryInfo('insert_id');



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


Эксперт
****


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

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





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


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


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

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



нет конечно. И я как-то говорил что мне не нужен супер-монстр, а нужен маленький монстрёнок  smile 


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


Эксперт
****


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

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



ну если для тренировки только, то наверно полезно.
жаль, поторопился, мог бы сэкономить время, если бы лучше продумал архитектуру: сплошной copy-paste
и интерфейс получился не слишком интуитивный, зачем мне вызывать специальную функцию delete или update, если я все-равно должен этот delete  или update продублировать на sql?
тем более что реализовано оно, мягко говоря, не разнообразно
Код

    /**
     * Выполнение REPLACE
     *
     * @param  string $query - строка запроса
     *
     * @return bool
     */
    public function replace($query)
    {
        $arguments = func_get_args();

        return call_user_func_array(array($this, 'i_query'), $arguments);
    }

    /**
     * Выполнение DELETE
     *
     * @param  string $query - строка запроса
     *
     * @return bool
     */
    public function delete($query)
    {
        $arguments = func_get_args();

        return call_user_func_array(array($this, 'i_query'), $arguments);
    }

 smile 
PM MAIL   Вверх
Gold Dragon
Дата 12.11.2012, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



baldina, замечая в тему и уже были озвучены. Функции разделены, т.к. в ближайшее время исправлю ситуацию с
Цитата(baldina @  12.11.2012,  09:40 Найти цитируемый пост)
зачем мне вызывать специальную функцию delete или update, если я все-равно должен этот delete  или update продублировать на sql?



То что код получился не слишком интуитивный, согласен. Сейчас конечно мне он понятен, но раньше пришлось по ломать голову. Я ранее писал что за основы и идею взял чужой код, который был работоспособен и отвечал моим "хочу". Но весь код построен на ссылках, я а это очень не люблю..Начал исправлять - полезли ошибки. Т.ч. пока оставил так. 

В конечно итоге конечно все постараюсь переделать. Для конечного пользователя это никоем образом не скажется

Сейчас задача избавится от лишнего.. т.е. если insert и ему подобные, то в sql-запросе этого не должно быть


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


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


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

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



Цитата(baldina @  12.11.2012,  08:40 Найти цитируемый пост)
 зачем мне вызывать специальную функцию delete или update, если я все-равно должен этот delete  или update продублировать на sql?

Хотя бы по тому, что обработка результатов запроса разная. Для инсерта нужно выдать last_insert_id, а для Delete - количество удаленных строк. Вообще - довольно полезно иметь selectCell, selectRow, insert, delete, update, и т.д. для разных вариантов возвращаемых данных. 


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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 1
Всего: 60



Я как то месяца 4 назад страдал такой же ерундой только в стиле PDO страдал чисто для себя и иза того что нужно было узнать предварительный результат сформулированного запроса в PDO с этим беда.

Мне вот с кешем не понравилось как у вас сделано я сделал у себя просто вызов метода до выполнения prepare и execute  query просто как метод
Цель метода указать использовать каширование
Код

bd::make()->cache()->prepare($sql)->execute(array(':id'=>'12') );


В данном случаи это просто установка флага в классе и инициализация через конфиг адаптера под каширование 
Код

public function cache($flag = true){
    $this->cache = (bool)$flag;
    if(is_null( $this->cacheAdapter){
       $this->cacheAdapter = cache::make(  confing::get('cache') );
    }
   return $this;
}


В методах execute query реализована обычная проверка на наличие включения включенного кеша.

В методах feach() реализован схожий функционал PDO получения результата кеша как будто из базы работаем
feachAll работает по прицепу отдать все

В данный момент пишу обучалку ИИ для этого дела что бы медленные запросы система сама кашировала.
Спасибо knsk за идею с шаблонными запросами
Я ток одном месте их использовал при наличии в название таблицы {{table}} подставлять прификс таблицы ( понравилась мне эта фишка в Yii ).

Чуть не забыл почему я выбрал PDO:
Гибче, абстракнее, приятный синтаксис написания,  по скорости: проигрывает капельку mysqli (где то видел тест но сам не проверял).
А именованные плэйсхолдеры повышает наглядность и эффективность использования в отличии от mysqli где просто "?" где иногда просто заставляет считать вопросики...
Хоть сам PDO и поддерживает плэйсхолдеры в стиле "?" (честно не пользовался)....

Планов у меня много и идей хоть отбавляй ( вот времени всегда мало)


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
baldina
Дата 17.11.2012, 21:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(ksnk @  12.11.2012,  11:21 Найти цитируемый пост)
Хотя бы по тому, что обработка результатов запроса разная.

неубедительно. вопрос был, не зачем что-то делать, а зачем что-то делать дважды.

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


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


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

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



Цитата(baldina @  17.11.2012,  21:39 Найти цитируемый пост)
а зачем что-то делать дважды.

В смысле?
писать 
Код

...->select('Select ...

Так?


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


Эксперт
****


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

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



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


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


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

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



baldina, На мой взгляд - первое из этих слов ->select необходимо, так как оно определяет формат ожидаемого мной оответа. Второе, если эстетические чувства протестуют - можно подставлять внутри функции. Мои эстетические чувства не протестуют. А вот подстановка в некоторых(не всех) функциях - странное и не совсем логичное действие.

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


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


Эксперт
****


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

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



можно сделать много чего, в т.ч. красиво и эффективно.
я всего лишь указал на сей недостаток (и Gold Dragon согласился)
PM MAIL   Вверх
ksnk
Дата 19.11.2012, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(baldina @  19.11.2012,  11:31 Найти цитируемый пост)
можно сделать много чего, в т.ч. красиво и эффективно.
я всего лишь указал на сей недостаток (и Gold Dragon согласился) 

Ok! Согласен. Пусть решает дракон  smile 


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


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


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

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



Цитата(baldina @  19.11.2012,  12:31 Найти цитируемый пост)
можно сделать много чего, в т.ч. красиво и эффективно.
я всего лишь указал на сей недостаток (и Gold Dragon согласился) 
Согласился, но кажется по горячился...

Тут я поразмышлял малость и прикинул... Допустим я всё упрощаю и удаляю "повторы" в этом
...->insert("INSERT...
Тогда мне нужно передавать не строкой запроса, а переменными

Возьмём запрос для вставки.
Код

->insert("INSERT INTO `#__table` (`id`, `name`, `date`) VALUES (?, ?, ?);", array(4, 'Антон', '2012-11-07'))

Сейчас тут
1 - Запрос
2 - массив с переменными

Если мы хотим избавится от "избыточности", то нам нужно передавать
1 - имя таблицы
2 - массив с именами полей
3 - массив с переменными
и вызов будет примерно такой
Код

->insetr('#__table', array(`id`, `name`, `date`), array(4, 'Антон', '2012-11-07'))


Теперь если взять "обновление" и сделать по подобию
Код

->update("UPDATE `#__table` SET `date`=? WHERE `id`=? AND `name`=?", array('2012-11-07', 3, 'Пётр'))

То нам нужно передавать 
1 - имя таблицы
2 - массив с именами полей
3 - массив с переменными
4 - массив с именами полей в условии
5 - массив с переменными условия
И получается что-то типа такого
Код

->update('#__table', array('date'), array('2012-11-07'), array('id','name'), array(3, 'Пётр'))


Вот тут то и вопрос: "А не слишком это всё усложняет и загромождает систему?"

Добавлено через 2 минуты и 41 секунду
и это если запросы простые без вложенности

Это сообщение отредактировал(а) Gold Dragon - 19.11.2012, 14:33


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


Эксперт
****


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

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



Цитата(Gold Dragon @  19.11.2012,  14:32 Найти цитируемый пост)
Вот тут то и вопрос: "А не слишком это всё усложняет и загромождает систему?"

По-моему поздно пить боржоми smile


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


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


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

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



Цитата(Fortop @  19.11.2012,  15:55 Найти цитируемый пост)
По-моему поздно пить боржоми 
адсолютно не поздно.. В крайнем случае можно сделать дополнительные методы



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


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


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

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



Тут обсуждается построитель запросов? Как показывает практика, строить достаточно адекватно удается только простые запросы. Всякая сложность потребует неадекватного усложнения построителя. Можно посмотреть на сложность activeRecord  в Yii, например.

Тонкость в том,что вся эта сложность нужна ТОЛЬКО для генерации строки SQL. Зачем ее генерировать, если можно просто ее явно  записать? 

Строка SQL может зависеть от конкретного sql-транспорта и незначительно меняться в зависимости от него. Почему бы не пойти по пути "многоязыковых" приложений и не сделать словарь SQL запросов, если действительно нужно работать в нескольких местах? Запросов в приложении не может быть уж очень много, так что словарь вполне реален.



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


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


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

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



ksnk, не совсем уловил мысль.. На примере покажи


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


Эксперт
****


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

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



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

Код

$query->
  update('table')->
  values (['field1'=>'value1', 'field2'=>'value2'])->
  where(['id'=>eq($x), 'value1'=>less($v1)]);

$affected_rows = $query->exec();

$query->
  select('table1')->
  fields(['table1.field1'=>'field1','table2.field2'=>'field2'])->
  inner_join('table2')->
  on('table1.id'=>eq('table2.t_id')->
  where(['id'=>less($id)]);

$iterator = $query->exec();
foreach ($iterator as $row) {...}


есть например такая библиотека http://www.notorm.com/, поглядите исходники.

Это сообщение отредактировал(а) baldina - 19.11.2012, 16:59
PM MAIL   Вверх
ksnk
Дата 19.11.2012, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Gold Dragon @  19.11.2012,  16:36 Найти цитируемый пост)
ksnk, не совсем уловил мысль.. На примере покажи

Про что? Про "многоязыковые" словари?

Код

// mysql_vocabular.php
class sql_vocabular {
  public const sql=array(
    'sql_111'=>'select * from xxx;',
    'sql_112'=>'select * from yyy;',
    'sql_113'=>'select * from ?;',
   ...
  )
}




Код

$vocabular= 'mysql_vocabular '


...->select('sql_111',$args,...)

...

function select ($sql){
   $query=sql_vocabular::$sql[$sql];
...
}



Вот, что-то на коленке накропалось ;)


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


Эксперт
****


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

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



а вообще, мне кажется, нужно начинать с целей: чего хочется достичь. Gold Dragon хотел маленькую библиотеку, удобную для него лично, но результат стал естественным образом разрастаться - по мере понимания проблем и способов решения.

видимо можно было прийти к пониманию несколько иным путем - сформулировав требуемый интерфейс к бд. а для начала - познакомиться с тем, что есть. вот например: http://sql-cross-queries.freexit.eu/

не удивлюсь, если в результате ТС поймет концепцию некоторых ранее виданных библиотек, что-то ему понравится, и он бросит свой велосипед.
хотя велосипеды изобретать полезно: начинаешь понимать как оно работает

PM MAIL   Вверх
Fortop
Дата 19.11.2012, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



ksnk, это же самое можно реализовать без словарей

Код

Model->fetchLastTenDayProducts()



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


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


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

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



ksnk, очень сложная система получается, да и не нужная на мой взгляд... Нужно как минимум ещё и "словари" знать smile

Цитата(baldina @  19.11.2012,  17:59 Найти цитируемый пост)
 внутри за счет полиморфизма и пр. все будет выглядеть коротко и ясно, а результат для использования - что-то типа такого:
интересный вариант. Но как ты заметил, мне нужна маленькая и простая библиотека... Хотя действительно интересный подход, ещё не встречал такого... 



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


 




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


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

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