3D Captcha

<?php
/**
 * 3D Captcha
 * автор: KAndy (http://kandy.habrahabr.ru/)
 * 30.07.08
*/
 
/*
Прочитал на хабрахабре интересный топик
http://habrahabr.ru/blog/php/45463.html
понравилась реализация 
капчи, все четко и ничего лишнего, в стиле ооп
*/
 
$capthca = new Capthca3d(); 
$capthca->render(); 
 
 
class Capthca3d{ 
    const CHARS = 'WEafRTYIPAGHJKXBNM3479j'; 
    protected $hypot = 8; 
    protected $image = null; 
     
    protected $text = ''; 
     
    public function __construct() 
    { 
        $this->time = microtime(true); 
        $this->generateCode(); 
     
    } 
    protected function generateCode() 
    { 
        $chars = self::CHARS; 
        for($i =0; $i<3; $i++){ 
            $this->text .= $chars{ mt_rand(0,22)}; 
        } 
    } 
     
    public function getText() 
    { 
        return $this->text; 
    } 
    protected function getProection($x1,$y1,$z1) 
    { 
        $x = $x1 * $this->hypot;  
        $y = $z1 * $this->hypot; 
        $z = -$y1 * $this->hypot; 
         
        $xx = 0.707106781187;  
        $xy = 0; 
        $xz = -0.707106781187;  
         
        $yx = 0.408248290464;  
        $yy = 0.816496580928;  
        $yz = 0.408248290464; 
         
        $cx = $xx*$x + $xy*$y + $xz*$z; 
        $cy = $yx*$x + $yy*$y + $yz*$z+ 20 * $this->hypot; 
        return array( 
            'x' => $cx, 
            'y' => $cy 
            );  
    } 
     
    function zFunction($x,$y){ 
        $z = imagecolorat($this->image,$y/2,$x/2)>0?2.6:0; 
        if( $z != 0 ){ 
            $z += mt_rand(0,60)/100; 
        } 
        $z += 1.4 * sin(($x+$this->startX)*3.141592654/15)*sin(($y+$this->startY)*3.141592654/15); 
        return $z; 
    } 
    public function render()     
    { 
        $xx =30; 
         $yy =60; 
         
         $this->image = imageCreateTrueColor($yy * $this->hypot  , $xx * $this->hypot); 
         
        $whiteColor = imageColorAllocate($this->image,255,255,255); 
        imageFilledRectangle($this->image,0,0,$yy * $this->hypot  , $xx * $this->hypot,$whiteColor); 
         
        $textColor = imageColorAllocate($this->image,0,0,0); 
        imageString($this->image, 5, 3, 0, $this->text, $textColor); 
         
         
         $this->startX = mt_rand(0,$xx);     
         $this->startY = mt_rand(0,$yy); 
         
         $coordinates = array(); 
          
        for($x = 0; $x < $xx + 1; $x++){ 
            for($y = 0; $y < $yy + 1; $y++){ 
                $coordinates[$x][$y] = $this->getProection($x,$y,$this->zFunction($x,$y)); 
             } 
         } 
          
        for($x = 0; $x < $xx; $x++){ 
            for($y = 0; $y < $yy; $y++){ 
                 $coord = array(); 
                 $coord[] = $coordinates[$x][$y]['x']; 
                 $coord[] = $coordinates[$x][$y]['y']; 
                  
                 $coord[] = $coordinates[$x+1][$y]['x']; 
                 $coord[] = $coordinates[$x+1][$y]['y']; 
                  
                 $coord[] = $coordinates[$x+1][$y+1]['x']; 
                 $coord[] = $coordinates[$x+1][$y+1]['y']; 
                  
                 $coord[] = $coordinates[$x][$y+1]['x']; 
                 $coord[] = $coordinates[$x][$y+1]['y']; 
                 
                $c = (int) ($this->zFunction($x,$y)*32); 
                $linesColor = imageColorAllocate($this->image, $c, $c, $c); 
                imageFilledPolygon($this->image, $coord, 4, $whiteColor); 
                imagePolygon($this->image, $coord, 4, $linesColor); 
             } 
         } 
         
        $textColor = imageColorAllocate($this->image,0,0,0); 
        imageString($this->image, 5, 3, 0, $this->text, $whiteColor); 
        imageString($this->image, 1, 3, 0, (microtime(true)-$this->time), $textColor); 
        header('Content-Type: image/png'); 
         
        imagepng($this->image); 
        imagedestroy($this->image); 
    } 
}
 
