Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Подсветка синтаксиса MySQL-запросов

07.04.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
При выводе диагностики в своих рабочих проектах я использую вот такую функцию для подсветки синтаксиса MySQL-запросов. Она преобразует текст запроса, делая все служебные слова языка заглавными буквами и подсвечивает их цветом, а также выделяет различными цветами числовые значения и скобки. Такая подсветка позволяет сразу же увидеть синтаксические ошибки, да и вообще повышает наглядность сообщений при отладке скриптов.
  1. //-------------------------------------------------------------------
  2. // Функция подсветки синтаксиса MySQL-запроса
  3. // (C) ManHunter / PCL
  4. // http://www.manhunter.ru
  5. //-------------------------------------------------------------------
  6. function mysql_debug($query) {
  7.     $tmp=htmlspecialchars($query);
  8.     $tmp=str_replace("\r",'',$tmp);
  9.     $tmp=trim(str_replace("\n","\r\n",$tmp))."\r\n";
  10.  
  11.     $quote_list_text=array();
  12.     $quote_list_symbols=array();
  13.  
  14.     $k=0;
  15.     $quotes=Array();
  16.     // Обработать экранированные кавычки
  17.     preg_match_all("/\\\'|\\\"/is"$tmp$quotes);
  18.     array_unique($quotes);
  19.     if (count($quotes)) {
  20.         foreach($quotes[0] as $i) {
  21.             $k++;
  22.             $quote_list_symbols[$k]=$i;
  23.             $tmp=str_replace($i'<symbol'.$k.'>'$tmp);
  24.         }
  25.     }
  26.  
  27.     $matches=Array(
  28.         "/(&quot;|'|`)(.*?)(\\1)/is"// текст в кавычках
  29.         "/\/\*.*?\*\//s",             // текст комментария
  30.         "/ \-\-.*\x0D\x0A/",          // текст ' --' комментария
  31.         "/ #.*\x0D\x0A/",             // текст ' #' комментария
  32.     );
  33.  
  34.     // Обработать текст
  35.     foreach($matches as $match) {
  36.         // Обработать текст
  37.         $found=array();
  38.         preg_match_all($match$tmp$found);
  39.         $quotes=(array)$found[0];
  40.         array_unique($quotes);
  41.         if (count($quotes)) {
  42.             foreach($quotes as $i) {
  43.                 $k++;
  44.                 $quote_list_text[$k]=$i;
  45.                 $tmp=str_replace($i'<text'.$k.'>'$tmp);
  46.             }
  47.         }
  48.     }    
  49.  
  50.     // Служебные слова MySQL
  51.     $keywords=Array(
  52.         "avg""as""auto_increment""and""analyze""alter",
  53.         "asc""all""after""add""action""against",
  54.         "aes_encrypt""aes_decrypt""ascii""abs""acos",
  55.         "asin""atan""authors""between""btree""backup",
  56.         "by""binary""before""binlog""benchmark""blob",
  57.         "bigint""bit_count""bit_or""bit_and""bin",
  58.         "bit_length""both""create""count""comment",
  59.         "check""char""concat""cipher""changed""column",
  60.         "columns""change""constraint""cascade""checksum",
  61.         "cross""close""concurrent""commit""curdate",
  62.         "current_date""curtime""current_time",
  63.         "current_timestamp""cast""convert""connection_id",
  64.         "coalesce""case""conv""concat_ws""char_length",
  65.         "character_length""ceiling""cos""cot""crc32",
  66.         "compress""delete""drop""default""distinct",
  67.         "decimal""date""describe""data""desc",
  68.         "dayofmonth""date_add""database""databases",
  69.         "double""duplicate""disable""datetime""dumpfile",
  70.         "distinctrow""delayed""dayofweek""dayofyear",
  71.         "dayname""day_minute""date_format""date_sub"
  72.         "decode""des_encrypt""des_decrypt""degrees",
  73.         "decompress""dec""engine""explain""enum",
  74.         "escaped""execute""extended""errors""exists",
  75.         "enable""enclosed""extract""encrypt""encode",
  76.         "elt""export_set""escape""exp""end""from",
  77.         "float""flush""fields""file""for""fast""full",
  78.         "fulltext""first""foreign""force""from_days"
  79.         "from_unixtime""format""found_rows""floor""field",
  80.         "find_in_set""group""grant""grants""global"
  81.         "get_lock""greatest""having""high_priority"
  82.         "handler""hour""hex""insert""into""inner"
  83.         "int""ifnull""if""isnull""in""infile""is"
  84.         "interval""ignore""identified""index""issuer"
  85.         "integer""is_free_lock""inet_ntoa""inet_aton"
  86.         "instr""join""kill""key""keys""left""load"
  87.         "local""limit""like""lock""lpad""last_insert_id"
  88.         "logs""length""longblob""longtext""last""lines"
  89.         "low_priority""locate""ltrim""leading""lcase"
  90.         "lower""load_file""ln""log""least""month""mod"
  91.         "max""min""mediumint""medium""master""modify"
  92.         "mediumblob""mediumtext""match""mode""monthname"
  93.         "mid""minute""master_pos_wait""make_set""null"
  94.         "not""now""none""new""numeric""no""natural"
  95.         "next""nullif""national""nchar""on""or"
  96.         "optimize""order""optionally""option""outfile"
  97.         "open""offset""outer""old_password""ord""oct"
  98.         "octet_length""primary""password""privileges"
  99.         "process""processlist""purge""partial""procedure",
  100.         "prev""period_add""period_diff""position""pow"
  101.         "power""pi""quick""quarter""quote""right"
  102.         "repair""restore""reset""regexp""references"
  103.         "replace""revoke""reload""require""replication"
  104.         "read""rand""rename""real""restrict"
  105.         "release_lock""rpad""rtrim""repeat""reverse"
  106.         "rlike""round""radians""rollup""select""sum"
  107.         "set""show""substring""smallint""super""subject"
  108.         "status""slave""session""start""share"
  109.         "straight_join""sql_small_result""sql_big_result"
  110.         "sql_buffer_result""sql_cache""sql_no_cache"
  111.         "sql_calc_found_rows""second""sysdate""sec_to_time"
  112.         "system_user""session_user""substring_index""std"
  113.         "stddev""soundex""space""strcmp""sign""sqrt"
  114.         "sin""straight""sleep""text""truncate""table"
  115.         "tinyint""tables""to_days""temporary""terminated"
  116.         "to""types""time""timestamp""tinytext"
  117.         "tinyblob""transaction""time_format""time_to_sec"
  118.         "trim""trailing""tan""then""update""union"
  119.         "using""unsigned""unlock""usage""use_frm"
  120.         "unix_timestamp""unique""use""user""ucase"
  121.         "upper""uuid""values""varchar""variables"
  122.         "version""variance""varying""where""with"
  123.         "warnings""write""weekday""week""when""xor"
  124.         "year""yearweek""year_month""zerofill");
  125.     $replace=Array();
  126.     foreach($keywords as $keyword) {
  127.         $replace[]='/\b'.$keyword.'\b/ie';
  128.     }
  129.  
  130.     // Выделить служебные слова в тексте запроса
  131.     $tmp=preg_replace($replace,
  132.         '"<b style=\"color:#0000FF\">".strtoupper("$0")."</b>"',$tmp);
  133.  
  134.     // Выделить числовые значения в тексте запроса
  135.     $tmp=preg_replace('/\b([\.0-9]+)\b/',
  136.         '<b style="color:#008000">\1</b>',$tmp);
  137.  
  138.     // Выделить скобки в тексте запроса
  139.     $tmp=preg_replace('/([\(\)])/',
  140.         '<b style="color:#FF0000">\1</b>',$tmp);
  141.  
  142.     // Вернуть обратно строки в кавычках
  143.     if (count($quote_list_text)) {
  144.         $quote_list_text=array_reverse($quote_list_texttrue);
  145.         foreach($quote_list_text as $k=>$i) {
  146.             $tmp=str_replace('<text'.$k.'>',
  147.                 '<span style="color:#777;">'.$i.'</span>'$tmp);
  148.         }
  149.     }
  150.     // Вернуть обратно экранированные символы
  151.     if (count($quote_list_symbols)) {
  152.         $quote_list_symbols=array_reverse($quote_list_symbolstrue);
  153.         foreach($quote_list_symbols as $k=>$i) {
  154.             $tmp=str_replace('<symbol'.$k.'>'$i$tmp);
  155.         }
  156.     }
  157.  
  158.     // Вернуть подсвеченный текст запроса
  159.     // Если не надо расставлять переносы, то уберите nl2br
  160.     return nl2br(trim($tmp));
  161. }
