PHP выполнить фоновый процесс - PullRequest
       85

PHP выполнить фоновый процесс

241 голосов
/ 05 сентября 2008

Мне нужно выполнить копию каталога при действии пользователя, но каталоги достаточно велики, поэтому я хотел бы иметь возможность выполнять такое действие, не зная, сколько времени потребуется пользователю для завершения копирования.

Любые предложения будут высоко оценены.

Ответы [ 18 ]

2 голосов
/ 04 июля 2016

Используйте эту функцию для запуска вашей программы в фоновом режиме. Он кроссплатформенный и полностью настраиваемый.

<?php
function startBackgroundProcess(
    $command,
    $stdin = null,
    $redirectStdout = null,
    $redirectStderr = null,
    $cwd = null,
    $env = null,
    $other_options = null
) {
    $descriptorspec = array(
        1 => is_string($redirectStdout) ? array('file', $redirectStdout, 'w') : array('pipe', 'w'),
        2 => is_string($redirectStderr) ? array('file', $redirectStderr, 'w') : array('pipe', 'w'),
    );
    if (is_string($stdin)) {
        $descriptorspec[0] = array('pipe', 'r');
    }
    $proc = proc_open($command, $descriptorspec, $pipes, $cwd, $env, $other_options);
    if (!is_resource($proc)) {
        throw new \Exception("Failed to start background process by command: $command");
    }
    if (is_string($stdin)) {
        fwrite($pipes[0], $stdin);
        fclose($pipes[0]);
    }
    if (!is_string($redirectStdout)) {
        fclose($pipes[1]);
    }
    if (!is_string($redirectStderr)) {
        fclose($pipes[2]);
    }
    return $proc;
}

Обратите внимание, что после запуска команды по умолчанию эта функция закрывает stdin и stdout запущенного процесса. Вы можете перенаправить вывод процесса в некоторый файл с помощью аргументов $ redirectStdout и $ redirectStderr.

Примечание для пользователей Windows:
Вы не можете перенаправить stdout / stderr на nul следующим образом:

startBackgroundProcess('ping yandex.com', null, 'nul', 'nul');

Однако вы можете сделать это:

startBackgroundProcess('ping yandex.com >nul 2>&1');

Примечания для пользователей * nix:

1) Используйте команду оболочки exec, если хотите получить фактический PID:

$proc = startBackgroundProcess('exec ping yandex.com -c 15', null, '/dev/null', '/dev/null');
print_r(proc_get_status($proc));

2) Используйте аргумент $ stdin, если вы хотите передать некоторые данные на вход вашей программы:

startBackgroundProcess('cat > input.txt', "Hello world!\n");
1 голос
/ 03 октября 2014

Я интенсивно использую fast_cgi_finish_request()

В сочетании с замыканием и register_shutdown_function ()

$message ='job executed';
$backgroundJob = function() use ($message) {
     //do some work here
    echo $message;
}

Затем зарегистрируйте это закрытие, которое будет выполнено перед выключением.

register_shutdown_function($backgroundJob);

Наконец, когда ответ был отправлен клиенту, вы можете закрыть соединение с клиентом и продолжить работу с процессом PHP:

fast_cgi_finish_request();

Закрытие будет выполнено после fast_cgi_finish_request.

Сообщение $ не будет видно в любое время. И вы можете зарегистрировать столько замыканий, сколько захотите, но позаботьтесь о времени выполнения скрипта. Это будет работать, только если PHP работает как модуль Fast CGI (это правильно?!)

1 голос
/ 02 июля 2014

Если вы используете PHP, есть гораздо более простой способ сделать это с помощью pcntl_fork:

http://www.php.net/manual/en/function.pcntl-fork.php

1 голос
/ 26 апреля 2012

Вместо того, чтобы инициировать фоновый процесс, как насчет создания файла триггера и того, чтобы планировщик, такой как cron или autosys, периодически выполнял скрипт, который ищет и воздействует на файлы триггера? Триггеры могут содержать инструкции или даже необработанные команды (еще лучше, просто сделайте это сценарием оболочки).

0 голосов
/ 28 января 2019

Благодаря этот ответ : идеальным инструментом для запуска фонового процесса будет Symfony Process Component , который основан на proc_* функциях, но его гораздо проще использовать. См. документацию для получения дополнительной информации.

0 голосов
/ 12 августа 2011

Я знаю, что это 100-летний пост, но все равно подумал, что это может быть кому-то полезно. Вы можете поместить невидимое изображение где-нибудь на странице, указывая на URL, который должен работать в фоновом режиме, например:

<img src="run-in-background.php" border="0" alt="" width="1" height="1" />

0 голосов
/ 05 июня 2015

Для тех из нас, кто использует Windows , посмотрите на это:

Ссылка: http://php.net/manual/en/function.exec.php#43917

Я слишком боролся с тем, чтобы программа работала в фоновом режиме в Windows пока скрипт продолжает выполняться. Этот метод в отличие от другие решения позволяют запускать любую программу свернутой, развернутой, или без окна вообще. Решение llbra @ phpbrasil работает, но оно иногда выдает нежелательное окно на рабочем столе, когда вы действительно хотите, чтобы задача выполнялась скрытой.

запуск Notepad.exe, свернутый в фоновом режиме:

<?php 
$WshShell = new COM("WScript.Shell"); 
$oExec = $WshShell->Run("notepad.exe", 7, false); 
?> 

запустить команду оболочки, невидимую в фоновом режиме:

<?php 
$WshShell = new COM("WScript.Shell"); 
$oExec = $WshShell->Run("cmd /C dir /S %windir%", 0, false); 
?> 

Запустите MSPaint в развернутом виде и подождите, пока вы закроете его, прежде чем продолжить скрипт:

<?php 
$WshShell = new COM("WScript.Shell"); 
$oExec = $WshShell->Run("mspaint.exe", 3, true); 
?> 

Для получения дополнительной информации о методе Run () перейдите по ссылке: http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp

Отредактированный URL:

Вместо этого перейдите на https://technet.microsoft.com/en-us/library/ee156605.aspx, поскольку вышеуказанная ссылка больше не существует.

0 голосов
/ 03 августа 2014

PHP-скриптинг не похож на другие языки разработки приложений для настольных компьютеров. В языках настольных приложений мы можем настроить потоки демона для запуска фонового процесса, но в PHP процесс происходит, когда пользователь запрашивает страницу. Однако можно установить фоновое задание, используя функции сервера cron, которые запускает скрипт php.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...