
Быстрый поиск
Введите фрагмент названия статьи для поиска
Определение браузера посетителя сайта на PHP
16.11.2009 | Категория: Web-мастеру и не только | Автор: ManHunter
Для сбора внутренней статистики я написал простую функцию для определения браузеров посетителей сайта. За несколько месяцев активной "дрессировки" в нее были добавлены сигнатуры практически всех популярных браузеров, и вот уже достаточно длительное время она не обновляется. Информация берется из переменной окружения HTTP_USER_AGENT, но так как строка идентификации браузера формируется на стороне пользователя, то она может быть легко подделана. Например, при помощи расширения User Agent Switcher для браузера Firefox или какого-нибудь локального прокси-сервера. Поэтому 100% достоверной эту информацию считать никак нельзя. Но для подавляющего большинства случаев ее будет вполне достаточно. Функция возвращает строку с названием браузера и его версией типа Internet Explorer 6.0, Mozilla Firefox 3.0.14, или же Unknown, если браузер определить не удалось.Code (PHP) : Убрать нумерацию
- //-------------------------------------------------------------------
- // Функция определения браузера по данным поля User-Agent
- //-------------------------------------------------------------------
- function GetUserAgent() {
- // Получить переменную окружения
- $str=getenv('HTTP_USER_AGENT');
- // Попытаться определить известные браузеры по сигнатурам
- if (strpos($str,"Avant Browser",0)!==false) {
- return "Avant Browser";
- }
- elseif (strpos($str,"Acoo Browser",0)!==false) {
- return "Acoo Browser";
- }
- elseif (eregi("Iron/([0-9a-z\.]*)",$str,$pocket)) {
- return "SRWare Iron ".$pocket[1];
- }
- elseif (eregi("Chrome/([0-9a-z\.]*)",$str,$pocket)) {
- return "Google Chrome ".$pocket[1];
- }
- elseif (eregi("(Maxthon|NetCaptor)( [0-9a-z\.]*)?",$str,$pocket)) {
- return $pocket[1].$pocket[2];
- }
- elseif (strpos($str,"MyIE2",0)!==false) {
- return "MyIE2";
- }
- elseif (eregi("(NetFront|K-Meleon|Netscape|Galeon|Epiphany|Konqueror|".
- "Safari|Opera Mini)/([0-9a-z\.]*)",$str,$pocket)) {
- return $pocket[1]." ".$pocket[2];
- }
- elseif (eregi("Opera[/ ]([0-9a-z\.]*)",$str,$pocket)) {
- return "Opera ".$pocket[1];
- }
- elseif (eregi("Orca/([ 0-9a-z\.]*)",$str,$pocket)) {
- return "Orca Browser ".$pocket[1];
- }
- elseif (eregi("(SeaMonkey|Firefox|GranParadiso|Minefield|".
- "Shiretoko)/([0-9a-z\.]*)",$str,$pocket)) {
- return "Mozilla ".$pocket[1]." ".$pocket[2];
- }
- elseif (eregi("rv:([0-9a-z\.]*)",$str,$pocket) &&
- strpos($str,"Mozilla/",0)!==false) {
- return "Mozilla ".$pocket[1];
- }
- elseif (eregi("Lynx/([0-9a-z\.]*)",$str,$pocket)) {
- return "Lynx ".$pocket[1];
- }
- elseif (eregi("MSIE ([0-9a-z\.]*)",$str,$pocket)) {
- return "Internet Explorer ".$pocket[1];
- }
- else {
- // Это какой-то неизвестный браузер
- return "Unknown";
- }
- }
Просмотров: 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. Сперва скачаем эту библиотеку и воспользуемся Ассемблером, чтобы сжать какую-нибудь эталонную строку.Code (Assembler) : Убрать нумерацию
- format PE GUI 4.0
- entry start
- include 'win32a.inc'
- section '.data' data readable writeable
- strr db 'ManHunter' ; Строка для компрессии
- lend = $-strr
- bsize = 1000
- blen dd bsize
- tmp rb bsize
- tmp2 rb bsize
- tmp3 rb bsize
- mask db '%.2X ',0
- ;----------------------------------------------------------
- section '.code' code readable executable
- start:
- invoke compress,tmp,blen,strr,dword lend
- mov ecx,[blen]
- mov esi,tmp
- @@:
- push ecx
- movzx eax,byte [esi]
- invoke wsprintf,tmp2,mask,eax
- add esp,12
- invoke lstrcat,tmp3,tmp2
- inc esi
- pop ecx
- loop @b
- invoke MessageBox,HWND_DESKTOP,tmp3,NULL,MB_OK
- invoke ExitProcess,0
- ;----------------------------------------------------------
- section '.idata' import data readable writeable
- library kernel32,"kernel32.dll",\
- user32,"user32.dll",\
- zlib,"zlib1.dll"
- include "apia\kernel32.inc"
- include "apia\user32.inc"
- import zlib,\
- 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 определяется по расширению, можно анализировать внутреннюю структуру, но это, наверное, в данном случае лишнее и остается на совести вебмастера.Code (PHP) : Убрать нумерацию
- //-------------------------------------------------------------------
- // Функция нанесения графического водяного знака на изображение
- // Copyright (C) ManHunter / PCL
- // http://www.manhunter.ru
- //-------------------------------------------------------------------
- // Параметры вызова:
- // $picture - путь к файлу картинки на сервере
- // $marker - путь к файлу водяного знака на сервере
- // $opacity - процент прозрачности
- // $watermark_position - положение водяного знака на картинке
- //-------------------------------------------------------------------
- // Константы положения водяного знака на картинке
- define ("WATERMARK_LEFT_BOTTOM",0);
- define ("WATERMARK_LEFT_TOP",1);
- define ("WATERMARK_RIGHT_BOTTOM",2);
- define ("WATERMARK_RIGHT_TOP",3);
- define ("WATERMARK_CENTER",4);
- function Watermark_PNG_Image($picture, $marker, $opacity=100,
- $watermark_position=WATERMARK_RIGHT_BOTTOM) {
- // Проверки на наличие файлов и допустимые параметры
- if (!file_exists($picture)) { return false; }
- if (!file_exists($marker)) { return false; }
- // Получить размеры исходного изображения
- list ($sx,$sy)=GetImageSize($picture);
- if ($sx==0 || $sy==0) { return false; }
- // Получить размеры маркера
- list ($mx,$my)=GetImageSize($marker);
- if ($mx==0 || $my==0 || $sx<($mx+20) || $sy<($my+20)) { return false; }
- // Если расширение маркера не .PNG, то выход с ошибкой
- if (strtolower(substr($marker,-4))!=".png") { return false; }
- // Если расширения нет, то выход с ошибкой
- $pocket=Array();
- eregi("\.([a-z]*)$",$picture,$pocket);
- if ($pocket[1]=="") { return false; }
- // На основании расширения создать картинку
- switch (strtolower($pocket[1])) {
- case "jpeg":
- case "jpg": {
- if (!$im=@ImageCreateFromJpeg($picture)) { return false; }
- break;
- }
- case "gif": {
- if (!$im=@ImageCreateFromGif($picture)) { return false; }
- break;
- }
- case "png": {
- if (!$im=@ImageCreateFromPng($picture)) { return false; }
- break;
- }
- default: { return false; }
- }
- // Получить координаты блока на картинке для нанесения надписи
- switch ($watermark_position) {
- case WATERMARK_LEFT_BOTTOM: {
- $pos_x=10;
- $pos_y=$sy-$my-10;
- break;
- }
- case WATERMARK_RIGHT_BOTTOM: {
- $pos_x=$sx-$mx-10;
- $pos_y=$sy-$my-10;
- break;
- }
- case WATERMARK_LEFT_TOP: {
- $pos_x=10;
- $pos_y=10;
- break;
- }
- case WATERMARK_RIGHT_TOP: {
- $pos_x=$sx-$mx-10;
- $pos_y=10;
- break;
- }
- case WATERMARK_CENTER: {
- $pos_x=intval($sx/2-$mx/2);
- $pos_y=intval($sy/2-$my/2);
- break;
- }
- default: {
- imageDestroy($im);
- return false;
- }
- }
- // Нанести водяной знак с нужной прозрачностью
- $watermark=@ImageCreateFromPng($marker);
- ImageCopyMerge($im, $watermark, $pos_x, $pos_y, 0, 0, $mx, $my, $opacity);
- ImageDestroy($watermark);
- // Записать измененный файл на место
- switch (strtolower($pocket[1])) {
- case "jpeg":
- case "jpg": {
- ImageJPEG($im,$picture,90);
- break;
- }
- case "gif": {
- ImageGIF($im,$picture);
- break;
- }
- case "png": {
- ImagePNG($im,$picture);
- break;
- }
- }
- ImageDestroy($im);
- return true;
- }
Читать статью целиком »
Просмотров: 9515 | Комментариев: 13


