Hay muchos casos en los que preferirá ejecutar un script php con la consola en lugar de una interfaz de usuario, pero hay algunos casos en los que usar una interfaz de usuario es la única forma, al igual que el cliente que activa la acción.
Probablemente ya sepa cómo ejecutar una tarea bash usando PHP, pero ¿qué pasa si su tarea es demasiado pesada y tarda demasiado en completarse? Nadie quiere ver una barra de progreso durante una hora esperando una respuesta del servidor ... al menos no con las cosas del trabajo.
En este caso, querrá ignorar la salida y dejar que su tarea se ejecute en segundo plano. Para lograr nuestro objetivo, necesitamos usar la system
función en Windows y la shell_exec
función para ubuntu y linux.
shell_execute: Ejecuta un comando a través de shell y devuelve la salida completa como una cadena (pero lo evitará en este caso).
sistema: Ejecute un programa externo y muestre la salida (y ninguno en este caso).
Ambas funciones te permiten hacer algo con la línea de comando, sin embargo vamos a evitar que estas funciones esperen la salida en cada plataforma usando un simple truco.
La siguiente función le permitirá hacer el truco fácilmente en la mayoría de los casos:
<?php
/**
* Ejecuta un comando de consola (como ejecutar el comando a través de putty) en
* un entorno linux o windows desde php sin esperar el resultado.
*
* Útil para ejecutar tareas extensas.
*
* @param {String} $comando
*/
function executeAsyncShellCommand($comando = null){
if(!$comando){
throw new Exception("No command given");
}
// Si windows, o si no
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
system($comando." > NUL");
}else{
shell_exec("/usr/bin/nohup ".$comando." >/dev/null 2>&1 &");
}
}
La función espera la entrada del shell como primer parámetro:
<?php
executeAsyncShellCommand(`echo hello`);
Nota importante: en algunos entornos Linux o Windows, deberá cambiar las comillas ( ""
o ''
para ``
), de lo contrario, el comando fallará.
El punto importante es saber qué comando usar en qué plataforma y redirigir la salida en ella. Para el uso de Windows {command} > NUL
y para Linux, Ubuntu funcionará /usr/bin/nohup {command here} >/dev/null 2>&1 &
.
Sin embargo, tenga en cuenta que esta función lo ayudará con comandos simples, ya que php bin/console do:something
, si sus comandos usan una estructura compleja o contiene caracteres especiales, es posible que desee implementarla usted mismo de acuerdo con sus necesidades.
El siguiente fragmento autoescrito escribe un archivo en Windows desde php con la función del sistema y los caracteres especiales se escapan gracias a la escapeshellcmd
función:
Nota: escapeshellcmd escapa cualquier carácter en una cadena que podría usarse para engañar a un comando de shell para que ejecute comandos arbitrarios.
<?php
$filecontent = escapeshellcmd("> algo que no podía funcionar en la línea de comandos <¡Hola mundo! Voy a hacer algo con personajes raros");
$comando = `echo {$filecontent} > foo.txt`;
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
system($comando." > NUL");
}else{
shell_exec("/usr/bin/nohup ".$comando." >/dev/null 2>&1 &");
}
Consejos a considerar
- Pruebe su comando en vivo en la línea de comando para ver si funciona solo, si lo hace, entonces funcionará con la función.
- Este método es útil si necesita ejecutar tareas largas y es posible que el usuario no quiera esperar o ver el progreso.
- Si usa el comando para ejecutar otro en PHP, recuerde dar un límite de tiempo mayor
ini_set('max_execution_time', seconds)
de ejecución tanto para la función como para el script que se ejecutará ya que el límite de tiempo predeterminado es de 30 segundos. - Los métodos system y shell_exec siempre esperan el resultado, no hay forma de evitarlo, sin embargo, usamos el truco para redirigir un resultado nulo para cada plataforma.
Que te diviertas ❤️!
Conviertete en un programador más sociable