?>
4 ноября 2014, 07:12

Исправление всех таблиц MYISAM в MYSQL

Если вы до сих пор используете движок MYISAM, то наверняка встречали такую ошибку после внезапной перезагрузки системы
Table 'tbl' is marked as crashed and should be repaired

Да, вот какая плата за простоту этого движка.
Лекарство такое
mysqlcheck -u root -pROOT_PASSWORD --auto-repair --optimize --all-databases

Вместо ROOT_PASSWORD конечно же надо ввести рут пароль от mysql
4 ноября 2014, 07:12

Создание и вывод древовидных структур на PHP

Древовидные структуры встречаются в повседневной жизни довольно часто. Это различные списки категорий, комментарии, разделы каталогов.
При не очень большом объеме выводимых элементов организовать их иерархический вывод проще всего на php.
Для этого нам потребуется вот такая структура
id | pid | name

id - это ид текущего элемента
pid - это ид родительского элемента (для элемента первого уровня это значение примем 0)
name - это имя элемента

Фактически, это структура таблицы в базе данных.
Получить массив данных из базы очень просто
SELECT * FROM table ORDER BY pid, id

Теперь сам скрипт вывода
// это наш массив из базы, но для примера задаю данные в пхп массиве
$data = array(
    array('id' => 1, 'pid' => 0, 'name' => '1'),
    array('id' => 2, 'pid' => 1, 'name' => '1.1'),
    array('id' => 3, 'pid' => 2, 'name' => '1.1.1'),
    array('id' => 4, 'pid' => 0, 'name' => '2'),
    array('id' => 5, 'pid' => 0, 'name' => '3'),
    array('id' => 6, 'pid' => 5, 'name' => '3.1'),
    array('id' => 7, 'pid' => 5, 'name' => '3.2'),
);

//теперь создаем массив в виде дерева
$tree = array();
foreach ($data as $row) {
    $tree[(int) $row['pid']][] = $row;
}

//ну и рекурсивная функция для вывода дерева
function treePrint($tree, $pid=0) {
    if (empty($tree[$pid]))
        return;
    echo '<ul>';
    foreach ($tree[$pid] as $k => $row) {
        echo '<li>';
        echo $row['name'];
        if (isset($tree[$row['id']]))
            treePrint($tree, $row['id']);
        echo '</li>';
    }
    echo '</ul>';
}

//вызов функции
treePrint($tree);


Результат должен быть таким
11.11.1.1 2 3 3.1 3.2
4 ноября 2014, 07:12

Организация 301 редиректа в NGINX

Некоторые посетители упорно набирают www.site.ru вместо site.ru и поисковые боты так и наровят сделать из вашего сайта сразу два, в итоге размазав выдачу.
Для искоренения www будет использовать 301 редирект и nginx

неправильный рабочий вариант (зато можно поместить в дефалт секцию и забыть ;) )
if ($host ~* www\.(.*)) {
    set $host_without_www $1;
    rewrite ^(.*)$ http://$host_without_www$1 permanent;
}


правильный рабочий вариант с двумя секциями server
server {
    listen 80;
    server_name www.site.ru;
    rewrite ^ $scheme://site.ru$request_uri permanent;
}

server {
    listen 80;
    server_name site.ru;
    ............
}


Еще один вариант без rewrite
server {
    listen 80;
    server_name www.site.ru;
    return 301 $scheme://site.ru$request_uri;
}


Обратите внимание, что везде используется ключевое слово permanent.
4 ноября 2014, 07:12

Заставляем syslogd слушать localhost

