За последние 24 часа нас посетили 22679 программистов и 1281 робот. Сейчас ищут 760 программистов ...

Класс для работы с БД с Placeholder'ами

Тема в разделе "Решения, алгоритмы", создана пользователем Mr.M.I.T., 18 мар 2010.

  1. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    По ряду причин - deleted
     
  2. с тех пор как появилась их нативная поддержка.
     
  3. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    да ну, так не интересно. тем более не всех
     
  4. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    Mr.M.I.T.
    а как же goDB ?
     
  5. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Я как-то еще не дорос до placeholder'ов... =))
    Я пошел по другому пути:
    escape - определяет тип переданной переменной и возвращает строку в кавычках, число или NULL. Естественно проходится обработка типа mysql_real_escape_string.
    select, insert, update, delete - могут принимать готовый запрос, а могут принимать имя таблицы и массивы и уже на их основе составлять запросы.
     
  6. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    флоппик
    да, но неудобно писать так:
    PHP:
    1.  
    2. <?php
    3. $_db->prepare('INSERT INTO table SET field1=:f1, field2=:f3');
    4. $_db->bind('f1', $_GET['f1'], PDO::INTEGER);
    5. $_db->bind('f2', $_GET['f2'], PDO::STRING);
    куда лучше так:

    PHP:
    1.  
    2. <?php
    3. $_db->query('INSERT INTO table SET field1=?i, field2=?s', $_GET['f1'], $_GET['f2']);
    4.  
     
  7. PHP:
    1.  
    2. <?php
    3. $pdo->prepare('INSERT INTO table SET field1=?, field2=?');
    4. $pdo->execute(array($_GET['f1'], $_GET['f2']));
     
  8. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    каким образом будут преобразованы переменные? У меня strict mode и оборачивать int'ы кавычками нельзя
     
  9. относительно их текущего типа.
     
  10. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    учитывая то, что данные от пользователя приходят в виде строк, то нужно либо писать bind + PDO::INTEGER либо внутри execute приводить их к нужному типу. Довольно напряжно [для меня].

    Я остаюсь при своем мнении - типизированным плейсхолдерам (?i, ?s, ?f) быть.
     
  11. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    а если они прийдут как строки в массив который ты передаешь на екзекьют? или типа полей?
     
  12. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    флоппик
    кстати то что ?arrlk у Mr.M.I.T. очень классная штука, чтобы не использовать отдельные билдеры.
    И вообще prepare->execute может замедлять работу с БД в полтора раза :D
     
  13. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    в моих велосипедных библиотеках тоже так можно =)

    но, кстати, мы не замеряли во сколько раз наши либы замедляют работы с БД
     
  14. lexa

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

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    ?n - ?d или ?i логичнее, имхо. ?n выделить под null.

    ?arr* - ?ap или просто ?a. Соответственно, для ключей ?ak и ?av - для значений.

    ?arrand и ?arrand на мой взгляд лишние сущности.
     
  15. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    флоппик
    да ладно, чё морозишься, поясни нам, чё делать?

    пофиг, замедляет только взаимодействие с БД, а один preg_replace или типа того ничёго не замедляет...
     
  16. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
  17. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    глянь какой у меня там парсер и кешер =)
    можно сказать ради него писал.
    всё парсится только один раз.
    lexa
    да можно поменять без труда. там всё в switch'е
    но это на любителя. мне лично вообще без разницы, если не доходит до такого
    Koc
    это твоя?
     
  18. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    флоппик
    кстати, ты же сам писал, что используешь почти "эти" же плейсхолдеры? =)
     
  19. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Mr.M.I.T.
    Да, но не тестированная толком. И я еще не решил, что лучше возвращать - объект Mysqli_result или свой объект BL_Database_ Result.
     
  20. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    прикольные у тебя комменты ))

    Mr.M.I.T. заделаешь нормальный LIKE плейсхолдер будешь реально крут!
     
  21. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    мм? если ты о результате, дело не в LIKE'е
    у меня круче =)
    зачем тебе свой обжект? и тем более почему _Result. уж не итератор ли?
     
  22. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    нет, спасибо =)
    PHP:
    1.    
    2. <?
    3. public function fetch($result, $fetch)
    4.     {
    5.         $fetch = strToLower($fetch);
    6.         if ((!$fetch) || ($fetch == 'no')) {
    7.             return $result;
    8.         }
    9.         if ($fetch == 'id') {
    10.             return $this->insert_id;
    11.         }
    12.         if ($fetch == 'ar') {
    13.             return $this->affected_rows;
    14.         }
    15.         $numRows = $result->num_rows;
    16.         if ($fetch == 'num') {
    17.             return $numRows;
    18.         }
    19.         if ($fetch == 'row') {
    20.             $A = Array();
    21.             for ($i = 0; $i < $numRows; $i++) {
    22.                 $A[] = $result->fetch_row();
    23.             }
    24.             return $A;
    25.         }
    26.         if ($fetch == 'assoc') {
    27.             $A = Array();
    28.             for ($i = 0; $i < $numRows; $i++) {
    29.                 $A[] = $result->fetch_assoc();
    30.             }
    31.             return $A;
    32.         }
    33.         if ($fetch == 'col') {
    34.             $A = Array();
    35.             for ($i = 0; $i < $numRows; $i++) {
    36.                 $r = $result->fetch_row();
    37.                 $A[] = $r[0];
    38.             }
    39.             return $A;
    40.         }
    41.         if ($fetch == 'object') {
    42.             $A = Array();
    43.             for ($i = 0; $i < $numRows; $i++) {
    44.                 $A[] = $result->fetch_object();            
    45.             }
    46.             return $A;
    47.         }
    48.         if ($fetch == 'vars') {
    49.             $A = Array();
    50.             for ($i = 0; $i < $numRows; $i++) {
    51.                 $r = $result->fetch_row();
    52.                 $A[$r[0]] = $r[1];
    53.             }
    54.             return $A;
    55.         }
    56.         if ($fetch == 'irow') {
    57.             return new goDBResultRow($result);
    58.         }
    59.         if ($fetch == 'iassoc') {
    60.             return new goDBResultAssoc($result);
    61.         }
    62.         if ($fetch == 'icol') {
    63.             return new goDBResultCol($result);
    64.         }
    65.         if ($fetch == 'iobject') {
    66.             return new goDBResultObject($result);
    67.         }        
    68.         if ($numRows == 0) {
    69.             return false;
    70.         }
    71.         if ($fetch == 'rowrow') {
    72.             return $result->fetch_row();
    73.         }
    74.         if ($fetch == 'rowassoc') {
    75.             return $result->fetch_assoc();
    76.         }
    77.         if ($fetch == 'rowobject') {
    78.             return $result->fetch_object();
    79.         }        
    80.         if ($fetch == 'el') {
    81.             $r = $result->fetch_row();
    82.             return $r[0];
    83.         }
    84.         return true;
    85.     }
    86.  
    87.  
    88. /*........*/
    89.  
    90.  
    91. class goDBResultRow extends goDBResult
    92. {
    93.     protected function getEl()
    94.     {
    95.         return $this->result->fetch_row();
    96.     }
    97. }
    98.  
    99. class goDBResultAssoc extends goDBResult
    100. {
    101.     protected function getEl()
    102.     {
    103.         return $this->result->fetch_assoc();
    104.     }
    105. }
    106.  
    107. class goDBResultCol extends goDBResult
    108. {
    109.     protected function getEl()
    110.     {
    111.         $r = $this->result->fetch_row();
    112.         return $r[0];
    113.     }
    114. }
    115.  
    116. class goDBResultObject extends goDBResult
    117. {
    118.     protected function getEl()
    119.     {
    120.         return $this->result->fetch_object();        
    121.     }
    122. }
    123.  
     
  23. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Koc
    зря ты с неё всё слизал =)
     
  24. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    не понял. Что значит зря? Пользуюсь год где-то, доволен. А чем твое творение лучше goDB?

    А как дело было: я использовал sprintf для приведения типов. Потом увидел goDB и плейсхолдеры в ней. Через неделю узнал, что оказывается у нас на работе тоже класс для работы с БД с плейсхолдерами. Удивился, я тогда 3 месяца уже проработал в этой конторе и тут такая новость.


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

    Еще не понравилось то, что для разбора результатов нужно какую-то строку отправлять. Я предпочитаю автодополнение. Сделал адаптер к goDB, который разруливает 2 вышеперечисленных недочета. Потом решил сам написать.

    Через некоторое время решил глянуть ман для Zend_DB и PDO. Был приятно удивлен, что многие методы одинаково названы у меня (fetch, fetchAll, ...).

    Итого, можно сказать что мой класс для работы БД - синтез из:
    пары капель Zend_DB (добавлю еще пару капель - fetchParis, еще че-то)
    ложки goDB (тип справа от "?". На работе кроме "?" еще есть "!" и прочее. Это неудобно)
    ложки класса с работы
    половника своего писалова