За последние 24 часа нас посетили 57194 программиста и 1683 робота. Сейчас ищут 1250 программистов ...

Классы для работы с MySQL. За и против.

Тема в разделе "Прочие вопросы по PHP", создана пользователем Psih, 30 дек 2006.

  1. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    По поводу работы с MySQL, лично я пришел в итоге к одному простому решению.
    Для mysql - никаких классов - прямая работа с mysql_* - самое эффективное, гибкое и быстрое. Хороший программер как правило пишет SQL один раз и он работает если не меняеться структура базы ВСЕГДА, даже если данные заведомо ошибочны.
    Для mysqli я делаю наследование mysqli и переопределяю один единственный метод - query - вписываю туда дебагинг если он необходим и делаю вызов parent::query. В остальном опять же напрямую использую mysqli объект. И не надо никаких классов, они бесполезны и только жрут CPU и излишне нагружают своим кодом PHP.
     
  2. svk

    svk Активный пользователь

    С нами с:
    7 авг 2006
    Сообщения:
    506
    Симпатии:
    0
    Адрес:
    NetByNet
    а как же абстракция от БД?
     
  3. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    гыгы, повеселил :) пиши исчо!
    не надо путать принцип kiss с полным отказом от хелперов... попробуй поюзать мой класс - потом за ухи не оттянешь ;-)
    http://phorum.key.ru/viewtopic.php?p=463468#463468

    угу, а хороший заказчик никогда не просит расширить функционал :)
     
  4. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    извините, конечно... но это поделка на коленке.
     
  5. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    simpson, но она гораздо более удобная и наглядная, чем известные монстроклассы.
     
  6. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    нет гибкости составления SQL-запросов.
    банальные:
    Код (Text):
    1. SELECT * FROM table WHERE name IN ("a","b","c") LIMIT 10
    уже требуют составления ручками. полезность остального функционала отпадает при этом.

    а как насчет:
    Код (Text):
    1. INSERT INTO ... ON DUPLICATE KEY ...
    Код (Text):
    1. INSERT ... SELECT ...
    ?
     
  7. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    гибкости, как раз, выше крыши, ибо практически никаких ограничений.

    ес-сно ручками, любой более-менее сложный запрос полюбому составлять ручками. а что тебя смущает? боишься языка SQL?

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

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

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    нисколько.
    лишний и бесполезный код.
    так для чего тогда нужно автоматическое составление запроса, если все делается вручную?

    где оно, облегчение это?
     
  9. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    единственный автосоставитель запроса у меня - функция insert(), которая довольно удобна при работе с формами.

    поюзай функции mysql_* и мой класс - поймёшь.
     
  10. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    так я их и юзаю. напрямую. без всяких классов. а ваш мне и даром не нужен. =)
     
  11. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    simpson
    И везде, где требуется выборка из таблицы, пишешь связку mysql_query() ... mysql_fetch_xxx() ... mysql_free_result()? Каждый раз повторяя одно и то же?
     
  12. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    mysql_query написать ни чуть не сложнее, чем $db->query.
     
  13. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Это не ответ на мой вопрос ;) я говорю о том, что на каждую выборку тебе по сути приходится писать один и тот же "триндем" из трех стандартных функций PHP - одинаковый функционал, который много раз повторяется в твоем коде. Это если ты никак не проверяешь первый вызов на ошибку MySQL, в противном случае повторов будет больше. Ну хорошо. А как ты добавляешь данные в базу? Приведи простой пример добавления записи в таблицу, исходные данные допустим лежат в ассоциативном массиве $data.
     
  14. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    PHP:
    1. <?php
    2. function prepare($data) {
    3.    $parts = array();
    4.    foreach ($data as $field => $value) {
    5.       $parts[] = '`' . $field . '`="' . mysql_real_escape_string($value) . '"';
    6.    }
    7.    return implode(', ', $parts);
    8. }
    9.  
    10. $data = array('field1' => '123', 'field2' => '456', 'field3' => '789');
    11. $sql = 'INSERT INTO `table` SET ' . prepare($data);
    12. ?>
     
  15. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    угу, только не забывай, что тебе ещё и данные экранировать нужно, а при использовании второго варианта - это будет делаться автоматом.

    угу, а если полю `date` нужно присвоить значение NOW() без кавычек?

    ясно, более чем с двумя БД не работал...
     
  16. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    ... и вообще я первый день в программировании.
    просили простой пример, добавлять лишний код в данном случае считаю нецелесообразным.
    в таких ситуациях обычно NOW() ставится в значение поля по умолчанию, а при вставке вообще не используется.
    к тому же просили пример, где все данные будут находиться в ассоциативном массиве.
    все экранируется, код смотреть лучше надо.
     
  17. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    добавлю.
    ООП - вещь, бесспорно, хорошая, но использовать ее нужно тоже с умом, а не пихать везде, где попало.
     
  18. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Я прошел эту стадию уже. У меня у самого были свои классы для работы с базой. И куда более мощьные и функциональные, с куда более удобным функционалом. Но я по этому поводу уже где-то писал на форуме. Я не работаю с такой мелочёвкой больше, где бы такие классы могли бы быть применены - обработка результата из 5-6 линкованных таблиц с 2-6 подзапросами, сложными условиями - далеко не тривиальная задача, поэтому какая либо абстракция просто шагает строевым шагом сами знаете куда. В любом случае SQL запрос пишеться в ручную - зачем в таком случае передавать его в прослойку, там как-то обрабатывать, возращать результат в виде массива и потом его ещё раз прокручивать и обрабатывать. Небрежное отношение к ресурсам и памяти. Берём напрямую результат и обрабатываем его. Незнаю над какими проэктами вы работали, но что-то мне подсказывает, что в больших и сложных проэктах вам работать не приходилось, где каждый SQL запрос - произведение искуства.

    вообще люди опытные и набившие руку, которые используют шабоны юзают примерно такие конструкции (лично мы всем офисом по такому шаблону работаем)
    PHP:
    1. //some code
    2. $result = mysql_query('SELECT SQL QUERY HERE', $database);
    3. if (mysql_num_rows($result)){
    4.   // here init some variables if needed
    5.   $rows = array();
    6.   while ($row = mysql_fetch_assoc($result)){
    7.     // proccess data here
    8.     $rows[] = $proccessed_data;
    9.   }
    10.   $parser->set('data_key', $rows);
    11. }
    12. // some code
    А в шаблонах есть конструкция
    Код (Text):
    1. <!-- HTML CODE //-->
    2. <? if ($parser->is_set('data_key'){?>
    3.   <!-- here we generate HTML code //-->
    4. <?}else{?>
    5.   <!-- default HTML if there is NO data //-->
    6. <?}?>
    Удобнее и лучше конструкции наверно не придумали. К такому стилю меня приучил мой коллега, у которого опыт в разработке WEB приложений больше 10-ти лет, и на PHP пишет он уже очень давно, знает его внутренности как свои 5 пальцев.

    Что же до абстракции - скажу одно, она возможна только в довольно небольших либо не сложных проэктах, где не требуеться продвинутого функционала базы данных. И всё же частенько люди пишут отдельно запросы на каждую из баз и подключают фаилы с такими запросами в зависимости от типа базы данных. PHP не настолько быстрый, что бы на нём безболезненно можно было бы реализовать абстракцию уровня Java или C++ - и то, я уверен, что даже в таких языках, если использовать базу данных на полную катушку, никакая абстракция не поможет.

    PEAR :: DB когда нить пробовали пользовать? Я пробовал, больше не использую и никому не рекомендую. Тормозит нещадно. Может на небольшом проэкте и незаметно, но даже в таком случае, бесполезный расход ресурсов сервера.

    К примеру EMS MySQL Manager не позволяет по дефолту прописать такие значения как NOW() для полей datetime - незнаю почему, но не разрешает. Но это так, отступление...
    А по теме, NOW() - это довольно тривиальный и не всегда самый частый случай.. частенько приходиться вписывать и такие конструкции
    Код (Text):
    1. UPDATE/INSERT table SET filed = NOW() + INTERVAL 2 DAY
    Или выбирать значения из подзапроса, или расчитывать через самописную SQL функцию и.т.д. И не смотрите такими глазами, я с такими ситуациями сталкиваюсь часто. У меня есть один запрос, где значение устанавливаеться по условию, в котором вложено ещё несколько условий и подзапросов, и опять же, не единичный случай. Я вообще стараюсь не выносить на строну PHP то, что можно сделать SQL запросами. Поэтому у меня часто в бывает так, то что я делаю в один запрос, то многие из здесь сидящих делали бы в 3-6 запросов, поскольку не имеют достаточных знаний SQL'a.
     
  19. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Psih
    Слухай, ты случаем не мой бот ?
    (тоже из прибалтики, и уже второй раз за эти пять минуть я с тобой полностью согласен) :)
     
  20. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Нет, не бот :) Ip'ки у нас 100% разные :) Темболее я с Риги, Латвия :)
     
  21. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    кхы. использую аналогичные конструкции. =)
     
  22. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    вот видишь, а в реальности надо ещё кучу дополнительного кода дописывать. из раза в раз...

    ладно, тогда now() + некоторое заранее неопределённое кол-во дней.

    это наиболее универсальный и наглядный формат. не нравится? приведи тот вариант который нравится.

    какие?

    издеваешься? в моём классе нет никакой абстракции. только удобный механизм инлайн экранирования и получение результата ввиде значения/строки/таблицы/ресурса.

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

    далее я немного оптимизировал твой код...

    Код (Text):
    1. <?
    2. //some code
    3. #/$result = mysql_query('SELECT SQL QUERY HERE', $database);
    4. #if (mysql_num_rows($result)){
    5.   # here init some variables if needed
    6.   #$rows = array();
    7.   #while ($row = mysql_fetch_assoc($result)){
    8.     #// proccess data here
    9.     #$rows[] = $proccessed_data;
    10.   #}
    11.   $rows= $db->get2d('select sql query here');
    12.   // proccess data here
    13.   $parser->set('data_key', $rows);
    14. #}
    15. // some code
    16. ?>
    а на мой взгляд - уже и давно...
    Код (Text):
    1. <? if($data_key): ?>
    2. ...
    3. <? else: ?>
    4. ...
    5. <? endif; ?>
    то же самое могу сказать про PDO =)

    зависит от ситуации... некоторые вещи быстрее работают при реализации в несколько запросов, чем в один, но с кучей объединений, замыканий и подзапросов.
     
  23. draak

    draak Guest

    А мне больше ничего для жизни не надо...
    PHP:
    1.  
    2. $db_s = mysql_query("SELECT * FROM $table");
    3. while($s = mysql_fetch_assoc($db_s))
    4. $smarty->append("rows",$s);
    5.  
     
  24. Вльдемар

    Вльдемар Активный пользователь

    С нами с:
    20 май 2006
    Сообщения:
    635
    Симпатии:
    0
    Адрес:
    Белхород
  25. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    абоснуйте