Единственный параметр функции $query - текст исходного запроса. На выходе подсвеченная строка запроса в формате HTML. Цвета подсветки захардкодены в исходнике, если надо, то поменяйте их на свои или вообще замените на определения стилей CSS.

Читать статью целиком »
Просмотров: 4735 | Комментариев: 7

Кэширование на PHP

02.03.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
Кэширование данных - это особая технология, направленная на снижение нагрузки на сервер. Суть ее заключается в том, что динамический контент, выбранные из базы данные или данные, получаемые из сторонних источников, сохраняются на диске в виде обычного текстового файла или в памяти вашего сервера. Когда они потребуются снова, то уже нет необходимости опять выполнять тяжелый запрос к базе, обращаться к стороннему серверу или заново парсить шаблон страницы, достаточно просто прочитать эти данные из ранее сохраненного файла или из памяти. Такой подход позволяет значительно ускорить генерацию страниц и тем самым ускорить загрузку сайта, что немаловажно на нагруженных проектах. Актуальность закэшированных данных устанавливается параметром "жизни кэша", то есть интервалом времени от момента сохранения данных до момента, когда их требуется обновить. "Время жизни" определяется для каждого типа данных индивидуально. Так, например, текст статьи может больше никогда не меняться после опубликования, поэтому ее закэшированный вариант можно также никогда не обновлять, кэш с комментариями может обновляться по мере добавления комментариев, данные пузомерок Google PR и Яндекс тИЦ достаточно обновлять раз в сутки, а картинку счетчика посещений желательно перерисовывать с интервалом не реже 10 минут.

