tutorial sirve que programacion para lenguaje descargar caracteristicas php

sirve - php ejecuta un proceso en segundo plano



php tutorial (17)

Necesito ejecutar una copia de directorio en una acción de usuario, pero los directorios son bastante grandes, por lo que me gustaría poder realizar dicha acción sin que el usuario se dé cuenta del tiempo que tarda la copia en completarse.

Cualquier sugerencia sería muy apreciada.


¿Puede organizar un proceso separado y luego ejecutar su copia en segundo plano? Ha pasado un tiempo desde que hice PHP, pero la función pcntl-fork parece prometedora.


Aquí hay una función para iniciar un proceso en segundo plano en PHP. Finalmente, creó uno que también funciona en Windows, después de leer y probar diferentes enfoques y parámetros.

function LaunchBackgroundProcess($command){ // Run command Asynchroniously (in a separate thread) if(PHP_OS==''WINNT'' || PHP_OS==''WIN32'' || PHP_OS==''Windows''){ // Windows $command = ''start "" ''. $command; } else { // Linux/UNIX $command = $command .'' /dev/null &''; } $handle = popen($command, ''r''); if($handle!==false){ pclose($handle); return true; } else { return false; } }

Nota 1: En Windows, no use el parámetro /B como se sugiere en otro lugar. Obliga al proceso a ejecutar la misma ventana de consola que el comando de start sí, lo que hace que el proceso se procese de forma síncrona. Para ejecutar el proceso en un subproceso separado (asincrónicamente), no use /B

Nota 2: Las comillas dobles vacías después del start "" son necesarias si el comando es una ruta entre comillas. start comando de start interpreta el primer parámetro entre comillas como título de ventana.


Bueno, encontré una versión un poco más rápida y más fácil de usar

shell_exec(''screen -dmS $name_of_screen $command'');

y funciona.


En lugar de iniciar un proceso en segundo plano, ¿qué hay de crear un archivo de activación y tener un programador como cron o autosys que ejecuta periódicamente un script que busca y actúa sobre los archivos de activación? Los activadores pueden contener instrucciones o incluso comandos sin procesar (mejor aún, simplemente convertirlo en un script de shell).


Es posible que desee intentar adjuntar esto a su comando

>/dev/null 2>/dev/null &

p.ej.

shell_exec(''service named reload >/dev/null 2>/dev/null &'');


Escriba el proceso como una secuencia de comandos del lado del servidor en cualquier idioma (php / bash / perl / etc) y luego llámelo desde las funciones de control de procesos en su secuencia de comandos php.

La función probablemente detecta si se utiliza io estándar como el flujo de salida y si es así, se establecerá el valor de retorno ... si no termina

Proc_Close (Proc_Open ("./command --foo=1 &", Array (), $foo));

Probé esto rápidamente desde la línea de comandos usando "sleep 25s" como comando y funcionó a la perfección.

( Respuesta encontrada aquí )


Estoy usando mucho fast_cgi_finish_request()

En combinación con un cierre y register_shutdown_function ()

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

Luego registre este cierre para ser ejecutado antes del cierre.

register_shutdown_function($backgroundJob);

Finalmente, cuando la respuesta se envió al cliente, puede cerrar la conexión al cliente y continuar trabajando con el proceso de PHP:

fast_cgi_finish_request();

El cierre se ejecutará después de fast_cgi_finish_request.

El mensaje $ no será visible en ningún momento. Y puede registrar tantos cierres como desee, pero tenga cuidado con el tiempo de ejecución del script. Esto solo funcionará si PHP se está ejecutando como un módulo de CGI rápido (¡¿era eso correcto ?!)


PHP scripting no es como otro lenguaje de desarrollo de aplicaciones de escritorio. En los lenguajes de aplicaciones de escritorio, podemos establecer hilos de daemon para ejecutar un proceso en segundo plano, pero en PHP ocurre un proceso cuando el usuario solicita una página. Sin embargo, es posible establecer un trabajo en segundo plano utilizando la funcionalidad de trabajo cron del servidor que ejecuta el script php.


Para aquellos de nosotros que usamos Windows , miren esto:

Referencia: http://php.net/manual/en/function.exec.php#43917

Yo también luché con conseguir que un programa se ejecutara en segundo plano en Windows mientras el script continúa ejecutándose. Este método, a diferencia de otras soluciones, le permite iniciar cualquier programa minimizado, maximizado o sin ninguna ventana. La solución de llbra @ phpbrasil funciona pero a veces produce una ventana no deseada en el escritorio cuando realmente desea que la tarea se oculte.

iniciar Notepad.exe minimizado en el fondo:

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

iniciar un comando de shell invisible en el fondo:

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

inicie MSPaint maximizado y espere a que lo cierre antes de continuar con el script:

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

Para obtener más información sobre el método Run (), vaya a: http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp

URL editada:

Vaya a https://technet.microsoft.com/en-us/library/ee156605.aspx ya que el enlace anterior ya no existe.


Puede intentar un sistema de colas como Resque . A continuación, puede generar un trabajo, que procesa la información y un retorno bastante rápido con la imagen de "procesamiento". Sin embargo, con este enfoque no sabrás cuándo está terminado.

Esta solución está diseñada para aplicaciones de mayor escala, donde no desea que sus máquinas frontales hagan el trabajo pesado, por lo que pueden procesar las solicitudes de los usuarios. Por lo tanto, podría o no funcionar con datos físicos como archivos y carpetas, pero para procesar lógica más complicada u otras tareas asíncronas (es decir, nuevos correos de registros) es bueno tenerlo y es muy escalable.


Sé que es una publicación de 100 años, pero de todos modos, pensé que podría ser útil para alguien. Puede colocar una imagen invisible en algún lugar de la página que apunta a la URL que debe ejecutarse en segundo plano, como esto:

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


Si solo necesita hacer algo en segundo plano sin que la página de PHP espere a que se complete, puede usar otro script PHP (de fondo) que se "invoque" con el comando wget. Este script PHP de fondo se ejecutará con privilegios, por supuesto, como cualquier otro script PHP en su sistema.

Aquí hay un ejemplo en Windows usando wget de los paquetes gnuwin32.

El código de fondo (archivo test-proc-bg.php) como un ejemplo ...

sleep(5); // some delay file_put_contents(''test.txt'', date(''Y-m-d/H:i:s.u'')); // writes time in a file

El guión en primer plano, el que invoca ...

$proc_command = "wget.exe http://localhost/test-proc-bg.php -q -O - -b"; $proc = popen($proc_command, "r"); pclose($proc);

Debe usar el popen / pclose para que esto funcione correctamente.

Las opciones de wget:

-q keeps wget quiet. -O - outputs to stdout. -b works on background



Solo me gustaría agregar un ejemplo muy simple para probar esta funcionalidad en Windows:

Cree los dos archivos siguientes y guárdelos en un directorio web:

foreground.php

<?php ini_set("display_errors",1); error_reporting(E_ALL); echo "<pre>loading page</pre>"; function run_background_process() { file_put_contents("testprocesses.php","foreground start time = " . time() . "/n"); echo "<pre> foreground start time = " . time() . "</pre>"; // output from the command must be redirected to a file or another output stream // http://ca.php.net/manual/en/function.exec.php exec("php background.php > testoutput.php 2>&1 & echo $!", $output); echo "<pre> foreground end time = " . time() . "</pre>"; file_put_contents("testprocesses.php","foreground end time = " . time() . "/n", FILE_APPEND); return $output; } echo "<pre>calling run_background_process</pre>"; $output = run_background_process(); echo "<pre>output = "; print_r($output); echo "</pre>"; echo "<pre>end of page</pre>"; ?>

background.php:

<? file_put_contents("testprocesses.php","background start time = " . time() . "/n", FILE_APPEND); sleep(10); file_put_contents("testprocesses.php","background end time = " . time() . "/n", FILE_APPEND); ?>

Otorgue permiso a IUSR para escribir en el directorio en el que creó los archivos anteriores

Otorgue permiso IUSR para LEER y EJECUTAR C: / Windows / System32 / cmd.exe

Hit foreground.php desde un navegador web

Se debe representar lo siguiente en el navegador con las marcas de tiempo actuales y el número de recurso local en la matriz de salida:

loading page calling run_background_process foreground start time = 1266003600 foreground end time = 1266003600 output = Array ( [0] => 15010 ) end of page

Debería ver testoutput.php en el mismo directorio en el que se guardaron los archivos anteriores y debería estar vacío

Debería ver testprocesses.php en el mismo directorio en el que se guardaron los archivos anteriores, y debería contener el siguiente texto con las marcas de tiempo actuales:

foreground start time = 1266003600 foreground end time = 1266003600 background start time = 1266003600 background end time = 1266003610


Suponiendo que esto se ejecuta en una máquina Linux, siempre lo he manejado así:

exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));

