Blog. Just Blog

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

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

Определение браузера посетителя сайта на PHP

16.11.2009 | Категория: Web-мастеру и не только | Автор: ManHunter
Для сбора внутренней статистики я написал простую функцию для определения браузеров посетителей сайта. За несколько месяцев активной "дрессировки" в нее были добавлены сигнатуры практически всех популярных браузеров, и вот уже достаточно длительное время она не обновляется. Информация берется из переменной окружения HTTP_USER_AGENT, но так как строка идентификации браузера формируется на стороне пользователя, то она может быть легко подделана. Например, при помощи расширения User Agent Switcher для браузера Firefox или какого-нибудь локального прокси-сервера. Поэтому 100% достоверной эту информацию считать никак нельзя. Но для подавляющего большинства случаев ее будет вполне достаточно. Функция возвращает строку с названием браузера и его версией типа Internet Explorer 6.0, Mozilla Firefox 3.0.14, или же Unknown, если браузер определить не удалось.
  1. //-------------------------------------------------------------------
  2. // Функция определения браузера по данным поля User-Agent
  3. //-------------------------------------------------------------------
  4. function GetUserAgent() {
  5.   // Получить переменную окружения
  6.   $str=getenv('HTTP_USER_AGENT');
  7.   // Попытаться определить известные браузеры по сигнатурам
  8.   if (strpos($str,"Avant Browser",0)!==false) {
  9.     return "Avant Browser";
  10.   }
  11.   elseif (strpos($str,"Acoo Browser",0)!==false) {
  12.     return "Acoo Browser";
  13.   }
  14.   elseif (eregi("Iron/([0-9a-z\.]*)",$str,$pocket)) {
  15.     return "SRWare Iron ".$pocket[1];
  16.   }
  17.   elseif (eregi("Chrome/([0-9a-z\.]*)",$str,$pocket)) {
  18.     return "Google Chrome ".$pocket[1];
  19.   }
  20.   elseif (eregi("(Maxthon|NetCaptor)( [0-9a-z\.]*)?",$str,$pocket)) {
  21.     return $pocket[1].$pocket[2];
  22.   }
  23.   elseif (strpos($str,"MyIE2",0)!==false) {
  24.     return "MyIE2";
  25.   }
  26.   elseif (eregi("(NetFront|K-Meleon|Netscape|Galeon|Epiphany|Konqueror|".
  27.           "Safari|Opera Mini)/([0-9a-z\.]*)",$str,$pocket)) {
  28.     return $pocket[1]." ".$pocket[2];
  29.   }
  30.   elseif (eregi("Opera[/ ]([0-9a-z\.]*)",$str,$pocket)) {
  31.     return "Opera ".$pocket[1];
  32.   }
  33.   elseif (eregi("Orca/([ 0-9a-z\.]*)",$str,$pocket)) {
  34.     return "Orca Browser ".$pocket[1];
  35.   }
  36.   elseif (eregi("(SeaMonkey|Firefox|GranParadiso|Minefield|".
  37.           "Shiretoko)/([0-9a-z\.]*)",$str,$pocket)) {
  38.     return "Mozilla ".$pocket[1]." ".$pocket[2];
  39.   }
  40.   elseif (eregi("rv:([0-9a-z\.]*)",$str,$pocket) &&
  41.           strpos($str,"Mozilla/",0)!==false) {
  42.     return "Mozilla ".$pocket[1];
  43.   }
  44.   elseif (eregi("Lynx/([0-9a-z\.]*)",$str,$pocket)) {
  45.     return "Lynx ".$pocket[1];
  46.   }
  47.   elseif (eregi("MSIE ([0-9a-z\.]*)",$str,$pocket)) {
  48.     return "Internet Explorer ".$pocket[1];
  49.   }
  50.   else {
  51.     // Это какой-то неизвестный браузер
  52.     return "Unknown";
  53.   }
  54. }