В файле /etc/syslog.conf прописывается
syslogd_flags = "-s -s"

А в /etc/rc.conf дописываем
syslogd_flags="-s -b 127.0.0.1"

Далее перезапускаем демона
service syslogd restart
4 ноября 2014, 07:12

Заставляем proftpd слушать определенный ip адрес

По умолчанию proftpd слушает все адреса по 21 порту.
Чтобы назначить только 1 адрес необходимо в /usr/local/etc/proftpd.conf добавить следующие строки
SocketBindTight                 on
DefaultAddress                 xxx.xxx.xxx.xxx
4 ноября 2014, 07:12

Создание jail во FreeBsd

Иногда бывает полезно иметь в работающей системе еще одну или несколько виртуальных систем.
Во FreeBsd средством виртуализации является jail. Примеров применения множество: вы можете создавать jailы на своем сервере для знакомых или клиентов, и это обезопасит вашу систему от их проделок, вы можете поместить (это даже рекомендуется) разные сервисы в отдельные jail, например, mysql в одной системе, apache в другой. Таким образом, взлом mysql сервера ничем не грозит веб серверу.

Управлять jailами я буду при помощи ezjail, конечно, труъ-админы могут катать километры шелл скриптов и управлять всем вручную, но уж извольте..
Для начала установим ezjail
cd /usr/ports/sysutils/ezjail
make install clean
rehash


Теперь проинсталируемся
ezjail-admin install


Если вы еще не собирали мир в вашей системе, то придется это сделать.
Процедура длительная, может занять несколько часов, и потребуется ребут.
cd /usr/scr
make buildworld
make buildkernel
make installkernel
reboot


На сообщения mergemaster можно нажимать enter, конфликтов быть не должно.
mergemaster -p
cd /usr/src
make installworld
mergemaster
reboot


Теперь после сборки мира и 2 ребутов можно проапргейдить наш jail (тоже не быстрое дело)
ejzail-admin update -p -i


Для успешной работы jail ему необходим ip адрес. Внешний ip адрес каждому jail это довольно жирно, поэтому давайте выделим ему локальный ip, например, 192.168.0.11
Давайте добавим этот адрес в нашу сетевую карту em0, а также не забудем разместить запись в /etc/rc.conf чтобы при перезагрузке ничего не потерялось
ifconfig em0 alias 192.168.0.11 netmask 0xffffffff
echo 'ifconfig_em0_alias1="inet 192.168.0.11  netmask 255.255.255.0"' >> /etc/rc.conf


Важным условием выбора адреса является то, чтобы этот ип адрес не использовал ниодин сервис в вашей системе.
Пробуем создать jail
ezjail-admin create -r /usr/home/jails/test test 192.168.0.11


Скорее всего вы получите предупреждения, что ip 192.168.0.11 слушается другими сервисами, типа такого
  This may cause some confusion, here they are:
mysql    mysqld     6923  11 tcp4 6 *:3306                *:*
www      proftpd    1400  0  tcp4 6 *:21                  *:*
root     syslogd    1060  9  udp4   *:514                 *:*

Вам нужно вырубить прослушивание всех ip адресов у этих сервисов (это логично даже с точки зрения безопасности). Как это сделать можете почитать в других статьях на этом сайте.

Когда вы отключите прослушивание ip адреса везде, тогда можно запускать jail.
Но перед запуском сначала добавим его в автозагрузку
echo 'ezjail_enable="YES"' >> /etc/rc.conf


Давайте теперь запустим созданный jail
ezjail-admin start test

Проверим запущенные jails в системе
jls

Если все нормально, то должно выдать нечто такое
# jls
   JID  IP Address      Hostname                      Path
     1  192.168.0.11    test                      /usr/jails/test

Отлично, теперь у нас есть работающий jail!
Прежде чем лезть в него, нужно сразу скопировать файл /etc/resolv.conf чтобы разрешались днс адреса
cp /etc/resolv.conf /usr/jails/test/etc


