За последние 24 часа нас посетили 17834 программиста и 1614 роботов. Сейчас ищут 1450 программистов ...

Библиотека работы с MySql

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

  1. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    Решил поделиться своими наработками в части работы с базой данных mySql с применением языка PHP.

    Сразу оговорюсь, объектно-ориентированных подход в данном случае не используется, все написано не в плане максимально приближения к идеалу, а в плане максимального упрощения программирования.

    Дополнительными плюсами использования данной библиотеки являются:
    - В глобальной переменной $sql_time всегда хранится время выполнения всех sql запросов
    - При установке значения $debug[error] = true; на экран выводятся все ошибки исполнения запросов
    - При установке значения $debug[sql] = true; на экран выводятся все выполняемые запросы + время на выполнения каждого

    Минусы тоже присутствуют:
    - Во всех текстовых полях нельзя использовать знак #, удаляем, заменяем, но быть его не должно
    - Если в таблице нет auto_increment поля insertTable вернет 0

    И еще один минус, через месяц работы с этой библиотекой вы забудете как на самом деле по шагам должны были работать с mySql, я к примеру уже не помню :)

    Подключение к базе данных, не мучайте себя безумными кусками кода, которые приходиться постоянно вставлять в различные файлы:

    Код (Text):
    1.  
    2. $dbh = @mysql_connect($mysql_host, $mysql_user, $mysql_pass);
    3.  
    4. if (!@mysql_select_db($mysql_database, $dbh)) {
    5.      errorLog("Mysql server $mysql_host may be down\n", "error.fatal.log");
    6.     @mysql_close($dbh);
    7.      exit();
    8. }
    9. execSql("SET NAMES 'cp1251';");
    10. register_shutdown_function(exitDb);
    при использовании библиотеки:
    Код (Text):
    1. connectMysql($mysql_database, $mysql_host, $mysql_user, $mysql_pass);
    Далее очень часто нам необходимо получить всего одну строку:
    Код (Text):
    1. $sql     = "SELECT * FROM table WHERE key='some' LIMIT 0,1";
    2. $result = mysql_query($sql);
    3. $part = fetchArray($result);
    При использовании библиотеки:
    Код (Text):
    1.  
    2. $part = getOneRow("table", "key='some'");
    Получение количества строк
    Код (Text):
    1.  
    2. $sql     = "SELECT COUNT(*) as numRows FROM table WHERE key='some'";
    3. $result = mysql_query($sql);
    4. $part = fetchArray($result);
    5. $numRows = $part[numRows]; 
    С использованием библиотеки:
    Код (Text):
    1.  
    2. $numRows = getNumRows ("table", "key='some'");

    Вставляем новые строки в базу данных
    Код (Text):
    1.  
    2. $sql = "INSERT INTO table (field1, field2) values ('value1', 'value2')";
    3. $result = mysql_query($sql);
    4. $lastId = mysql_insert_id();   
    С использованием библиотеки:
    Код (Text):
    1.  
    2. $lastId = insertTable("table", "", "field1# field2", "$value1# $value2");
    Обновляем строки в базе данных
    Код (Text):
    1.  
    2. $sql = "UPDATE table SET field1='value1', field2='value2' WHERE key='some'";
    3. $result = mysql_query($sql);
    4. $numRows = mysql_affected_rows (); 
    С использованием библиотеки:
    Код (Text):
    1.  
    2. $numRows = insertTable("table", "", "field1# field2", "$value1# $value2");
    Бывают ситуации, когда мы неуверенны, есть ли в базе данных данная запись, но сохранить данные необходимо
    Код (Text):
    1.  
    2. If (getNumRows("table", "where")) {
    3.    updateTable("table", "where", "fields", "values");
    4. } else {
    5.    insertTable("table", "", "fields", "values");
    6. }  
    Код (Text):
    1.  
    2. $numRows = modifyTable("table", "key='some'", "field1# field2", "$value1# $value2");

    Вот собственно и все, вопросы комментарии?
     
  2. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    Собственно сама библиотека :)

    PHP:
    1.  
    2. <?
    3. // ===========================================================================================================
    4. // SQL Class
    5. // VER. 10.0.0.0
    6. //
    7. // Developed by Miftahov Nariman.
    8. // [url=http://vseznaut.ru/]http://vseznaut.ru/[/url]
    9. // [email=miftahovn@gmail.com]miftahovn@gmail.com[/email]
    10. // ===========================================================================================================
    11.  
    12. // Подключение к базе данных
    13. // ===============================================================================
    14. function connectMysql($mysql_database, $mysql_host, $mysql_user, $mysql_pass) {
    15.     global $dbh;
    16.  
    17.     $dbh = @mysql_connect($mysql_host, $mysql_user, $mysql_pass);
    18.  
    19.     if (!@mysql_select_db($mysql_database, $dbh)) {
    20.         errorLog("Mysql server $mysql_host may be down\n", "error.fatal.log");
    21.         @mysql_close($dbh);
    22.         exit();
    23.     }
    24.     execSql("SET NAMES 'cp1251';");
    25. }
    26.  
    27.  
    28. // Функция завершения связи с Mysql. Вызывается тихо, но всегда
    29. // ===============================================================================
    30. function exitDb() {
    31.     global $dbh;
    32.  
    33.     flush();
    34.     @mysql_close($dbh);
    35. }
    36.  
    37.  
    38. // Получаем результат запроса
    39. // ===============================================================================
    40. function getResults($table, $where="1") {
    41.  
    42.     $sql = "SELECT * FROM ".$table." WHERE ".$where;
    43.     return execSql($sql);
    44. }
    45.  
    46. // Здесь должны выполнятся все SQL выражения!
    47. // ==========================================
    48. function execSql($sql) {
    49.     global $_SESSION, $sql_time, $debug;
    50.  
    51.     // =======================================
    52.     $this_time = getmicrotime();
    53.  
    54.     if ($result=@mysql_query($sql)) {
    55.  
    56.         $end_time   = getmicrotime();
    57.         $spent_time = $end_time - $this_time;
    58.         $sql_time  += $spent_time;
    59.  
    60.         if ($debug[sql]) {  
    61.             echo sprintf("%01.2f", $spent_time)." + ";
    62.             echo $sql."<br>";
    63.         }
    64.         return $result;
    65.  
    66.     } else {
    67.         if ($debug[error]) {  
    68.             echo substr($sql, 0, 5000);
    69.             echo "<br>".mysql_errno().": ".mysql_error();
    70.         }
    71.         return false;
    72.     }
    73. }
    74.  
    75. // Fetch // Согласен некрасиво, но длинное выражение запомнить не удается -)
    76. // ===============================================================================
    77. function fetchArray($result) {
    78.     return mysql_fetch_array($result);
    79. }
    80.  
    81.  
    82. // Получаем одну строку
    83. //================================================================================
    84. function getOneRow($table, $where) {
    85.        
    86.     if (!eregi("LIMIT", $where)) {
    87.         $where .= " LIMIT 0, 1";
    88.     }
    89.  
    90.     if ($result = getResults($table, $where)) {
    91.         if ($fetch = fetchArray($result)) {
    92.             return $fetch;
    93.         }
    94.     }
    95.     return false;
    96. }
    97.  
    98. // Получаем количество строк
    99. // ===============================================================================
    100. function getNumRows($table, $where) {
    101.     $sql = "SELECT COUNT(*) as numRows FROM $table WHERE $where";
    102.     return mysql_result(execSql($sql), 0, 0);
    103. }
    104.  
    105. // Удаление из таблицы
    106. // ===============================================================================
    107. function deleteFrom($table, $where) {
    108.  
    109.     $sql = "DELETE FROM ".$table." WHERE ".$where;
    110.  
    111.     if (execSql($sql)) {
    112.         return mysql_affected_rows();
    113.     } else {
    114.         return false;
    115.     }
    116. }
    117.  
    118. // InsertTable // Поля fields и $values должны быть представлены в виде "test1# test2# test3"
    119. // ==========================================================================================
    120. function insertTable($table, $where, $fields, $values) {
    121.     $fields = explode("# ", $fields);
    122.     $values = explode("# ", $values);
    123.  
    124.     while (list($key, $field) = each($fields)) {   
    125.         if ($field_list) $field_list .= ", ";
    126.         $field_list .= $field;
    127.     }
    128.     while (list($key, $value) = each($values)) {   
    129.         if ($value_list) $value_list .= ", ";
    130.         $value_list .= "'$value'";
    131.     }
    132.        
    133.     $sql =  "INSERT INTO ".$table." (".$field_list.") values (".$value_list.")";
    134.  
    135.     // Возвращает последний индекс вставки
    136.     // ===================================
    137.     if (execSql($sql)) {
    138.         return mysql_insert_id();
    139.     } else {
    140.         return false;
    141.     }
    142. }
    143.  
    144. // Update table // Поля fields и $values должны быть представлены в виде "test1# test2# test3"
    145. // ===========================================================================================
    146. function updateTable($table, $where, $fields, $values) {
    147.     $fields = explode("# ", $fields);
    148.     $values = explode("# ", $values);
    149.  
    150.     if (!fill($where)) {
    151.         return false;
    152.     }
    153.  
    154.     while (list($key, $field) = each($fields)) {   
    155.  
    156.         list($key, $value) = each($values);
    157.  
    158.         if ($set)
    159.             $set .= ", ";
    160.        
    161.         // Если знак @ то не ставим кавычки для SET on=on+1
    162.         // ------------------------------------------------
    163.         if (substr($value, 0, 1) == "@") {
    164.             $set .= "$field=".substr($value, 1, 128);
    165.         } else {
    166.             $set .= "$field='$value'";
    167.         }
    168.  
    169.     }
    170.     $sql =  "UPDATE ".$table." SET ".$set." WHERE ".$where;
    171.  
    172.     // Возвращает число затронутых строк
    173.     // =================================
    174.     if (execSql($sql)) {
    175.         return mysql_affected_rows();
    176.     } else {
    177.         return false;
    178.     }
    179. }
    180.  
    181.  
    182. // Insert OR Update
    183. //===============================================================================
    184. function modifyTable($table, $where, $fields, $values) {
    185.  
    186.     // Получаем результат
    187.     // -------------------------------------
    188.     if ($where) {
    189.         $num = getNumRows($table, $where);
    190.     }
    191.  
    192.     if ($num) {
    193.         return  updateTable($table, $where, $fields, $values);
    194.  
    195.     } else {
    196.         return  insertTable($table, $where, $fields, $values); 
    197.  
    198.     }
    199. }
    200.  
    201. ?>
    202.  
     
  3. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    по сабжу: пишется новичком за полчаса.
    Пользы не так много, ввод данных можно сделать лучше.
    Массы глобальных переменных, зачем-то сессии подтянуты. Разбивать и сливать массивы можно проще и быстрее.
    Весь смысл не в том, чтобы забыть синтаксис, а чтобы унифицировать обработку данных. На эту тему тут и ломают копья.
    Есть лишние запросы. Сам код коряв, постестялся бы его выкладывать в таком виде.

    то есть не пишешь вообще кроме хелло ворлд?
    это ваще что?

    В общем, пример, как делать не надо.
     
  4. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    miftahovn
    Ухх... это довольно серьезное ограничение.
    Я бы сказал, это грабли с ядерной боеголовкой для разработчика ;)
    Можно ведь передавать значения в массиве, а не одной строкой, используя разделитель.
     
  5. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    Что значит унифицировать обработку данных? Лично для меня стоит задача, как можно более упростить написание кода, а уже затем унификация, рационализация и другое.

    Какие именно запросы лишние? Что именно криво? PS: Слово "постеснялся" пишется через "н"

    Код (Text):
    1. if (substr($value, 0, 1) == "@") {
    2.   $set .= "$field=".substr($value, 1, 128);
    3. } else {
    4.   $set .= "$field='$value'";
    5. }
    Есть два варианта работы с updateTable()
    1.
    Код (Text):
    1.  
    2. updateTable("table", "where", "summ# count", "1# 2");
    3. В итоге выполнит запрос вида:
    4. UPDATE table SET summ='1', count='2' WHERE where
    2.
    Код (Text):
    1.  
    2. updateTable("table", "where", "summ# count", "1# @count+1");
    3. В итоге выполнит запрос вида:
    4. UPDATE table SET summ='1', count=count+1 WHERE where
     
  6. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    Можно, но тогда сам процесс написания запроса усложняется на порядок ...

    PS: Две функции которые используются в библиотеке, но в её текст не вошли:
    PHP:
    1.  
    2. <?
    3.     $ROOT     = $_SERVER["DOCUMENT_ROOT"]."/";
    4.  
    5.     function errorLog($string, $location) {
    6.         global $ROOT;
    7.  
    8.         $string     = date("H:i:s d-m-Y")." | ".$string."\n";
    9.         $location   = $ROOT.".temp/logs/".$location;
    10.  
    11.         error_log($string, 3, $location);
    12.         echo $string."<br>";
    13.  
    14.         return true;
    15.     }
    16.  
    17.     function getmicrotime() {
    18.         list($usec, $sec) = explode(" ", microtime());
    19.             return ((float)$usec + (float)$sec);
    20.     }
    21. ?>
    22.  

    [/php]
     
  7. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    чтобы добавление данных в таблицу клиентов и в таблицу товаров было единообразно.
    писать select aa,bb... вместо $db('aa # bb',
    нагляднее, дописать query и mysql_fetch_assoc не проблема и не снижает читабельность кода.
    смысл классов для обработки данных не в этом.
     
  8. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    Что значит добавление в таблицу клиентов и товаров единообразно, пример?
    Если имеется ввиду возможность каскадного обновления нескольких таблиц применительно к свойствам, собираемой статистике объектов, то это совершенно другой разговор пишите классы, наследуйте их, описывайте свойства объектов в виде свойств класса и будет необходимый результат.

    Здесь же я представил пример библиотеки, которая является промежуточным звеном к mySql, и не берет на себя никаких функций касающихся представлению данных.
     
  9. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    нет, не в этом дело.
    Библиотека не дает ничего, кроме порчи данных и добавления различного синтаксиса ввода данных.
    Функционал даже инсерта недостаточен.
    Никакого назначения она не выполняет.
     
  10. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    miftahovn
    Совсем необязательно - в PHP есть понятие ассоциативного массива:

    PHP:
    1. <?php
    2.  
    3. $values=array(
    4.   "id"=>5,
    5.   "title"=>"Book",
    6.   "price"=>3000);
    7.  
    8. insertTable("table",$values);
    9.  
    10. ?>
     
  11. dark-demon

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

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    пора открывать новый подраздел: "кунсткамера мускулистых классов" :)
     
  12. Anonymous

    Anonymous Guest

    Вот за одно это я отрываю своим программерам руки. Дальше уже читать нет смысла.
    Все верно.
    Уважаемый, уберите рекламу, в противном случае через пару дней эта тема отправится в топку, и вы следом.
     
  13. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    И много у Вас Олег программеров своих которым вы отрываете руки?

    Мифтахов Нариман,
    Павлодар Казахстан, Телецентр, ул. Павлова.

    Вы можете говорить и писать все что угодно, но я поверю в это только тогда, когда Вы мне покажете свои проекты.
    К примеру мой сайт http://students.tomsk.ru 5500 хостов 360000 хитов в сутки http://tbe.tom.ru/date/2007-7-23
    55 000 пользователей и 28 миллионов записей в таблицах.

    Еще раз говорю эта библиотека просто работает, и упрощает жизнь, хотите использовать всю мощь SQL пользуйтесь полными запросами...
     
  14. Anonymous

    Anonymous Guest

    Хочу.
    Количество разве говорит о качестве?
    Даже проекты — не показатель. Лучший показатель — замеры времени эффективности работы вашей библиотечки, если вам уж так хочется что то доказать кому-то здесь.
    Вы правы. Эта библиотечка просто работает. Обратного никто и не утверждал. А эффективность ее работы, и даже использования — стоит очень остро. Если вы не хотите это обсуждать, зачем вы вообще здесь?

    Благодарю, что убрали рекламу. Приятного общения.

    ЗЫ. Если хочется цифирками мерятся:
    Код (Text):
    1.  
    2. SQL*Plus: Release 9.0.1.0.1 - Production on Сбт Июл 28 12:30:48 2007
    3.  
    4. (c) Copyright 2001 Oracle Corporation.  All rights reserved.
    5.  
    6.  
    7. Присоединен к:
    8. Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
    9. With the Partitioning, OLAP and Oracle Data Mining options
    10. JServer Release 9.2.0.4.0 - Production
    11.  
    12. SQL> select count(*) from ALL_TABLES;
    13.  
    14.  COUNT(*)
    15. ----------
    16.   1765
    17.  
    18. SQL>
    Правда, у меня не все таблицы под моим аккаунтом видны ))
     
  15. stas_t

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

    С нами с:
    24 апр 2007
    Сообщения:
    500
    Симпатии:
    0
    Адрес:
    Courbevoie, France
    фигасе, строчила ! :shock:
     
  16. miftahovn

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

    С нами с:
    31 май 2007
    Сообщения:
    14
    Симпатии:
    0
    насмешил, если уж тут PHP клуб, то мерятся именно веб-проектами,
    я тоже могу сделать COUNT всех таблиц в рабочей базе данных MS Axapta, хранимых в Oracle
    но те таблицы далеко не моих рук дело... пусть за них будет весело и радостно NAVISION и Microsoft ...
     
  17. Anonymous

    Anonymous Guest

    miftahovn, нет, это таблицы приложений нашего отдела, и веб-приложений в частности.
    Мерится надо не количеством, а качеством. Простите, но тут я не вижу качества.
     
  18. stas_t

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

    С нами с:
    24 апр 2007
    Сообщения:
    500
    Симпатии:
    0
    Адрес:
    Courbevoie, France
    miftahovn
    веб-проект имеет все права использовать оракл в качестве базы

    Горбунов Олег
    ты же знаешь, к чему здесь приводят соревнования вроде "у кого больше таблиц" ;-)
     
  19. Anonymous

    Anonymous Guest

    stas_t, ;)

    Ну вот почему если я нехочу уезжать с родного города, все считают, что я не могу, потому что я ламер?
     
  20. dj--alex

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

    С нами с:
    29 ноя 2007
    Сообщения:
    184
    Симпатии:
    0
    у меня начальная . зарезервирована для команд веб интерфейсу, с разделителем для данных передаваемых командой , это дело работает только в интерфейсе поиска, а начальная# там же зарезервирована для мультипоиска по таблицам.

    За это тоже отрывают руки? (за совмещение командной строки и поисковика)?
     
  21. Anonymous

    Anonymous Guest

    Отрывают руки за резервирование символов под себя по капризу.
     
  22. stas_t

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

    С нами с:
    24 апр 2007
    Сообщения:
    500
    Симпатии:
    0
    Адрес:
    Courbevoie, France
    извините, что встреваю, но содержание вашей беседы настолько меня заинтересовало, что я не смог остаться в стороне и не высказаться.

    вы можете мне не верить, но, по-моему, код
    PHP:
    1. <?php
    2. $sql = sprintf ("insert into users (usr_login, usr_pass, usr_name) values ('%s', '%s', '%s')"
    3.   , md5 ($pass)
    4.   );
    5. db_dml ($sql);
    6. ?>
    гораздо надёжнее, чем, скажем,
    PHP:
    1. <?php
    2. sql_insert ('users', array ('login'=>$login, 'pass'=>$pass, 'name'=>$name));
    3. ?>
    ибо в конечном случае второй вариант всё равно должен привести к первому, но приведёт или нет -- вы не можете быть уверены, пока не разберётесь с внутренностями этой самой sql_insert. и это, как видите, элементарнейший запрос. в случае, если вам надо соединять таблицы по сложным условиям, группировать записи, осуществлять сортировки и пр. гораздо спокойнее написать сам запрос, чем пытаться описать всё это же в рамках другого языка-посредника.

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

    я согласен, что mysql api для php можно чуток подправить, чтобы получить запись из базы можно было одной строкой кода, при этом зная, что в случае ошибки в sql-команде (чего не должно быть никогда) или подключении (что может произойти когда угодно) эта ошибка будет правильно обработана, записана в лог и отослана по мылу. но sql запрос я бы не доверял строить машине -- уж очень много тонкостей, которые нужно контролировать самому программисту. и чем наворачивать дополнительные апишники с искусственным интеллектом, лучше устроиться на любимом диване и полистать в очередной раз главку 6 мускульного мануала.
     
  23. Anonymous

    Anonymous Guest

    Целиком согласен со stas_t.