Кроме статистики определение браузера посетителя можно использовать для переадресации или выдачи определенных страниц сайта, показа целевых информационных блоков, подгонки стилей или дизайна и т.п. При необходимости функцию можно легко расширить собственными сигнатурами, например, добавить определение поисковых роботов. Для определения браузеров мобильных устройств используется отдельный скрипт.

Просмотров: 19802 | Комментариев: 16

Определение географического положения по IP-адресу

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

Определение географического положения по IP-адресу

Определение страны и города посетителя сайта по его IP-адресу применяется во многих случаях. Например, автоматическая подстройка языка отображения сайта, более точный таргетинг рекламных или информационных блоков сайта, разграничение доступа к разделам сайта для разных источников трафика, а также для многих других целей. Наиболее полные базы географического положения IP-адресов в настоящее время предоставляет компания MaxMind в своей базе GeoLite City. Бесплатный вариант базы содержит данные с точностью до города, его можно скачать с сайта в бинарном формате (в распакованном виде около 30 мегабайт) и в формате CSV (в распакованном виде около 130 мегабайт). На сайте также можно оформить подписку на коммерческие варианты базы, содержащие данные с точностью до улиц и обновляющиеся еженедельно, но это только если вашему проекту действительно требуется такая точность. Обновления бесплатной базы выходят регулярно, обычно в первых числах каждого месяца. Пример работы скрипта с коммерческой географической базой можно посмотреть на сайте MaxMind. Там же на сайте можно скачать бесплатные базы стран мира, почтовые индексы некоторых стран и много других полезных данных. К сожалению, самые вкусности предоставляются только за деньги.

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

Защита файлов на сервере от прямых ссылок (antileech)

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

Защита файлов на сервере от прямых ссылок (antileech)

Защита от скачивания файлов по прямым ссылкам, или как ее еще называют "антилич-защита" - задача не менее важная, чем защита остального контента сайта. Грамотно сделанная система защиты от прямых ссылок позволит разграничивать доступ к файлам разным категориям пользователей, вести подробную статистику скачиваний, скрывать истинное место размещения файлов, а также привлечет новых посетителей на ваш сайт. А то обычно получается так, что сторонние сайты публикуют прямую ссылку на файл, размещенный на вашем сервере, они получают посетителей, рейтинги, стригут купоны с рекламы, а вы получаете только счета за трафик. Справедливое разделение? Нет. В последнее время появилось огромное количество файлообменных сервисов, и на каждом из них используется своя система антилич-защиты, где-то более удачно реализованная, где-то менее. За счет этого они имеют возможность регулировать скорость отдачи файлов премиум-пользователям и халявщиками, определять лимит на скачивание по времени, поддерживать или не поддерживать докачку и т.д. В этой статье я расскажу о самом принципе построения антилич-системы, а также приведу пример простейшего, но вполне работоспособного скрипта.

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

gzuncompress и gzinflate: Assembler vs PHP

