2011-04-26 12 views

Respuesta

35

Sí, es posible. Para ser interactivo, el programa debe poder esperar y leer la entrada del usuario desde stdin. En PHP, puede leer desde stdin abriendo un descriptor de archivo al 'php://stdin'. Tomado de an answer to different question, esto es un ejemplo de un símbolo del usuario interactiva en PHP (cuando se ejecuta desde la línea de comandos, por supuesto):

echo "Continue? (Y/N) - "; 

$stdin = fopen('php://stdin', 'r'); 
$response = fgetc($stdin); 
if ($response != 'Y') { 
    echo "Aborted.\n"; 
    exit; 
} 

Por supuesto, para obtener una línea completa de entrada en lugar de un único personaje, necesitaría fgets() en lugar de fgetc(). Dependiendo de lo que haga su programa/shell, todo el programa podría estar estructurado como un gran bucle continuo. Espero que eso te dé una idea de cómo comenzar. Si quisiera obtener realmente elegante (CLI pseudo-GUI), podría use ncurses.

1

No queda del todo claro si desea CREAR el shell utilizando solo PHP, o si desea que el shell interactivo procese los comandos PHP. Voy a suponer lo último, y en ese caso, un ejemplo es phpsh que aparentemente fue creado en Facebook, pero está escrito en python.

+0

Gracias, pero no, quiero crear el shell usando PHP, como usted indicó. –

1

sé que el interrogador no quería que la segunda opción, pero para aquellos que quería que la segunda opción como lo hice, además de phpsh, PHP también tiene su own shell:

Sólo tiene que ejecutar php -a.

+0

Tenga en cuenta que no funcionará según lo previsto en Windows (allí solo puede escribir el contenido de un archivo y presionar 'Ctrl' +' Z' 'Enter'). Bastante molesto. –

0

Salida:

https://github.com/shaneharter/sheldon

Es bastante fácil para empezar. Incluye las bibliotecas Symfony2 y Zend Framework que realizan una gran parte del trabajo básico de E/S de la consola y le ofrece una abstracción de mayor nivel construida alrededor de los objetos Command (con rutas regex) y Contexts (que mantienen el estado inmutable).

Una de las cosas que me encanta es que la aplicación se puede ejecutar como un shell interactivo o como un script estándar que se puede ejecutar desde la línea de comandos, especificar un comando, pasar cualquier argumento, y cuando el comando finaliza, la aplicación sale.

+0

No funciona en Windows, a quien corresponda –

+0

La belleza de OSS - envíeme un PR @ViniciusMonteiro :) –

+0

No sé si es necesario, porque en la página de Github dice que se requiere extensión PHP PCNTL y el manual de PHP dice que esta extensión no está disponible en Windows –

5

La forma en que entiendo su pregunta es que desea que el intérprete PHP se ejecute en la línea de comandos para que pueda evaluar cualquier código PHP que escriba. Uso esa característica de Python todo el tiempo para probar fragmentos de código.En cuyo caso, creo que la respuesta que busca es ejecutar (desde la línea de comandos):

php -a 

Suponiendo PHP está en su camino esto le caiga en la que el intérprete de PHP, como lo hace en la mía:

$ php -a 
Interactive shell 

php > 

Desde allí se puede comenzar a evaluar expresiones PHP arbitrarios y ver los resultados:

php > $a = 'abcdef'; 
php > echo strlen($a); 
6 
20

Dado que esta cuestión ha sido formulada y respondida, una apuesta La solución ter se ha agregado a PHP. En todas las versiones recientes de PHP, puede obtener fácilmente la entrada del usuario de la siguiente manera:

$input = fgets(STDIN); 
+1

Funciona si elimino el espacio en blanco: '$ input = rtrim (fgets (STDIN)); ' – pablofiumara

+2

¿A qué versión de PHP se aplica esto? –

+1

@AaronWallentine: Lo he estado usando desde al menos PHP 5.4. Tenga en cuenta que ** todas las ** versiones de PHP actuales admiten 'fgets (STDIN)' ahora. – dotancohen

2

Aquí hay una versión ampliada de esto. He agregado un cheque isCLI() en caso de que ejecute su script tanto en CLI como en un servidor web. De lo contrario, el servidor podría usar mi función en bucle. Esta solución solicitará al usuario, verificará la entrada y volverá a solicitar al usuario una entrada fija si es necesario. I rtrim() la entrada porque si el usuario usa regresar para enviar su entrada, puede adjuntarse a la entrada. La validación no es necesaria, simplemente no pase una función en ese caso.

function isCLI() { 
    return (php_sapi_name() === 'cli' OR defined('STDIN')); 
} 

function userPrompt($message, $validator=null) { 
    if (!isCLI()) return null; 

    print($message); 
    $handle = fopen ('php://stdin','r'); 
    $line = rtrim(fgets($handle), "\r\n"); 

    if (is_callable($validator) && !call_user_func($validator, $line)) { 
     print("Invalid Entry.\r\n"); 
     return userPrompt($message, $validator); 
    } else { 
     print("Continuing...\r\n"); 
     return $line; 
    } 
} 

// Example ===================== 

function validateSetLangCode($str) { 
    return preg_match("/^[A-Z0-9]{3}-[A-Z]{2}$/", $str); 
} 

$code = userPrompt("Please enter the set/language codes. Use the format 'SET-EN', where SET is the three-letter set code and EN is the two-letter lang code. \r\n", 'validateSetLangCode') ?: 'SET-EN'; 
var_dump($code); 
Cuestiones relacionadas