Esto inicia el comando $cmd , redirige la salida del comando a $outputfile y escribe la identificación del proceso en $pidfile .

Eso le permite controlar fácilmente lo que está haciendo el proceso y si aún se está ejecutando.

function isRunning($pid){ try{ $result = shell_exec(sprintf("ps %d", $pid)); if( count(preg_split("//n/", $result)) > 2){ return true; } }catch(Exception $e){} return false; }


Una solución de trabajo para Windows y Linux. Encuentre más en mi página de github .

function run_process($cmd,$outputFile = ''/dev/null'', $append = false){ $pid=0; if (strtoupper(substr(PHP_OS, 0, 3)) === ''WIN'') {//''This is a server using Windows!''; $cmd = ''wmic process call create "''.$cmd.''" | find "ProcessId"''; $handle = popen("start /B ". $cmd, "r"); $read = fread($handle, 200); //Read the output $pid=substr($read,strpos($read,''='')+1); $pid=substr($pid,0,strpos($pid,'';'') ); $pid = (int)$pid; pclose($handle); //Close }else{ $pid = (int)shell_exec(sprintf(''%s %s %s 2>&1 & echo $!'', $cmd, ($append) ? ''>>'' : ''>'', $outputFile)); } return $pid; } function is_process_running($pid){ if (strtoupper(substr(PHP_OS, 0, 3)) === ''WIN'') {//''This is a server using Windows!''; //tasklist /FI "PID eq 6480" $result = shell_exec(''tasklist /FI "PID eq ''.$pid.''"'' ); if (count(preg_split("//n/", $result)) > 0 && !preg_match(''/No tasks/'', $result)) { return true; } }else{ $result = shell_exec(sprintf(''ps %d 2>&1'', $pid)); if (count(preg_split("//n/", $result)) > 2 && !preg_match(''/ERROR: Process ID out of range/'', $result)) { return true; } } return false; } function stop_process($pid){ if (strtoupper(substr(PHP_OS, 0, 3)) === ''WIN'') {//''This is a server using Windows!''; $result = shell_exec(''taskkill /PID ''.$pid ); if (count(preg_split("//n/", $result)) > 0 && !preg_match(''/No tasks/'', $result)) { return true; } }else{ $result = shell_exec(sprintf(''kill %d 2>&1'', $pid)); if (!preg_match(''/No such process/'', $result)) { return true; } } }


Utilice esta función para ejecutar su programa en segundo plano. Es multiplataforma y totalmente personalizable.

<?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; }

Tenga en cuenta que después de iniciar el comando, esta función cierra de forma predeterminada la entrada estándar y la salida estándar del proceso en ejecución. Puede redirigir la salida del proceso a algún archivo a través de los argumentos $ redirectStdout y $ redirectStderr.

Nota para los usuarios de Windows: no hay forma de redireccionar stdout / stderr a nul device. Desafortunadamente no puedes hacerlo:

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

Por lo tanto, debe redirigir stderr / stdin a un archivo válido o su comando debe esperar que no sea un descriptor stderr / stdout.

Notas para usuarios de * nix:

1) Utilice el comando exec shell si desea obtener un PID real:

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

2) Use el argumento $ stdin si desea pasar algunos datos a la entrada de su programa:

startBackgroundProcess(''cat > input.txt'', "Hello world!/n");