Также, чтобы пинговаться внутри jail надо добавить пару строк в /etc/sysctl.conf
echo 'security.jail.allow_raw_sockets=1' >> /etc/sysctl.conf
echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf

Перезапустим сервис
service sysctl restart


Все, теперь можно зайти в клетку
jexec 1 csh

*некоторое пояснение: 1 это тот самый JID который показывался командой jls, csh это версия шелла

Первым делом в клетке необходимо создать файл /etc/fstab
touch /etc/fstab
ee /etc/rc.conf

Открываем редактором /etc/rc.conf и пишем туда
network_interfaces=""
rpcbind_enable="NO"
cron_flags="$cron_flags -J 15"
syslogd_flags="-ss"

sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

sshd_enable="YES"

Проверяем локальный ping
test# ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.010 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.012 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.014 ms

Отлично, пинг работает.

Теперь на счет внешних соединений: Если вы тестируете это на локалке, то внешние соединения из клетки заработают, если же вы делаете это на сервере, то скорее всего пакеты изнутри клетки во внешнюю сеть будут резаться уровнем выше. Для того, чтобы сеть в клетке работала нужно прибегнуть к помощи файрвола.
В качестве файрвола я буду использовать pf. Нужно выйти из клетки перед тем, как настраивать файрвол
test# exit


Оказавшись в основной системе нужно подгрузить pf как модуль ядра
kldload pf
kldstat
echo 'pf_enable="YES"' >> /etc/rc.conf


Создадим файл /etc/pf.conf (xxx.xxx.xxx.xxx это внешний ип адрес вашего сервера), em0 это сетевой интерфейс
В pf.conf пишем
pub="xxx.xxx.xxx.xxx" 

jail_net="192.168.0.11/32"
jail="192.168.0.11"

if="em0"
 
set block-policy return
set skip on lo
scrub in

nat on $if from $jail to !$jail_net -> $pub 
#создали nat

В конце правила не забудьте пустую строку! Теперь наша клетка находится за натом, и для хостера пакеты из нее не будут отличаться от пакетов из основной системы, и он не будет их срезать.

Теперь запустим файрвол и применим эти правила
pfctl -e
pfctl -f /etc/pf.conf


Зайдем еще раз в клетку и пинганем яндекс
jexec 1 csh
test# ping ya.ru
PING ya.ru (87.250.250.3): 56 data bytes
64 bytes from 87.250.250.3: icmp_seq=0 ttl=57 time=65.462 ms
64 bytes from 87.250.250.3: icmp_seq=1 ttl=57 time=76.410 ms

Отлично, теперь сеть работает и у нас есть отдельная виртуальная система.
4 ноября 2014, 07:12

Вопрос про NGINX и переменную в proxy_pass (пофикшено)

location / {
set $h "site.ru";
proxy_pass http://$h;
resolver 8.8.8.8;
}

это работает, запросы /aaa идут на site.ru/aaa

Допустим, надо чуть-чуть поменять путь
location /new/ {
rewrite /new/(.+)$ /$1 break;
proxy_pass http://site.ru;
}

это тоже работает, запросы /new/aaa идут на site.ru/aaa

А вот комбинация 2 вариантов уже не работает
location /new/ {
set $h "site.ru";
rewrite /new/(.+)$ /$1 break;
proxy_pass http://$h;
resolver 8.8.8.8;
}

запросы /new/aaa идут site.ru/new/aaa

Кто знает, как задать хост в переменной и изменить путь?
вопрос на форуме nginx

В nginx начиная с версии 1.0 это пофикшено.
4 ноября 2014, 07:12

Установка и настройка MYSQL 5.5 на FreeBsd 8.2

Сначала ставим весь софт, а именно mysql server и mysql client, делается это очень просто из портов
cd /usr/ports/databases/mysql55-server 
make install clean
rehash


Ставится не так уж быстро, как хотелось бы, поэтому идем пить чай.
Когда сервер и клиент готовы, переходим к инициализации наших баз
cd /usr/local
mysql_install_db


