proc_open

(PHP 4 >= 4.3.0, PHP 5)

proc_open --  Ejecutar un comando y abrir apuntadores de archivo para entrada/salida

Descripción

resource proc_open ( string cmd, array espec_descriptor, array &pipes [, string cwd [, array env [, array otras_opciones]]] )

proc_open() es similar a popen() pero provee un grado de control mucho mayor sobre la ejecución del programa. cmd es el comando a ser ejecutado por el intérprete de comandos. espec_descriptor es una matriz indexada en donde la clave representa el número de descriptor y el valor representa el modo como PHP pasará ese descriptor al proceso hijo. pipes será definido como una matriz indexada de apuntadores a archivo que corresponden a los puntos de comunicación con PHP de todo pipe que sea creado. El valor de retorno es un recurso que representa el proceso; usted debe liberarlo usando proc_close() una vez haya terminado de usarlo.

<?php
$espec_descriptor
= array(
   
0 => array("pipe", "r"),  // stdin es un pipe usado por el hijo para lectura
   
1 => array("pipe", "w"),  // stdout es un pipe usado por el hijo para escritura
   
2 => array("file", "/tmp/error-output.txt", "a") // stderr es un archivo para escritura
);
$proceso = proc_open("php", $espec_descriptor, $pipes);
if (
is_resource($proceso)) {
    
// $pipes ahora luce de esta forma:
    // 0 => gestor de escritura conectado con la entrada estandar del hijo
    // 1 => gestor de lectura conectado con la salida estandar del hijo
    // Cualquier mensaje de salida de error sera adicionado a /tmp/error-output.txt

    
fwrite($pipes[0], "<?php echo \"&iexcl;Hola mundo!\"; ?>");
    
fclose($pipes[0]);

    while (!
feof($pipes[1])) {
        echo
fgets($pipes[1], 1024);
    }
    
fclose($pipes[1]);
    
// Es importante que cierre todos los pipes antes de llamar
    // proc_close para evitar un bloqueo muerto
    
$retval = proc_close($proceso);

    echo
"el comando ha devuelto $retval\n";
}
?>

PHP 5RC2 introduce soporte pty para sistemas con ptys Unix98. Esto le permite a su script interactuar con aplicaciones que esperan estar hablando con una terminal. Una pty trabaja como un pipe, pero es bi-direccional, así que no hay necesidad de especificar un modo de lectura/escritura. El siguiente ejemplo muestra cómo usar una pty; note que no necesita tener todos los descriptores hablando con una pty. Note también que solo una pty es creada, incluso cuando pty se especifica 3 veces. En una versión futura de PHP, puede que sea posible hacer más que simplemente leer y escribir a la pty.

<?php
// Crear una pseudo terminal para el proceso hijo
$espec_descriptor = array(
   
0 => array("pty"),
   
1 => array("pty"),
   
2 => array("pty")
);
$proceso = proc_open("cvs -d:pserver:cvsread@cvs.php.net:/repository login", $espec_descriptor, $pipes);
if (
is_resource($proceso)) {
   
// trabaje con el recurso aqui
}
?>

Los números de descriptor de archivo en espec_descriptor no están limitados a 0, 1 y 2 - usted puede especificar cualquier número de descriptor de archivo válido y éste será pasado al proceso hijo. Esto le permite a su script interoperar con otros scripts que corran como "co-procesos". En particular, esto es útil para pasar contraseñas a programas como PGP, GPG y openssl en un modo más seguro. También es útil para la lectura de información de status entregada por aquellos programas en descriptores de archivo auxiliares.

Nota: Compatibilidad con windows: Los descriptores más allá de 2 (stderr) son entregados al proceso hijo como gestores heredables, pero ya que la arquitectura windows no asocia números de descriptor de archivo con gestores de bajo nivel, el proceso hijo no dispone (aun) de un medio para acceder a esos gestores. Stdin, stdout y stderr funcionan como es de esperar.

Nota: Si sólo necesita un pipe de proceso uni-direccional (una-vía), use popen() en su lugar, ya que es mucho más fácil de usar.

Vea también stream_select(), exec(), system(), passthru(), popen(), escapeshellcmd(), y el operador de comilla invertida.