Сейчас мы попробуем написать свой модуль для работы с кэшем, основанный на файлах, чтобы понять как это все работает. Функции будут очень простые:
  1. // Определить папку для хранения кэшированных данных
  2. define ('CACHE_DIR',dirname(__FILE__).'/cache');
  3.  
  4. // Запись данных в кэш
  5. function save_cache($file$data) {
  6.     if ($f=fopen(CACHE_DIR.'/'.$file,'w')) {
  7.         fwrite($f,serialize($data));
  8.         fclose($f);
  9.         return true;
  10.     }
  11.     else {
  12.         return false;
  13.     }
  14. }
С записью проблем нет, мы просто создаем файл с заданным именем и записываем в него сериализованные данные. Чтение из кэша немного сложнее, так как сперва надо будет проверять наличие файла и, если требуется, его актуальность.

Читать статью целиком »
Просмотров: 6487 | Комментариев: 11

Отправка файла на сервер с помощью сокетов

02.02.2012 | Категория: Web-мастеру и не только | Автор: ManHunter
Иногда при разработке проектов возникает задача отправки данных на другие серверы. В случае текстовых данных или небольших объемов бинарных данных можно ограничиться POST- или GET-запросами. Этот способ никаких сложностей не представляет и здесь описываться не будет. А как быть, если на сторонний сервер требуется передать не только данные, но и файлы? Например, вы загружаете картинки через форму на своем сервере, но фактически храните их на каком-нибудь другом. В этом случае нам надо полностью проэмулировать работу браузера, а именно его обмен данными с удаленным сервером, как будто бы пользователь заполнил и отправил форму с web-страницы. Предположим, что для загрузки файлов на сервер используется следующая форма:
  1. <form action="/uploader.php" method="post" enctype="multipart/form-data">
  2.     Выберите файл: <input type="file" name="my_file"><br>
  3.     Описание: <input type="text" name="ext_field_1"><br>
  4.     <input type="submit" value="Загрузить">
  5. </form>
C HTML все понятно, а вот чтобы понять как передаются данные после нажатия в браузере кнопки "Загрузить", рекомендую прочитать официальную документацию. В заголовках HTTP-запроса, отправляемого на сервер, обязательно должен присутствовать заголовок "Content-Type: multipart/form-data; boundary=NNNNN". Значение параметра boundary - это уникальная строка, используемая в качестве разделителя полей в теле запроса. Она не должна встречаться ни в одном значении поля формы. Обычно для этого достаточно сгенерировать хэш от случайного числа и использовать его в качестве искомого значения.

