2009-09-19 27 views
6

¿Cómo puede iniciar un script PHP otro script PHP, y luego la salida, dejando el otro script en ejecución?¿Puede un script PHP iniciar otro script PHP y salir?

Además, ¿hay alguna forma para que la segunda secuencia de comandos pueda informar al script PHP cuando alcanza una línea en particular?

+0

¿Podría 'curl' ayudar con esto? Alguna idea de como? –

+0

Curl? Posiblemente solo con una solicitud de 'cabeza', pero soy escéptico –

+0

- si termina el primer guión, ¿cómo informaría el segundo guión el 1 °? - ¿se trata de una página web o un script de consola? –

Respuesta

7

He aquí cómo hacerlo. Le dice al navegador que lea los primeros N caracteres de salida y luego cierre la conexión, mientras su secuencia de comandos continúa ejecutándose hasta que finalice.

<?php 
ob_end_clean(); 
header("Connection: close"); 
ignore_user_abort(); // optional 
ob_start(); 
echo ('Text the user will see'); 
$size = ob_get_length(); 
header("Content-Length: $size"); 
ob_end_flush();  // Will not work 
flush();   // Unless both are called ! 

// At this point, the browser has closed connection to the web server 

// Do processing here 
include('other_script.php'); 

echo('Text user will never see'); 
?> 
+1

¿Puedes explicar un poco tu código? Por ejemplo, el enjuague engaña al navegador para que piense que la solicitud HTTP ha terminado. –

+0

Sí, ¡funciona! También publique esta respuesta a esta pregunta: http://stackoverflow.com/questions/1436575/can-a-php-script-trick-the-browser-into-thinking-the-http-request-is-over –

+0

Edité la respuesta para explicarlo un poco. –

1

Aquí hay una foto en la oscuridad: podría intentar usar las funciones de ejecución del sistema operativo de php con &.

exec("./somescript.php &"); 

Además, si eso no funciona, puede intentar

exec("nohup ./somescript.php &"); 

Editar: nohup is a POSIX command to ignore the HUP (hangup) signal, enabling the command to keep running after the user who issues the command has logged out. The HUP (hangup) signal is by convention the way a terminal warns depending processes of logout.

+0

'nohup' ?? ¿Qué hace eso? –

3

Puede lograrlo de manera efectiva por forking y luego llamando al include o require.

parent.php:

<?php 

    $pid = pcntl_fork(); 
    if ($pid == -1) { 
     die("couldn't fork"); 
    } else if ($pid) { // parent script 
     echo "Parent waiting at " . date("H:i:s") . "\n"; 
     pcntl_wait($status); 
     echo "Parent done at " . date("H:i:s") . "\n"; 
    } else { 
     // child script 
     echo "Sleeper started at " . date("H:i:s") . "\n"; 
     include('sleeper.php'); 
     echo "Sleeper done at " . date("H:i:s") . "\n"; 
    } 

?> 

sleeper.php:

<?php 
sleep(3); 
?> 

Salida:

 
$ php parent.php 
Sleeper started at 01:22:02 
Parent waiting at 01:22:02 
Sleeper done at 01:22:05 
Parent done at 01:22:05 

Sin embargo, la bifurcación no permite inherentemente cualquier comunicación entre procesos, por lo que Tendría que encontrar otra forma de informar a los padres que el niño ha llegado a la línea específica, como usted pidió en el e pregunta

+0

+1 No creo que sea exactamente lo que quería, pero sigue siendo muy útil –

+0

Puede proporcionar comunicación bilateral a través de los métodos de socket (consulte http://www.php.net/manual/en/ref.sockets.php) . –

0

Si no desea compilar la extensión pcntl, entonces una buena alternativa es usar proc_open().

http://www.php.net/manual/en/function.proc-open.php

uso, que junto con stream_select() para que su proceso de PHP puede dormir hasta que algo sucede con el proceso hijo que ha creado.

Eso creará efectivamente un proceso en segundo plano, sin bloquear el proceso padre de PHP. Usted PHP puede leer y escribir en STDIN, STDOUT, STDERR.

Para completar la carga del navegador (detener el indicador de progreso de la carga), puede utilizar lo que Milan Babuškov mencionó.

La clave para hacer que el navegador piense que la solicitud HTTP está completa es enviarla con la longitud del contenido. Para hacer esto, puede comenzar a almacenar en búfer la solicitud y, a continuación, enjuagarla después de enviar el encabezado Content-Length.

por ejemplo:

<?php 

ob_start(); 

// render the HTML page and/or process stuff 

header('Content-Length: '.ob_get_length()); 
ob_flush(); 
flush(); 

// can do more processing 

?> 
0

Usted puede crear una solicitud y cerrar la conexión justo después de que se hace que se escriban.

Verifique el código en http://drupal.org/project/httprl como puede hacer esto (solicitud no bloqueante). Planeo empujar esta lib a github una vez que la haya pulido más; algo que se puede ejecutar fuera de drupal. Esto debería hacer lo que estás buscando.