PHP proc_open Example  screenshot

PHP proc_open Example

La función “proc_open” nos permite ejecutar desde PHP un programa externo y comunicarnos con él mediante un canal de entrada (pasarle datos); y otro de salida de datos (ver lo que nos devuelve).

Para una descripción detallada la función “proc_open” visita la página oficial de PHP:

En este artículo vamos a ver ejemplos de su utilización:

Ejemplo de “proc_open” para obtener el resultado de ejecutar el comando linux “ls -l”

<?php
$descr = array(
    0 => array(
        'pipe',
        'r'
    ) ,
    1 => array(
        'pipe',
        'w'
    ) ,
    2 => array(
        'pipe',
        'w'
    )
);
$pipes = array();
$process = proc_open("ls -l", $descr, $pipes);
if (is_resource($process)) {
    while ($f = fgets($pipes[1])) {
        echo "-pipe 1--->";
        echo $f;
    }
    fclose($pipes[1]);
    while ($f = fgets($pipes[2])) {
        echo "-pipe 2--->";
        echo $f;
    }
    fclose($pipes[2]);
    proc_close($process);
}
?>

Utilizamos el array $pipes[1] para conocer el resultado de la ejecución del programa.

Podría ser cualquier programa, comando o script bash, que nos interesase obtener su resultado de ejecución.

Ejemplo de “proc_open” para interactuar con el programa y ver los resultados

Otra opción es interaccionar con el programa externo. De forma que le pasemos datos y veamos el resultado.

<?php
$descr = array(
    0 => array(
        'pipe',
        'r'
    ) ,
    1 => array(
        'pipe',
        'w'
    ) ,
    2 => array(
        'pipe',
        'w'
    )
);
$pipes = array();
$process = proc_open("php", $descr, $pipes);
if (is_resource($process)) {
    fputs($pipes[0], "");
    fclose($pipes[0]);
    while ($f = fgets($pipes[1])) {
        echo "-pipe 1--->";
        echo $f;
    }
    fclose($pipes[1]);
    while ($f = fgets($pipes[2])) {
        echo "-pipe 2--->";
        echo $f;
    }
    fclose($pipes[2]);
    proc_close($process);
}
?>

Escribiendo en el array $pipes[0] se le envían datos al proceso. Cerramos el canal y ya podemos obtener el resutlado en el array $pipes[1].

Ejemplo de “proc_open” que espera a que el programa termine

<?php
$descr = array(
    0 => array(
        'pipe',
        'r'
    ) ,
    1 => array(
        'pipe',
        'w'
    ) ,
    2 => array(
        'pipe',
        'w'
    )
);
$pipes = array();
$process = proc_open("top -b -n 5", $descr, $pipes);
if (is_resource($process)) {
    while ($f = fgets($pipes[1])) {
        echo "-pipe 1--->";
        echo $f;
    }
    fclose($pipes[1]);
    while ($f = fgets($pipes[2])) {
        echo "-pipe 2--->";
        echo $f;
    }
    fclose($pipes[2]);
    proc_close($process);
}
?>

La función “proc_open” esperará a que el programa termine para obtener los datos. Por ejemplo, el comando “top -b -n 5” de linux dará 5 iteraciones antes de terminar. Es entonces cuando podremos consultar a “proc_open” el resutlado:

Ejemplo de “proc_open” obtiene la temperatura de una ciudad

“proc_open” puede sernos de utilidad para obtener la temperatura de una lista de cidades de una base de datos.

<?php
$descr = array(
    0 => array(
        'pipe',
        'r'
    ) ,
    1 => array(
        'pipe',
        'w'
    ) ,
    2 => array(
        'pipe',
        'w'
    )
);
$pipes = array();
$city = "http://www.accuweather.com/en/jp/tokyo/226396/weather-forecast/226396";
$commd = "xargs -0 curl -s  | awk -F\' '/acm_RecentLocationsCarousel\.push/{print $2\": \"$4\":  \"$16\", \"$12\"°\" }' | head -1";
$process = proc_open($commd, $descr, $pipes);
if (is_resource($process)) {
    fputs($pipes[0], $city);
    fclose($pipes[0]);
    while ($f = fgets($pipes[1])) {
        echo "-pipe 1--->";
        echo $f;
    }
    fclose($pipes[1]);
    while ($f = fgets($pipes[2])) {
        echo "-pipe 2--->";
        echo $f;
    }
    fclose($pipes[2]);
    proc_close($process);
}
?>

Podría ser lo mismo para verificar si un fichero subido por un usuario tiene un virus o no. Ejecutando el antivirus desde el modo comando y pasándole la ruta del fichero.