За последние 24 часа нас посетили 17875 программистов и 1613 роботов. Сейчас ищут 1462 программиста ...

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

Тема в разделе "Решения, алгоритмы", создана пользователем pihel, 7 июл 2008.

  1. pihel

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    Прошу зацените класс для работы с БД http://pastebin.ru/295136
    Особенности:
    - надстройка над PDO
    - улучшена работа с PDO, убраны много словные запросы (Сразу скажу названия функции я взял из SimpleDB в целях переносимости кода с этой системы)
    - логирование ошибочных sql зарпосов
    - кэширование select запросов
    - подсчет статистики (число запросов, их тип, время выполнения)
    - префиксы для таблиц
    Я хотел совместить простоту работы (как в SimpleDB) и скорость работы PDO

    Нужно ли комунить такое? если нужно, то что следует изменить или добавить
     
  2. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    прикольно. Я вот тоже хочу услышать мнение некоторых людей и в случае чего перейти на этот класс.
     
  3. Ti

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

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

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    Наверно... надо гденить в своих проектах пока поиспользовать, пообкатать..
     
  5. topas

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

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Ti
    Идеального кода не существует :)
     
  6. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    PHP:
    1. if((bool)(int)$e[0]) throw new Exception($e[2], $e[0]);
    wtf?
     
  7. pihel

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    :)
    Ну там строка вида 00000, если запрос нормально выполнился
    можно и по другому написать if($e[0] !== "00000")
     
  8. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    дак зачем (bool)?

    PHP:
    1. (int)"0000" == false
     
  9. pihel

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    В моем варианте строка приводится к числу, а потом число к булевому типу
    Ваш вариант тоже будет работать, только здесь преобразованием занимается сам пхп
    вообще это столь принципиально ?
     
  10. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Да нет. Просто сразу в глаза бросается :)
     
  11. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Надстрока над PDO который надстройка над mysql/pgsql/ect. Знаете, лучше уж PEAR::DB :)
     
  12. pihel

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    Помоему PDO может работать быстрей стандарнтых функций mysql, за счет своей реализации плэйсхолдеров bindvalue
     
  13. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    pihel
    MySQLi - покажи мне что-нить быстрее родного драйвера (placeholders там присутствуют), ибо PDO это надстройка над стандартными драйверами. Учим матчасть господа.
     
  14. pihel

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    Получается mysqli быстрей pdo ?
    Может тогда надстройку над mysqli написать :)) ??
     
  15. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Я такую и использую.
     
  16. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    mysqli точно такая же надстройка над нативным драйвером mysql, как и pdo_mysql.
     
  17. pihel

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

    С нами с:
    3 май 2007
    Сообщения:
    7
    Симпатии:
    0
    а SHOW TABLE STATUS LIKE ... заработает еще гденить кроме mysql ?
     
  18. Ti

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

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

    Psih
    PDO это скомпилиный C код, он на порядок быстрее PEAR :: DB

    mysql выпустила нативные драйвера, зовутся mysqlnd, они быстрее
    включены в ветку php-5.3, могут юзатся в расширениях mysql и mysqli
    отдельная версия драйвера для PDO
     
  19. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Ti
    Я знаю что такое mysqlnd.
    Это я к тому, что нафиг сдался что PDO, что PEAR:DB - есть нормальные родные библиотеки. Для серьёзных проектов абстракции типа PDO или PEAR:DB убийственны и бесполезны, а для мелочёвки это просто излишество. Т.е. по сути куда не плюнь, везде вы упрётесь в то, что как только напишите запрос, специфичный для конкретной базы данных или просто различно работающий на двух разных БД, вы автоматом теряете ВСЮ кроссплатформенность. Вам оно надо трахаться, извините за мой французкий, с запросами, пытаясь заставить их быстро и корректно работать во всех базах которые вам надо? Да хотя бы элементарное TOP vs LIMIT в MSSQL vs MySQL - подходы настолько разные, что без шаманства (и тормозов) не обойтись. А сложный запрос построить на базе PDO или PEAR::DB не выйдет. Вам тогда нужен Doctrine, а это хоть и хорошая штука, но очень тяжелая хочу заметить и по этой причине не везде её можно применять (особенно когда кол-во запросов идёт на тысячи в секунду и вы не владеете дата центром)
     
  20. Ti

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

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

    остальной флейм - частный случай, всякие инструменты полезны и хороши для своих задач
     
  21. Anonymous

    Anonymous Guest

    м, PDO = не абстракция!!
    Только унификация, по большей части.
     
  22. Psih

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

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Горбунов Олег
    Ну эта унификация у них получилась слишком тяжелой имхо. Ладна если нужно работать с несколькими базами сразу, но это и проекты совершенно другого уровня как правило и частенько там даже не PHP :) А если нужен один MySQL - то mysqli идеально подходит + в объектном стиле она сама по себе даёт абстракцию названий методов, можно легко имплементировать её функциональность самому для того же MSSQL (что знакомый мой один и сделал, PDO ему не понравился, зато MySQLi на ура использует) или PostrgeSQL
     
  23. Danilka

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

    С нами с:
    8 ноя 2007
    Сообщения:
    192
    Симпатии:
    0
    Достаточно давно пользую этот код:
    PHP:
    1. <?php
    2. class SQL{
    3.  
    4. private $db     = NULL;
    5. private $error_log  = NULL;
    6. private $query_log  = NULL;
    7. private $r      = NULL;
    8.  
    9. private $all = 0;
    10. private $q = NULL;
    11. private $tmp_query = NULL;
    12.  
    13. public function __construct( $db_host , $db_name , $db_user , $db_pass )
    14. {
    15.     $db = new PDO( 'mysql:host='.$db_host.';dbname='.$db_name , $db_user , $db_pass );
    16.     if( !$db )  return( false );
    17.     $db -> exec( 'SET NAMES '.DB_ENCODING );
    18.  
    19.     $this -> db = $db;
    20.     $this -> error_log['all'] = 0;
    21.     $this -> query_log['all'] = 0;
    22. }
    23.  
    24. private function add_query_log( $query , $array , $res )
    25. {
    26.     $this -> all++;
    27.     if( $res )  $this -> q[ $this -> all ][0] = true;
    28.     else        $this -> q[ $this -> all ][0] = false;
    29.     $this -> q[ $this -> all ][1] = $query;
    30.     $this -> q[ $this -> all ][2] = $array;
    31. }
    32.  
    33. public function log()
    34. {
    35.     $all = $this -> all;
    36.     $q = $this -> q;
    37.     if( $all > 0 )  echo '<br><b>DB log:</b><hr>';
    38.     print_r( $this -> db -> errorInfo() );
    39.     echo '<hr>';
    40.     for( $i=1 ; $i<=$all ; $i++ )
    41.     {
    42.         $query = $q[$i][1];
    43.         $n = 0;
    44.         $data = NULL;
    45.         if( $q[$i][2] )
    46.         {
    47.             foreach( $q[$i][2] as $val )
    48.             {
    49.                 $n++;
    50.                 $data[$n] = $val;
    51.             }
    52.         }
    53.         $n = 0;
    54.         while( is_int( $pos = strpos( $query , '?' , 0 ) ) )
    55.         {
    56.             $n++;
    57.             if( isset( $data[$n] ) )
    58.             {
    59.                 $query = substr_replace( $query , '\''.$data[$n].'\'' , $pos , true );
    60.             }
    61.             else    $query = str_replace( '?' , '#' , $query );
    62.         }
    63.         if( $q[$i][0] ) echo '<b>['.$i.']</b>&nbsp;'.$query.';<hr>';
    64.         else        echo '<b>['.$i.']</b>&nbsp;<font color="red">'.$query.';</font><hr>';
    65.     }
    66. }
    67.  
    68. public function get_res()
    69. {
    70.     return( $this -> r );
    71. }
    72. public function fetch()
    73. {
    74.     return( $this -> r -> fetch(PDO::FETCH_ASSOC) );
    75. }
    76.  
    77. public function fetch_all()
    78. {
    79.     return( $this -> r -> fetchAll(PDO::FETCH_ASSOC) );
    80. }
    81.  
    82. public function count()
    83. {
    84.     return( $this -> r -> rowCount() );
    85. }
    86.  
    87. private function del_slashes( $data )
    88. {
    89.     foreach( $data as $key => $value )
    90.     {
    91.         $data[$key] = stripslashes( $value );
    92.     }
    93.     return( $data );
    94. }
    95.  
    96. public function prepare( $request )
    97. {
    98.     $this -> tmp_query = $request;                      ### TEMP ###
    99.     if( $this -> r = $this -> db -> prepare( $request ) )   return( true );
    100.     else    return( false );
    101. }
    102.  
    103. public function execute( $p )
    104. {
    105.     $p = $this -> del_slashes( $p );
    106.     if( $this -> r -> execute( $p ) )
    107.     {
    108.         $this -> add_query_log( $this -> tmp_query , $p , true );   ### TEMP ###
    109.         return( true );
    110.     }
    111.     else
    112.     {
    113.         $this -> add_query_log( $this -> tmp_query , $p , false );  ### TEMP ###
    114.         return( false );
    115.     }
    116. }
    117.  
    118. public function last_id()
    119. {
    120.     return( $this -> db -> lastInsertId() );
    121. }
    122.  
    123. public function get_row( $table , $what , $where , $param )
    124. {
    125.     if( $r = $this -> db -> prepare( 'SELECT '.$what.' FROM '.DB_TABLE_PREF.$table.' WHERE '.$where ) )
    126.     {
    127.         if( $r -> execute( $param ) )
    128.         {
    129.             if( $row = $r -> fetch(PDO::FETCH_ASSOC) )
    130.             {
    131.                 $this -> add_query_log( 'SELECT '.$what.' FROM '.DB_TABLE_PREF.$table.' WHERE '.$where , $param , true );   ### TEMP ###
    132.                 return( $row );
    133.             }
    134.             else
    135.             {
    136.                 $this -> add_query_log( 'SELECT '.$what.' FROM '.DB_TABLE_PREF.$table.' WHERE '.$where , $param , false );  ### TEMP ###
    137.                 return( false );
    138.             }
    139.         }
    140.         else
    141.         {
    142.             $this -> add_query_log( 'SELECT '.$what.' FROM '.DB_TABLE_PREF.$table.' WHERE '.$where , $param , false );  ### TEMP ###
    143.             return( false );
    144.         }
    145.     }
    146.     else
    147.     {
    148.         $this -> add_query_log( 'SELECT '.$what.' FROM '.DB_TABLE_PREF.$table.' WHERE '.$where , $param , false );  ### TEMP ###
    149.         return( false );
    150.     }
    151. }
    152.  
    153. public function insert( $table , $fields , $data )
    154. {
    155.     $data = $this -> del_slashes( $data );
    156.     $all = count( $data );
    157.     $query = 'INSERT INTO '.DB_TABLE_PREF.$table.' ('.$fields.') VALUES ( ';
    158.     if( $all > 0 )  $query .= ' ? ';
    159.     for( $i=1 ; $i<$all ; $i++ )    $query .= ', ? ';
    160.     $query .= ')';
    161.     if( $r = $this -> db -> prepare( $query ) )
    162.     {
    163.         if( $r -> execute( $data ) )
    164.         {
    165.             $this -> add_query_log( $query , $data , true );    ### TEMP ###
    166.             return( $this -> db -> lastInsertId() );
    167.         }
    168.         else
    169.         {
    170.             $this -> add_query_log( $query , $data , false );   ### TEMP ###
    171.             return( false );
    172.         }
    173.     }
    174.     else
    175.     {
    176.         $this -> add_query_log( $query , $data , false );   ### TEMP ###
    177.         return( false );
    178.     }
    179. }
    180.  
    181. public function select( $table , $what , $where , $data )
    182. {
    183.     $data = $this -> del_slashes( $data );
    184.     $query = 'SELECT '.$what.' FROM '.DB_TABLE_PREF.$table.' WHERE '.$where;
    185.     if( $r = $this -> db -> prepare( $query ) )
    186.     {
    187.         if( $r -> execute( $data ) )
    188.         {
    189.             $this -> add_query_log( $query , $data , true );    ### TEMP ###
    190.             $this -> r = $r;
    191.             return( true );
    192.         }
    193.         else
    194.         {
    195.             $this -> add_query_log( $query , $data , false );   ### TEMP ###
    196.             return( false );
    197.         }
    198.     }
    199.     else
    200.     {
    201.         $this -> add_query_log( $query , $data , false );   ### TEMP ###
    202.         return( false );
    203.     }
    204. }
    205.  
    206. public function update( $table , $what , $where , $data , $limit )
    207. {
    208.     $data = $this -> del_slashes( $data );
    209.     $query = 'UPDATE '.DB_TABLE_PREF.$table.' SET '.$what;
    210.     if( $where )    $query .= ' WHERE '.$where;
    211.     if( $limit = (int)$limit > 0 )  $query .= ' LIMIT '.$limit;
    212.     if( $r = $this -> db -> prepare( $query ) )
    213.     {
    214.         if( $r -> execute( $data ) )
    215.         {
    216.             $this -> add_query_log( $query , $data , true );    ### TEMP ###
    217.             return( $r -> rowCount() );
    218.         }
    219.         else
    220.         {
    221.             $this -> add_query_log( $query , $data , false );   ### TEMP ###
    222.             return( false );
    223.         }
    224.     }
    225.     else
    226.     {
    227.         $this -> add_query_log( $query , $data , false );   ### TEMP ###
    228.         return( false );
    229.     }
    230. }
    231.  
    232. public function delete( $table , $where , $data , $limit )
    233. {
    234.     $query = 'DELETE FROM '.DB_TABLE_PREF.$table.' WHERE '.$where;
    235.     if( $limit = (int)$limit > 0 )  $query .= ' LIMIT '.$limit;
    236.     if( $r = $this -> db -> prepare( $query ) )
    237.     {
    238.         if( $r -> execute( $data ) )
    239.         {
    240.             $this -> add_query_log( $query , $data , true );    ### TEMP ###
    241.             return( $r -> rowCount() );
    242.         }
    243.         else
    244.         {
    245.             $this -> add_query_log( $query , $data , false );   ### TEMP ###
    246.             return( false );
    247.         }
    248.     }
    249.     else
    250.     {
    251.         $this -> add_query_log( $query , $data , false );   ### TEMP ###
    252.         return( false );
    253.     }
    254. }
    255.  
    256. public function query( $query )
    257. {
    258.     if( $this -> r = $this -> db -> query( $query ) )
    259.     {
    260.         $this -> add_query_log( $query , NULL , true ); ### TEMP ###
    261.         return( true );
    262.     }
    263.     else
    264.     {
    265.         $this -> add_query_log( $query , NULL , false );    ### TEMP ###
    266.         return( false );
    267.     }
    268. }
    269.  
    270. }