Внимание! Если запустить mysql_install_db не из директории /usr/local то скорее всего будет ошибка.
Этот небольшой нюанс может сэкономит вам пару нервных клеток.

Инициализация создает базу mysql в системе.
Теперь добавим mysql в автозагрузку и запустим его
echo 'mysql_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/mysql-server start


Если не запустилось смотрим лог ошибок
tail -f /var/db/mysql/`uname -a | awk '{print $2}'`.err


Если mysql заработал можно приступать к настройке.
Первым делом скопируем файл настроек my.cnf
cp /usr/local/share/mysql/my-huge.cnf /etc/my.cnf
/usr/local/etc/rc.d/mysql-server restart

Я выбрал my-huge.cnf потому что это для систем с 1-2Гб памяти.
Посмотрите этот каталог, там есть еще несколько штатных конфигов, подберите для себя оптимальный.
Также можно поковырять в my.cnf и подкрутить там всякое.

Теперь нужно поудалять ненужные базы и юзеров, еще поставить пароль для рута.
mysql -u root
>drop database test;
>UPDATE mysql.user SET Password=PASSWORD('newpwd') WHERE User='root';
>delete from mysql.user where password='';
>FLUSH PRIVILEGES;
>exit;
service mysql-server restart

Отлично, теперь для рута будет стоять пароль newpwd

Теперь давайте создадим базу snippetsdb и юзера snippets
Заходим в mysql рутом
mysql -u root -pnewpwd
>create database snippets;
>grant  usage  on snippetsdb.*  to snippets@localhost  identified by 'пароль';
>grant all privileges on snippetsdb.*  to snippets@localhost;


База и юзер созданы.

Еще можно создать некого юзера admin и разрешить ему управлять базами удаленно
GRANT ALL PRIVILEGES ON *.* TO admin@"%" IDENTIFIED BY 'some_password' WITH GRANT OPTION;

Оставляйте вопросы в комментариях.
4 ноября 2014, 07:12

Установка ffmpeg-php на Centos 5

Внезапно на выделенном сервере стали делаться косячные скриншоты, типа вот таких


Скриншоты создавались через ffmpeg-php. Первая мысль была верной: переустановка ffmpeg-php
[root@www ~]# yum install ffmpeg ffmpeg-devel php-devel 
[root@www ~]# cd /usr/src
[root@www ~]# wget http://switch.dl.sourceforge.net/project/ffmpeg-php/ffmpeg-php/0.6.0/ffmpeg-php-0.6.0.tbz2
[root@www ~]# tar xjf ffmpeg-php-0.6.0.tbz2
[root@www ~]# cd ffmpeg-php-0.6.0
[root@www ~]# phpize
[root@www ~]# ./configure –-enable-shared -–prefix=/usr
[root@www ~]# make

Но тут я встретился с очень интересной ошибкой
/usr/src/ffmpeg-php-0.6.0/ffmpeg_frame.c:421: error: 'PIX_FMT_RGBA32' undeclared (first use in this function)
 make: *** [ffmpeg_frame.lo] Error 1


Оказывается, ффмпег-пхп кривой! Патчим
cd /usr/src/ffmpeg-php-0.6.0
wget http://snippets.pp.ru/data/ffmpeg_frame.c.patch
patch -p0 ffmpeg_frame.c < ffmpeg_frame.c.patch
make clean && make && make install

Если ругается на make и patch то
yum install make patch


Я и без патча решал проблему вот так (но с патчем удобнее)

Открываем файл ffmpeg_frame.c (он в /usr/src/ffmpeg-php-0.6.0/)
Правим там везде PIX_FMT_RGBA32 на PIX_FMT_RGB32

После этого можно устанавливать
[root@www ~]# make
[root@www ~]# make install


Не забываем перезапустить apache (ну или что там у вас) и вписать в /etc/php.ini
extension = ffmpeg.so

После такой свистопляски скриншоты стали отрабатывать нормально.

Разработчики рассширения распиздяи, надо проверять прежде чем выкладывать
p.s зеркало для ffmpeg-php-0.6.0.tbz2
4 ноября 2014, 07:12