11.08.2009 | Категория: Темная сторона Силы | Автор: ManHunter
При разработке проекта Massacre возникла необходимость реализовать функции распаковки PHP-кода на Ассемблере. В этой статье я распишу все выкладки по этому вопросу. Кому-нибудь пригодится - хорошо, не пригодится - оставлю для себя, чтобы не забыть. Как всегда, начнем с теории. Функции gzuncompress и gzinflate обратны к функциям gzcompress и gzdeflate, соответственно. Все они используют алгоритм сжатия LZW, который также используется в бесплатной библиотеке zlib. Сперва скачаем эту библиотеку и воспользуемся Ассемблером, чтобы сжать какую-нибудь эталонную строку.
  1. format PE GUI 4.0
  2. entry start
  3.  
  4. include 'win32a.inc'
  5.  
  6. section '.data' data readable writeable
  7.  
  8. strr    db 'ManHunter'  ; Строка для компрессии
  9. lend    = $-strr
  10. bsize   = 1000
  11.  
  12. blen    dd bsize
  13.  
  14. tmp     rb bsize
  15. tmp2    rb bsize
  16. tmp3    rb bsize
  17.  
  18. mask    db '%.2X ',0
  19.  
  20. ;----------------------------------------------------------
  21.  
  22. section '.code' code readable executable
  23. start:
  24.  
  25.         invoke  compress,tmp,blen,strr,dword lend
  26.  
  27.         mov     ecx,[blen]
  28.         mov     esi,tmp
  29. @@:
  30.         push    ecx
  31.         movzx   eax,byte [esi]
  32.         invoke  wsprintf,tmp2,mask,eax
  33.         add     esp,12
  34.         invoke  lstrcat,tmp3,tmp2
  35.         inc     esi
  36.         pop     ecx
  37.         loop    @b
  38.  
  39.         invoke  MessageBox,HWND_DESKTOP,tmp3,NULL,MB_OK
  40.         invoke  ExitProcess,0
  41.  
  42. ;----------------------------------------------------------
  43.  
  44. section '.idata' import data readable writeable
  45.  
  46. library kernel32,"kernel32.dll",\
  47.         user32,"user32.dll",\
  48.         zlib,"zlib1.dll"
  49.  
  50. include "apia\kernel32.inc"
  51. include "apia\user32.inc"
  52.  
  53.   import zlib,\
  54.          compress,'compress'
В окне будет показана следующая строка:

78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
Часть строки я специально выделил красным цветом, дальше будет понятно зачем это сделано.

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

Нанесение графических водяных знаков на изображение