Каждое текстовое поле в теле запросе кодируется следующим образом:

--boundary
Content-Disposition: form-data; name="имя_поля_в_форме"

значение поля

Файлы при передаче кодируются несколько иначе:

--boundary
Content-Disposition: form-data; name="имя_поля" filename="имя_файла"
Content-Type: mime-тип файла

двоичное содержимое файла

Как узнать mime-тип файла по его расширению, написано в этой статье. В заголовках запроса также обязательно должны присутствовать данные об общем размере тела запроса, а именно длина всех кодированных полей формы. Эта информация передается заголовком "Content-Length: NNNN". То есть сперва в вашем обработчике формируется тело запроса, а только после него заголовок.

Читать статью целиком »
Просмотров: 12188 | Комментариев: 10

Автоматическое получение Яндекс тИЦ для сайтов

13.12.2011 | Категория: Web-мастеру и не только | Автор: ManHunter
Тематический индекс цитирования (тИЦ) используется в поисковой системе Яндекс и определяет "авторитетность" интернет-ресурсов. Этот индекс используется в различных СЕО-инструментах, однако сам Яндекс не предоставляет никаких средств для его легального получения. Но нам на помощь может прийти разработка самого Яндекса - Яндекс.Бар, в котором при серфинге отображается тИЦ открытого сайта. Очевидно, что эти данные Яндекс.Троян получает от самого сервера, осталось отследить любым сниффером, куда идет обращение и в каком формате. В отличие от Google PR, с Яндексом проблем нет. Никаких дополнительных контрольных сумм для ссылки считать не надо, да и тИЦ единый для всего домена. В итоге все ограничивается одним простым запросом типа:

http://bar-navig.yandex.ru/u?ver=2&show=32&url=http://www.manhunter.ru

В качестве значения последнего параметра url передается имя проверяемого домена. В ответ вернется XML-файл, подобный приведенному ниже:
  1. <?xml version="1.0" encoding="windows-1251" ?>
  2. <urlinfo>
  3.     <url domain="www.manhunter.ru"><![CDATA[/]]></url>
  4.     <yaca url="www.manhunter.ru"/>
  5.     <tcy rang="3" value="70"/>
  6.     <topics></topics>
  7.     <textinfo></textinfo>
  8. </urlinfo>
Искомое значение Яндекс тИЦ содержится в теге tcy, вытащить его оттуда можно простейшим парсером. Но злоупотреблять подобными запросами все-таки не надо, можно получить бан по IP. Значение тИЦ пересчитывается примерно раз в неделю, поэтому информацию достаточно загружать раз в час или вообще раз в сутки, а полученные данные кэшировать на своей стороне.

Просмотров: 6207 | Комментариев: 8

Релевантный поиск по базе MySQL

04.11.2011 | Категория: Web-мастеру и не только | Автор: ManHunter

Релевантный поиск по базе MySQL

Я уже писал о возможностях поиска с учетом морфологии, а теперь обещанная статья о релевантном поиске по базе MySQL. Как разъясняют словари, релевантность - в поисковых системах - мера соответствия результатов поиска задаче поставленной в запросе. То есть чем ближе найденный результат соответствует искомому, тем выше в результатах поиска он должен находиться. Применительно к выборке из базы, в строках результата релевантность должна быть представлена неким числовым значением, по которому эта выборка должна быть отсортирована.

Начнем с теории. Если мы ищем строку из нескольких слов среди нескольких текстов, то наибольшей релевантностью обладает текст, в котором встречается вся эта строка целиком и точно в том виде, как ее задали к поиску. Затем идут тексты, где есть все слова из искомой фразы, но расположенные не по порядку. После них идут тексты, где встречаются только отдельные слова, и, чем меньше слов из фразы, тем ниже релевантность. К тому же слова из заголовка текста должны иметь поисковый вес больше, чем такие же слова из текста.

Читать статью целиком »
Просмотров: 18828 | Комментариев: 13

01 ... 14 15 16 17 18 19 20 ... 25
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 3 (0.0055 сек.) / Память: 4.5 Mb
Наверх