У меня есть простой PHP-скрипт, который я хочу запустить из терминала и иметь возможность обрабатывать сигнальные коды. Скрипт создает TCP-сервер и обрабатывает соединения. Не знаю почему, но я не могу заставить работать обработку сигналов:
<?php
declare(ticks = 1);
// Register shutdown command.
pcntl_signal(SIGINT, function ($sig) {
echo 'Exiting with signal: ' . $sig;
global $sock;
global $client;
socket_close($sock);
socket_close($client);
exit(1);
});
$address = '127.0.0.1';
$port = 1234;
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port) or die('Could not bind to address.');
socket_listen($sock);
while (TRUE) {
$client = socket_accept($sock);
if ($client) {
$input = socket_read($client, 1024000);
socket_write($client, var_export($input, TRUE));
socket_write($client, 'End of data transmission.');
socket_close($client);
}
usleep(100);
}
CTRL + C не убивает приложение и не нажимает на функцию.
Если я удалю pcntl_signal
функции, CTRL + C убивает программу, как и ожидалось.
Основываясь на проведенном мной исследовании, эта установка должна работать. Я пробовал это в PHP 5.5 и 5.6 … Не могу заставить работать как задумано.
проблема
Проблема в том, что вы используете socket_read()
который выполняет блокировку ввода-вывода. PHP не может обрабатывать сигналы, если он зависает в операции блокирования ввода-вывода.
Решение
Используйте неблокирующий ввод-вывод для чтения данных из сокета. Вы можете использовать функцию socket_select()
с таймаутом в цикле, чтобы убедиться, что чтение не будет блокироваться.
Других решений пока нет …