Blog: Administración de sistemas
Ejecutar un script PHP en segundo plano bajo Windows
Publicado el: 6/08/2008 en: Administración de sistemas | 8 comentarios
Caso:
Tenemos un site que realiza una tarea muy larga y pesada, por ejemplo consultar un webservice externo con miles de registros.
Problema:
Si ejecutamos desde el servidor apache un script PHP que realize esa acción puede pasarnos:
1.- La pagina se nos bloqueará hasta que finalice su ejecución, no pudiendo ver nada más.
2.- Si el tiempo se alarga demasíado el servidor web cortará la conexión o bién lo hará nuestro navegador
3.- Si cerramos accidentalmente el navegador o se produce un error en la conexión el proceso se interrumpira.
Tentativa de Solución:
Lanzar con un exec de PHP una llamada al php.exe que ejecute el script en cuestión. Por ejemplo si tenemos el script consulta_webservice.php que es el que realiza la carga de datos del Webservice podemos escribir en nuestro script de lanzamiento lanzador_webservice.php:
< ?php
exec("C:\ruta_al_exe_php\php.exe -f consulta_webservice.php");
?>
Este metodo funciona optimamente bajo entornos linux, no así en windows. ¿Por qué? Pues por que deja al script lanzador esperando que termine el proceso que él mismo ha lanzado (en nuestro caso php.exe -f consulta_webservice.php)
Es decir no ganamos nada respecto a la opción de invocarle desde la web.
Buscando la respuesta:
Tras muchas horas de pruebas con diversas soluciones que en la www se dan a este problema, nos dimos cuenta que tan sólo una nos funcionaba correctamente. En concreto se trata de usar un programa auxiliar “psexec.exe” cuya principal utilidad consiste en lanzar programas tanto en nuestra máquina como en máquinas en red.
Veamos como usarlo:
En nuestro script lanzador usamos la funcion exec para lanzar este comando:
< ?php
exec('psexec -d C:\ruta_al_exe_php\php.exe -f consulta_webservice.php');
?>
Esta linea nos lanza desde el PHP el mencionado psexec (deberá estar en el mismo directorio en el que estamos), que a su vez invoca al php.exe que ejecuta nuestro script cargador que se ejecutará en segundo plano. Consiguiendo con este pequeño rodeo que el script lanzador quede libre de esperar a que acabe su ejecución el script cargador.
Para lograr esto usamos la opcion del psexec “-d”
Rizando el rizo:
Pero imaginemos que al script que queremos usar para cargar datos del webservice tenemos que pasarle parametros (por ejemplo un id) digamos: consulta_webservice.php?id=123
Si probamos a llamarlo tal cual lo hariamos desde la web, nos encontraremos con un fallo del psexec, el cual no admite ningún parametro con “?” o con “=”, así que recurriremos al uso de parametros específicos para ejecutar php desde la linea de comandos, tal que así:
< ?php
exec('psexec -d C:\ruta_al_exe_php\php.exe -f consulta_webservice.php -- 123');
?>
El script receptor, consulta_webservice.php, deberá recojer dicho valor de la siguiente forma:
< ?php
$id=$argv[1];
# $id vale 123
?>
Donde el array global $argv nos proporciona todos los parametros pasados y la variable $arvc su cardinalidad.
Resumiendo:
El programa psexec nos brinda la posibilidad de ejecutar una aplicacion en segundo plano llamada desde un script PHP ejecutado en un servidor Apache en Windows, sin interrumpir el uso nuestra aplicación web.
Podeis descargarlo aquí: psexec






(7 voto(s), media: 4.43 sobre 5)
Deja tu comentario8 Comentarios
d
22/08/2008
esta muy buena esta pagina
wilian
2/09/2008
yo en mi experiencia para evitar que el servidor me corte la ejecucion por demaciado tiempo uso la seguiente funcion en php:
set_time_limit(0);
Marco Antonio Ortega
19/09/2008
Puedes integrar en tu aplicación el uso de AJAX para cargar los datos de manera asíncrona y evitar que se interrumpa, incluso realizar la carga de los datos sobre demanda, así no tendrás este problema y tu aplicación se podrá utilizar rápidamente.
Marcos
23/09/2008
Hola de nuevo, la idea subyacente de este ejemplo es la de liberar al navegador de la ejecución de la aplicación.
El alargar el tiempo de ejecución del servidor no impide que la conexión sea cortada por nuestro navegador, bien por superar su tiempo de espera, bien accidentalmente al cerrar la ventana nosotros mismos.
En cuanto a la solución con AJAX, efectivamente puede ser una solución muy adecuada, aunque seguimos con el mismo problema de antes, para continuar la ejecución del script necesitamos tener nuestra ventana activa, y seguimos presos de la misma limitación.
Un saludo.
Andres
21/07/2011
Muy bueno tu articulo me sirvió de mucha ayuda… pero no me quiso correr por ningún motivo, ya que olvidaste mencionar en el articulo que hay que declarar una bandera ‘flag’ en el comando: llamada -accepteula, de esta manera si corre el script.
Marcos
22/07/2011
Hola Andrés. Gracias por tu comentario.
El flag al que haces referencia es un parámetro que indica a Windows que aceptas los “Microsoft Software License Terms”.
Puede ser necesario en caso de que carezcas de ciertos permisos de administración y lances el “psexec.exe”.
Saludos!
tebca
11/02/2012
muy servicial. Gracias por exhibir algo asi al internet
Alejandro Esteban Daza Londoño
2/03/2012
Debo reconocer que es una excelente opción en en el windows 7 de 64 deja el script corriendo no entiendo por que creo que me volveré loco
Deja tu comentario
Tags HTML Permitidos:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>