301 редирект на php

<?php
header("HTTP/1.1 301 Moved Permanently");
header('Location: http://site.ru');

/*
Еще Вариант header('Location: http://site.ru', true, 301)
*/
28 мая 2011, 14:44

Что делать если apache портит картинки при upload

# Чтобы апаче 1.3.37 (русский апаче) не  портил   картинки  при аплоаде
# надо в .htaccess прописать это
 
CharsetRecodeMultipartForms Off
4 марта 2011, 13:25

Удаление звуковой дорожки из видео

Если вы конвертировали фильмы ффмпегом, то наверняка замечали неприятную особенность: когда у фильма две звуковые дорожки (русская+английская), то 
в сконверченном видео он частенько оставляет только английскую.
Вот так можно решить проблему
 
ffmpeg -i input.avi -map 0:0 -vcodec copy -map 0:1 -acodec copy output.avi
 
в новом файле будет только ПЕРВАЯ звуковая дорожка.
 
Второй способ через mencoder (необходимо его сначала поставить конечно)
 
mencoder -alang ru -ovc copy -oac copy input.avi -o  output.avi
 
У второго способа преимущество в том, что он оставит именно русскую дорожку, а не первую. 
Но для этого русская дорожка должна быть помечена в исходном файле как таковая (за редким исключением это так и есть).
16 февраля 2011, 02:50

Получение почты при помощи imap

<?php
$box = imap_open("{pop.mail.ru/pop3:110}", 'mylo@inbox.ru', 'password');
 
echo '<pre>Писем: ';
echo $count = imap_num_msg($box);
echo "\n\n";
 
$i=1;
while ($i<=$count) {
    $overview = imap_fetch_overview($box, $i);
    echo 'тема: '. imap_utf8($overview[0]->subject);
    echo "\n";
    $body =  imap_body($box, $i);
    $body = imap_qprint($body);
    $body = iconv('windows-1251', 'utf-8', $body);
    echo "$body \n\n***********\n\n";
    $i++;
}
 
imap_close($box);
3 февраля 2011, 02:41

Определение компьютер или мобильное устройство 2

