Пишем демона на php

Иногда бывает нужно держать определенное количество процессов в работе.
Это можно реализовать через крон, который запускается раз в минуту, но как показала практика это не лучшее решение.
Предлагаю более технологичный вариант:
<?php
 
// создаем дочерний процесс
$child_pid = pcntl_fork();
 
if ($child_pid) {
    // выходим из родительского, привязанного к консоли, процесса
    exit;
}
 
// делаем основным процессом дочерний
// После этого он тоже cможет создавать процессы
posix_setsid();
 
//чтобы повторно не запустить демона, нужна функция для проверки его pid
function isDaemonActive($pid_file) {
    if (is_file($pid_file)) {
        $pid = file_get_contents($pid_file);
        //проверяем на наличие процесса
        if (posix_kill($pid, 0)) {
            //демон уже запущен
            return true;
        } else {
            //pid-файл есть, но процесса нет
            if (!unlink($pid_file)) {
                //не могу уничтожить pid-файл. ошибка
                exit(-1);
            }
        }
    }
    return false;
}
 
//проверяем запущен ли демон
if (isDaemonActive(__DIR__ . '/daemon.pid')) {
    echo 'Daemon already active';
    exit;
}
 
//регистрируем обработчик сигналов
pcntl_signal(SIGTERM, "sigHandler");
 
//сама функция обработчика
function sigHandler($signo) {
    global $stop_server;
    switch ($signo) {
        case SIGTERM: {
                $stop_server = true;
                break;
            }
        default: {
                //все остальные сигналы
            }
    }
}
 
//говорим php принимать сигналы
pcntl_signal_dispatch();
 
//записываем pid процесса демона
file_put_contents(__DIR__ . '/daemon.pid', getmypid());
 
//будем держать не более 20 процессов одновременно
define('MAX_CHILD_PROCESSES', 20);
//задержка чтобы не гонять цикл постоянно
define('DELAY', 1);
 
//массив для хранения дочерних процессов
$child_processes = array();
 
//запускаем бесконечный цикл
while (!$stop_server) {
    if (!$stop_server and (count($child_processes) < MAX_CHILD_PROCESSES)) {
        //плодим дочерний процесс
        $pid = pcntl_fork();
        if ($pid == -1) {
            //ошибка - не смогли создать процесс
        } elseif ($pid) {
            //процесс создан
            $child_processes[$pid] = true;
        } else {
            $pid = getmypid();
            //дочерний процесс - тут рабочая нагрузка
            //для примера заснем на 100
            //на этом месте может быть, например, команда конвертации видео
            sleep(100);
            exit;
        }
    } else {
        //чтоб не гонять цикл постоянно
        sleep(DELAY);
    }
    //проверяем, умер ли один из детей
    while ($signaled_pid = pcntl_waitpid(-1, $status, WNOHANG)) {
        if ($signaled_pid == -1) {
            //детей не осталось
            $child_processes = array();
            break;
        } else {
            unset($child_processes[$signaled_pid]);
        }
    }
}


Осталось только запустить демона
php daemon.php

Если все сделано верно, то будет постоянно висеть 20 процессов.

Убить такого демона можно опять же из php
<?php
//НАПРИМЕР pid демона 56497
posix_kill(56497, 9);
4 ноября 2014, 07:12

git insufficient permission for adding an object to repository database ./objects

sudo chmod -R g+ws *
 sudo chgrp -R git *

 git repo-config core.sharedRepository true
4 ноября 2014, 07:12

Просмотр числа активных соединений с ip адресов FreeBsd

netstat -nptcp | egrep -v 'Active|Address' | awk '{print $5}' | cut -d. -f 1-4 | sort | uniq -c | sort -n

вывод примерно такой
число ip
число ip
число ip
число ip
с сортировкой по числу в сторону возрастания

Если нужно вывести последние 10, то можно обрезать через tail
netstat -nptcp | egrep -v 'Active|Address' | awk '{print $5}' | cut -d. -f 1-4 | sort | uniq -c | sort -n | tail -n 10
4 ноября 2014, 07:12

Шифрование по ключу

<?php
$phrase = 'secret message';
$key = 'KEY';
 
$encrypt = encrypt($key, $phrase);
$phrase = decrypt($key, $encrypt);
echo $encrypt, ' = ', $phrase;
 
function encrypt($key, $text) {
    $cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');
    mcrypt_generic_init($cipher, $key, '12345678');
    $encrypted = mcrypt_generic($cipher,$text);
    mcrypt_generic_deinit($cipher);
    $encrypted = bin2hex($encrypted);
    return $encrypted;
}
 