13.07.2009 | Категория: Web-мастеру и не только | Автор: ManHunter
Наносить текстовые надписи на картинки средствами PHP мы уже умеем. Теперь рассмотрим как делать то же самое, только на этот раз вместо текста будет графический маркер. Сам маркер представляет собой картинку в формате PNG-8 (глубина цвета - 8 бит), допускается прозрачность и произвольная форма. Если маркер будет с другой глубиной цвета, то при наложении прозрачный цвет будет заменен на черный. Другой формат маркеров не поддерживается! Файл PNG определяется по расширению, можно анализировать внутреннюю структуру, но это, наверное, в данном случае лишнее и остается на совести вебмастера.
  1. //-------------------------------------------------------------------
  2. // Функция нанесения графического водяного знака на изображение
  3. // Copyright (C) ManHunter / PCL
  4. // http://www.manhunter.ru
  5. //-------------------------------------------------------------------
  6. // Параметры вызова:
  7. // $picture - путь к файлу картинки на сервере
  8. // $marker - путь к файлу водяного знака на сервере
  9. // $opacity - процент прозрачности
  10. // $watermark_position - положение водяного знака на картинке
  11. //-------------------------------------------------------------------
  12.  
  13. // Константы положения водяного знака на картинке
  14. define ("WATERMARK_LEFT_BOTTOM",0);
  15. define ("WATERMARK_LEFT_TOP",1);
  16. define ("WATERMARK_RIGHT_BOTTOM",2);
  17. define ("WATERMARK_RIGHT_TOP",3);
  18. define ("WATERMARK_CENTER",4);
  19.  
  20. function Watermark_PNG_Image($picture$marker$opacity=100,
  21.                            $watermark_position=WATERMARK_RIGHT_BOTTOM) {
  22.   // Проверки на наличие файлов и допустимые параметры
  23.   if (!file_exists($picture)) { return false; }
  24.   if (!file_exists($marker)) { return false; }
  25.  
  26.   // Получить размеры исходного изображения
  27.   list ($sx,$sy)=GetImageSize($picture);
  28.   if ($sx==|| $sy==0) { return false; }
  29.  
  30.   // Получить размеры маркера
  31.   list ($mx,$my)=GetImageSize($marker);
  32.   if ($mx==|| $my==|| $sx<($mx+20) || $sy<($my+20)) { return false; }
  33.  
  34.   // Если расширение маркера не .PNG, то выход с ошибкой
  35.   if (strtolower(substr($marker,-4))!=".png") { return false; }
  36.  
  37.   // Если расширения нет, то выход с ошибкой
  38.   $pocket=Array();
  39.   eregi("\.([a-z]*)$",$picture,$pocket);
  40.   if ($pocket[1]=="") { return false; }
  41.  
  42.   // На основании расширения создать картинку
  43.   switch (strtolower($pocket[1])) {
  44.     case "jpeg":
  45.     case "jpg": {
  46.       if (!$im=@ImageCreateFromJpeg($picture)) { return false; }
  47.       break;
  48.     }
  49.     case "gif": {
  50.       if (!$im=@ImageCreateFromGif($picture)) { return false; }
  51.       break;
  52.     }
  53.     case "png": {
  54.       if (!$im=@ImageCreateFromPng($picture)) { return false; }
  55.       break;
  56.     }
  57.     default: { return false; }
  58.   }
  59.  
  60.   // Получить координаты блока на картинке для нанесения надписи
  61.   switch ($watermark_position) {
  62.     case WATERMARK_LEFT_BOTTOM: {
  63.       $pos_x=10;
  64.       $pos_y=$sy-$my-10;
  65.       break;
  66.     }
  67.     case WATERMARK_RIGHT_BOTTOM: {
  68.       $pos_x=$sx-$mx-10;
  69.       $pos_y=$sy-$my-10;
  70.       break;
  71.     }
  72.     case WATERMARK_LEFT_TOP: {
  73.       $pos_x=10;
  74.       $pos_y=10;
  75.       break;
  76.     }
  77.     case WATERMARK_RIGHT_TOP: {
  78.       $pos_x=$sx-$mx-10;
  79.       $pos_y=10;
  80.       break;
  81.     }
  82.     case WATERMARK_CENTER: {
  83.       $pos_x=intval($sx/2-$mx/2);
  84.       $pos_y=intval($sy/2-$my/2);
  85.       break;
  86.     }
  87.     default: {
  88.       imageDestroy($im);
  89.       return false;
  90.     }
  91.   }
  92.  
  93.   // Нанести водяной знак с нужной прозрачностью
  94.   $watermark=@ImageCreateFromPng($marker);
  95.   ImageCopyMerge($im$watermark$pos_x$pos_y00$mx$my$opacity);     
  96.   ImageDestroy($watermark);
  97.  
  98.   // Записать измененный файл на место
  99.   switch (strtolower($pocket[1])) {
  100.     case "jpeg":
  101.     case "jpg": {
  102.       ImageJPEG($im,$picture,90);
  103.       break;
  104.     }
  105.     case "gif": {
  106.       ImageGIF($im,$picture);
  107.       break;
  108.     }
  109.     case "png": {
  110.       ImagePNG($im,$picture);
  111.       break;
  112.     }
  113.   }
  114.   ImageDestroy($im);
  115.   return true
  116. }
Параметры вызова функции: $picture - полный путь к файлу на сервере, поддерживаются форматы JPG, GIF, PNG. Файл должен быть доступен для записи, так как после нанесения водяного знака он будет перезаписан с тем же именем. $marker - полный путь к файлу водяного знака в формате PNG. $opacity - прозрачность водяного знака в процентах, необязательный параметр, по умолчанию 100%. $watermark_position - положение маркера на картинке, необязательный параметр, по умолчанию правый нижний угол изображения. Доступные значения определены константами, прочие значения игнорируются: 0 - левый нижний угол, 1 - левый верхний угол, 2 - правый нижний угол (значение по умолчанию), 3 - правый верхний угол, 4 - центр изображения.

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

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2026
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 3 (0.0062 сек.) / Память: 4.5 Mb
Наверх