ФорумПрограммированиеPHP для идиотов → Класс для работы с БД

Класс для работы с БД

  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 15 августа 2009 г. 13:51, спустя 19 минут 58 секунд


    Неа, справочная литература так говорит.
    пиздит она значит
    Сапожник без сапог
  • Batler

    Сообщения: 142 Репутация: N Группа: Кто попало

    Spritz 15 августа 2009 г. 14:27, спустя 35 минут 59 секунд

    Столбец типа инт. Ты передаешь строку в которой содержится число. Надо преобразовывать строку в число. Иначе как ее записать в столбец типа инт?
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 15 августа 2009 г. 14:37, спустя 9 минут 20 секунд


    Столбец типа инт. Ты передаешь строку в которой содержится число. Надо преобразовывать строку в число. Иначе как ее записать в столбец типа инт?
    как ты дуаешь, какова сложность такого преобразования?
    Сапожник без сапог
  • Batler

    Сообщения: 142 Репутация: N Группа: Кто попало

    Spritz 15 августа 2009 г. 15:13, спустя 35 минут 59 секунд

    Наверное O(N) =)
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 15 августа 2009 г. 15:21, спустя 8 минут 11 секунд


    Наверное O(N) =)
    0
    Сапожник без сапог
  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 17 августа 2009 г. 20:28, спустя 2 дня 5 часов 7 минут

    Всегда было интересно … как вы отлаживаете свои запросы типа?
    SELECT #0 FROM #1 WHERE `user`.`id` = &2 AND
    `user`.`name` = $3

    Не встречал я менеджеров БД, которые это принимают.

    Но почти все менеджеры (все взрослые) принимают вид:
    select fld from tbl where id between :id_min and :id_max

    Почему эту нотацию не принимаете в работу?
    Ведь сразу же исчезает, как понятие, "sql-инъекция".

    "$ - реал_эскаип стринг.  … $$ - ОТМЕНА реал_эскаип стринг."
    Сразу скажу: "Я абсолютно ничего против не имею Вашего класса. Ваш класс - лишь как пример множества других".

    Скажите, люди, для чего собирать SQL код из кусков строк.
    Встраивать в него юзерские данные, потом заморачиваться "обезопасить, заэскейпить и т.д."
    Написать 30 запросов идеальных, в 31 пропустить реал_ескейп и выставить дырявый продукт?

    Почему не свести запросы к виду обычной строки + параметры. Тем самым свести вопрос безопасности в одну функцию - выполнения запроса. (если расширение вашей СУБД не поддерживает работу с параметрами)


  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 17 августа 2009 г. 22:11, спустя 1 час 42 минуты 24 секунды

    Всегда было интересно … как вы отлаживаете свои запросы типа?
    всегда есть методы для дампа и дебага
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Batler

    Сообщения: 142 Репутация: N Группа: Кто попало

    Spritz 18 августа 2009 г. 9:11, спустя 11 часов 3 секунды


    Всегда было интересно … как вы отлаживаете свои запросы типа?
    Не встречал я менеджеров БД, которые это принимают.

    Как всегда, по старинке $db->debug=1 + можно собирать в лог.
    И еще можно воспользоваться одним из дебаггеров php, чтобы смотреть какие запросы уходят в БД.


    Скажите, люди, для чего собирать SQL код из кусков строк.
    Встраивать в него юзерские данные, потом заморачиваться "обезопасить, заэскейпить и т.д."
    Написать 30 запросов идеальных, в 31 пропустить реал_ескейп и выставить дырявый продукт?

    Если использовать единый интерфейс к базе данных, то это как то входит в привычку и ошибок нет. К тому же каждый маркер ($,#,&) действует по своему, и если даже перепутаешь максимум что случится - исключение. Минимум - будут не те данные в столбцах, и это заметно. Не согласен с вами, что SQL собирается из кусков строк. Строка берется исходная, а вместо спецсимволов вставляются отформатированные, безопасные данные. И реал эскеип выполняется автоматически…


    Почему не свести запросы к виду обычной строки + параметры. Тем самым свести вопрос безопасности в одну функцию - выполнения запроса. (если расширение вашей СУБД не поддерживает работу с параметрами)

    Этой идеи я не понял, к сожалению. Не могли бы вы подробнее объяснить?

    P.S.
    SELECT fld FROM tbl WHERE id BETWEEN :id_min AND :id_max
    А это по вашему обычная строка? По-моему это замена одного синтаксиса другим…
  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 18 августа 2009 г. 12:56, спустя 3 часа 44 минуты 40 секунд

    Эмоции взяли верх - я не о Вашей конкретно реализации говорил - простите.
    Под строка + параметры я имел ввиду именно "SELECT fld FROM tbl WHERE id BETWEEN :id_min AND :id_max"

    Ваш класс - один из вариантов "строка + параметры".

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

    "чтобы смотреть какие запросы уходят в БД". Такой подход, как по мне, удобен для запросов "две таблички три условия".

    Представляю. в какой кошмарик превратится такая отладка запроса в несколько десятков строк с кучкой вложенных и/или подзапросов.

    А план посмотреть запроса? А как он в индексы ложится? А перепробовать несколько подобных и сравнить продуктивность?

    Для этого существую менеджеры БД и подобное ПО. Создавая же "непереносимые" запросы прямо в коде, мы отлучаем себя от этих удобств и довольствуемся $db->debug = 1 и разгребанием логов.

    Это не наезд "вы все дураки", а побуждение "попробуйте иначе - Вам, скорее всего, понравится." :-)
  • Batler

    Сообщения: 142 Репутация: N Группа: Кто попало

    Spritz 18 августа 2009 г. 13:36, спустя 40 минут 9 секунд


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

    Мы народ темный, слаще редьки ничего не ели :)
    Работаем по старинке. Честно говоря не видел этих менеджеров. Если надо использую mysql в консоле.
    Можно о них подробнее? Какие вы используете?
    Ну и интересно было бы знать как вы обезопасиваете свои запросы…


    Представляю. в какой кошмарик превратится такая отладка запроса в несколько десятков строк с кучкой вложенных и/или подзапросов.
    А план посмотреть запроса? А как он в индексы ложится? А перепробовать несколько подобных и сравнить продуктивность?
    Для этого существую менеджеры БД и подобное ПО.

    Не далее чем 2 дня назад занимался как раз этим. По моему даже где-то запрос остался…
    Вот:

    $select = 'EXPLAIN SELECT `hotels`.`id`, `hotels`.`name`, `hotels`.`region`, `hotels`.`type` FROM `hotels`
    USE KEY (nrt) WHERE ROW(`hotels`.`name`, `hotels`.`region`, `hotels`.`type`) IN (';
    $db = DB::getDB();
    $db->query('USE `arcd`');
    foreach ($unique as $k => &$v) {
    $mass = explode('|', $v);
    $select .= $db->prepare('($0, $1, $2), ', array($mass[0], $mass[1], $mass[2]));
    }
    $select = substr($select, 0, strlen($select)-2) . ')';
    $hotels_from_db = $db->query($select, null, 'assoc');
    print_r($hotels_from_db);

    По поводу оценки времени работы соглашусь. Я не нашел как выдернуть из MySQL время выполнения запроса (а так хотелось).
    Незнаю как остальные, я сперва хорошенько продумываю структуру базы и примерно какие запросы я буду использовать. Далее я пишу пробные запросы (работают или нет) без использования плейсхолдеров (обычный SQL), убедившись, что запрос тот, который меня интересует я немного изменяю его.


    Создавая же "непереносимые" запросы прямо в коде, мы отлучаем себя от этих удобств и довольствуемся $db->debug = 1 и разгребанием логов.

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

  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 18 августа 2009 г. 16:28, спустя 2 часа 52 минуты 1 секунду

    Менеджеры.
    Не скажу точно по MySQL (у меня с ней свидания эпизодические) для Firebird всем известный IBExpert.
    По mySQL один красивый попался. И процедуры писать давал культурно и, даже, (чем меня и очаровал) имел свой PHP-прокси для работы с удаленной БД. На сайт закидываете скриптик .. и соединяетесь с БД хостера, которая, как правило, не позволяет удаленных коннектов.

    Не надо вспоминать про phpmyadmin :) - удобная штука, не спорю. Но другие менеджеры могут побольше.

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

    ДА! Именно это я хотел сказать. Использовать стандартизированный "костыль" (из SQL/92) и пользоваться благами стандартизации.

    http://www.citforum.ru/database/sqlbook/sqlbook_12.shtml
    Имена параметров в SQL/89 не имели префикса в виде двоеточия. SQL/92 требует наличия такого префикса.


    О защите.
    Используя параметры в запросах отпадает вообще проблема запроса безопасности - никогда часть параметра не выполнится как часть запроса.
    Но эти слова правдивы только, если сам клиент использует параметры, а не внутри себя собирает из кусков запрос. В таком случае, конечно, нужно "обезопасить" текст параметров.

    ___
    P.S.
    Кажись, вот это тот самый менеджер … http://sqlmanager.net/products/mysql/manager
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 18 августа 2009 г. 17:02, спустя 34 минуты 37 секунд


    и соединяетесь с БД хостера, которая, как правило, не позволяет удаленных коннектов.
    Если есть шелл, делаешь тунель и вуаля …
    Если нету шелла, платишь хостеру лишние 100 руб за нормальный тарифный план и он есть ))))
  • Batler

    Сообщения: 142 Репутация: N Группа: Кто попало

    Spritz 18 августа 2009 г. 17:13, спустя 10 минут 19 секунд

    Я вот не уверен, что MySQL поддерживает SQL стандарт в полной мере. Надо почитать в карманном справочнике. Знаю что mysqli поддерживает т.н. prepared statement. Подробнее про параметры можно?
  • AndryG

    Сообщения: 237 Репутация: N Группа: Адекваты

    Spritz 19 августа 2009 г. 14:25, спустя 21 час 12 минут 41 секунду

    "обычое" выполнение запроса:
     - составили код запроса
     - добавили в этот код "опасные" данные - получили "текст запроса"
       (текст = код_запроса + данные.  Под данными я имею ввиду изменяемый/опасный текст запроса)
     - выполняем текст запроса
    Параметры и prepared statement:
     - составили код запроса. На место данных ставим :param_name (В php тоже не по человечески .. требует на место параметра ставить ?)
     - подготавливаем запрос (СУБД анализирует код запроса, составляет его план и т.д.) -  получаем подготовленный запрос
     - подг. запросу указываем наши данные как значения параметров и выполняем его

    Если выполняется много-много раз один и тот же запрос с разными данными(значениями параметров), то вариант с предварительной его подготовкой дает значительный прирост производительности, ибо СУБД не тратит время на парсинг запроса и его анализ, а сразу использует для выполнения подготовленный запрос.

    О безопасности. Какие бы вы данные не указали в значении параметра - они никак не могут повлиять на выполнение запроса, ибо сам запрос уже проанализирован СУБД и для него уже создан "сценарий выполнения". Все ваши инъекции отныне будут рассматриваться не как код запроса, а как значение параметра, над которым будет издеваться СУБД по уже известному ей сценарию.

    Во, блин, написал … точнее смотрите умные книги :-)
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 19 августа 2009 г. 14:36, спустя 10 минут 58 секунд

    AndryG, молодец!

    по теме
    1. редко надо вызывать более 1го запроса с разными данными.
    2. в пхп все не по человечески, но мы его любим
    3. инъекции не проходят и про mysql_real_escape_string так что если учесть (1.) я думаю что скорость будет одинаковая, может я неправ. переубедите
    4. больше коду - больше шанс на ошибку
    5. умные книги продают чтобы их покупали, а никак не чтобы по ним учились :)

    Спустя 5 сек.
    я не быдло.
    Сапожник без сапог

Пожалуйста, авторизуйтесь, чтобы написать комментарий!