function decrypt($key, $encrypted) {
    $encrypted = hex2bin($encrypted);
    $cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');
    mcrypt_generic_init($cipher, $key, '12345678');
    $decrypted = mdecrypt_generic($cipher,$encrypted);
    mcrypt_generic_deinit($cipher);
    return $decrypted;
}

12345678 это размер блока, его можно задать произвольный, не задавать вообще (0) или сгенерить через mcrypt_enc_get_iv_size
4 ноября 2014, 07:12

Установка phpMyAdmin на nginx + php-fpm

Для начала ставим из портов
cd /usr/ports/databases/phpmyadmin 
make install clean 


Секция в nginx выглядит следующим образом
location /pma {
    alias /usr/local/www/phpMyAdmin;
}

location ~ ^/pma/(.+\.php)$ { 
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    include fastcgi_params; 
    fastcgi_param SCRIPT_FILENAME /usr/local/www/phpMyAdmin/$1; 
    fastcgi_param DOCUMENT_ROOT /usr/local/www/phpMyAdmin; 
}
4 ноября 2014, 07:12

Установка ImageMagick на FreeBsd

cd /usr/ports/graphics/ImageMagick
make install clean
4 ноября 2014, 07:12

Mysql natural sort

SELECT * FROM tbl ORDER BY LENGTH(name), name;

-----------------------------------------
|	id	|	name		|
-----------------------------------------
|	2	|	Episode 1	|
|	1	|	Episode 2	|
|	4	|	Episode 11	|
|	3	|	Episode 112	|
-----------------------------------------
4 ноября 2014, 07:12

Сброс root пароля в mysql

Если у вас windows
mysqld.exe -u root --skip-grant-tables

Закрываем окно консоли, вызываем новое, там вызываем mysql (должно зайти без пароля) и выполняем команду
UPDATE user SET Password = PASSWORD('NEW_PASSWORD') WHERE User = 'root';
4 ноября 2014, 07:12

Как удалить коммит в GIT

Откатываемся на 1 коммит назад и форсим
git reset --hard HEAD~1
git push origin HEAD --force
4 ноября 2014, 07:12

Установка memcache на FreeBsd

portmaster memcache

cd /usr/ports/databases/pecl-memcache
make install clean
4 ноября 2014, 07:12

It-отдел

4 ноября 2014, 07:12

Cocaine world championship

4 ноября 2014, 07:12

Чтение Atom лент через PHP

Для начала нам нужно загрузить Atom:
<?php
 $feed = simplexml_load_file("адресс сайта без кавычек");
 $children = $feed->children('http://www.w3.org/2005/Atom');
?>


Теперь можно обращаться к ленте. Например:
 echo $children->title //после выполнения этого скрипта на экране вы увидите заголовок ленты


P.S.
В даном случаи мы используем SimpleXML. Он работает не для всех лент.
P.P.S.
Для устранения этой проблемы можно использовать ZendFramework.
4 ноября 2014, 07:12

Уходим на технические работы в nginx

    error_page 503 /during_build.html;

    location / {

        if (-f /var/www/during_build.html) {
            return 503;
        }

    }

    location = /during_build.html {
        root /var/www/;
        internal;
    }

Этот способ мне не нравится из-за постоянного if
Если кто знает метод лучше, напишите..
4 ноября 2014, 07:12

Вот так..

4 ноября 2014, 07:12

Программист-сантехник

4 ноября 2014, 07:12

XSS для IE через style

<span style="width: exp​ression(alert('OLOLO!'));"></span>
4 ноября 2014, 07:12

Создание и монтирование дисков в памяти

mdconfig -a -t swap -s 128M -u 10
newfs -U /dev/md10
mount /dev/md10 /tmp
chmod 1777 /tmp

Теперь содержимое каталога /tmp будет храниться в памяти и исчезать после ребутов :)

Еще вариант
mdmfs -S -o async -s 1024m md0 /tmpfs
4 ноября 2014, 07:12

Получение информации о слотах оперативной памяти во FreeBSD

Нужно установить утилиту dmidecode. Ставится из портов
portinstall dmidecode

Получаем информацию
dmidecode -t memory
4 ноября 2014, 07:12

Пакетная перекодировка файлов из windows-1251 в utf-8

Для примера перекодируем все php файлы в текущей директории и ее поддиректориях
#!/bin/sh
for i in `find . -name "*.php" -type f`
do
echo $i
iconv -f WINDOWS-1251 -t UTF-8 "$i" > tmp
mv -f tmp "$i"
done

На винде человек часа 4 потратил на поиск проги, которая это сделает :)
4 ноября 2014, 07:12