<?php
/*
Регулярочка, конечно, "пацанская", но идет в ногу со временем
*/
$useragent=$_SERVER['HTTP_USER_AGENT'];
if(preg_match('/android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)))
header('Location: http://detectmobilebrowser.com/mobile');
?>
3 февраля 2011, 02:40

Установка и синхронизация времени на сервере

Для начала необходимо установить временную зону. 
За это отвечает файл /etc/localtime
Переименуйте его вот так 
 
# mv /etc/localtime /etc/localtime.old
 
Теперь необходимо создать симлинк на файл /etc/localtime с нужной нам временной зоны (пример для Москвовского времени) 
 
# ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime
 
Ну и финальный штрих, синхронизация времени:
 
# ntpdate ntp0.zenon.net
 
(если нету ntpdate, то необходимо установить его)
 
Смотрим в консоле на результат и радуемся
# date
20 января 2011, 02:40

Переадресация с поддомена www через .htaccess

# Очень часто яндекс склеивает ваш сайт с www и без, в итоге получается
# как бы 2 сайта, но неполноценных. Причем, прописка host в robots.txt не помогает.
# Привожу пример коротый 100% работает (это надо писать в .htaccess)
 
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.snippets\.pp\.ru
RewriteRule ^(.*)$ http://snippets.pp.ru/$1 [R=301,L]
 
# Обратите внимание, что код 301 (не 302!), и в условии точки экранируются
# Результат можно проверить, набрав http://www.snippets.pp.ru
25 декабря 2010, 02:39

Zend Guard. Мнимая защита

Zend Guard. Мнимая защита.
 
В последнее время, люди активно "защищают" свои скрипты, кодируя избранные файлы или 
целый проект в Zend Guard. Этими людьми движет желание, чтобы их кодом не пользовались 
как попало, с одной стороны, это понятно. Но с другой стороны, ими движет алчность, они 
не покупают Zend Guard, а качают крякнутый, чтобы потом продавать свои поделки.
 
Расскажу, как можно просто декодировать файл, зашифрованный не последней оф версией, а взломаной.
Для этого существует сервис http://showmycode.com/
 
В поисках закодированных файлов я наткнулся на описание скрипта подсчета переходов на http://wapes.org.ru/
Бинго, база ип как раз закодирована, скачать ее можно по этой ссылке http://wapes.org.ru/xrek/oper.zip
Действительно, файл oper.php в архиве закодирован зендом, давайте его раскодируем, 
потому что базы ип должны быть бесплатными и свободными :)
Грузим этот файл в формочку на http://showmycode.com, вводим простенькую капчу и наслаждаемся результатом
 
<?php
if ( eregi( "oper.php", $PHP_SELF ) )
{
    exit( );
}
$oper = trim( htmlspecialchars( stripslashes( @$_GET['oper'] ) ) );
$oper = @preg_replace( "/[^0-9]/", "", $oper );
if ( $oper != "" )
{
    if ( !( $oper < 0 ) && !( 160 < $oper ) )
    {
        $oper = 0;
    }
}
else
{
    do
    {
        $ip = @$_SERVER['REMOTE_ADDR'];
        $ips = split( "\\.", $ip );
        @$ipnum = @$ips[3] + @$ips[2] * 256 + @$ips[1] * 256 * 256 + @$ips[0] * 256 * 256 * 256;
        $oper = 0;
        $IP101 = array( 1402273792, 1402277888, 3.25123e+009, 3.58203e+009, 3.64763e+009, 2.88676e+009, 1427800064 );
        $IP201 = array( 1402276863, 1402290175, 3.25123e+009, 3.58203e+009, 3.64763e+009, 2.88677e+009, 1427832831 );
        .............. продолжение не пишу
?>
 
Такой "удобный" формат записи ип придумал (скорее всего под укуркой) автор небезызвестного скрипта вапфикс.
А остальные переняли и юзают до сих пор.
 
Почему нельзя было хранить как-то так
array( 
  oper1 => array( 
    array(start, end), 
    array(start, end), 
    array(start, end), 
  ),
  oper2 => array( 
    array(start, end), 
    array(start, end), 
    array(start, end), 
  )  
)
25 декабря 2011, 02:38

Инвертирование rgb цвета

<?php
/**
 * 
 */
function color_inverse($color){
    $color = substr($color, 1); //отрезаем # от цвета
    if (strlen($color) != 6){ return '000000'; } //проверка  на длинну
    $rgb = '';
    for ($x=0; $x<3; $x++){
        $c = 255 - hexdec(substr($color, (2*$x), 2));
        $c = ($c < 0) ? 0 : dechex($c);
        $rgb .= (strlen($c) < 2) ? '0'.$c : $c;
    }
    return '#'.$rgb;
}
 
//возьмем для примера желтый
$color = '#FFFF00';
echo "<div style='height:10%; background-color:$color'></div>";
//посмотрим что получится если его инвертировать
echo "<div style='height:10%; background-color:".color_inverse($color)."'></div>";
 
//на флаг Украины смахивает :))
24 декабря 2010, 02:37

Работа со временем. Получение диаппазонов текущей и прошлой недели

<?php
/**
 * 
 */
 
//понедельник на этой неделе
echo date('d.m.Y', strtotime(date('Y').'W'.date('W')));
echo ' - ';
//воскресенье на этой неделе
echo date('d.m.Y', strtotime(date('Y').'W'.date('W').'-7'));
 
echo '<br />'.PHP_EOL;
 
//прошлую неделю можно получить просто вычитая неделю от предыдущих расчетов    
echo date('d.m.Y', strtotime(date('Y').'W'.date('W').' - 1 week'));
echo ' - ';
echo date('d.m.Y', strtotime(date('Y').'W'.date('W').'-7 - 1 week'));
24 декабря 2010, 02:36