readline

(PHP 4, PHP 5, PHP 7, PHP 8)

readlineLee una línea

Descripción

readline(string $prompt = null): string

Lee una sola línea del usuario. Debe agregar esta línea al historial utilizando readline_add_history().

Parámetros

mensaje

Puedes especificar un mensaje que se muestra al usuario.

Valores devueltos

Devuelve un único string del usuario. Esta línea retornada tiene el avance de línea al final eliminado.

Ejemplos

Ejemplo #1 Ejemplo de readline()

<?php
//obtener 3 comandos del usuario
for ($i=0; $i < 3; $i++) {
$linea = readline("Comando: ");
readline_add_history($linea);
}

//mostrar historial
print_r(readline_list_history());

//mostrar variables
print_r(readline_info());
?>

add a note add a note

User Contributed Notes 17 notes

up
12
Antony Penn
4 years ago
Christian's code works well, but if you want to be able to hide the user input and not echo it to screen, you need to add -s to the read command. The code below is an expanded function that allows an optional prompt and optional hiding of the input:

function read_password($prompt=null, $hide=false)
{
    if($prompt) print $prompt;
    $s = ($hide) ? '-s' : '';
    $f=popen("read $s; echo \$REPLY","r");
    $input=fgets($f,100);
    pclose($f);
    if($hide) print "\n";
    return $input;
}
up
2
mfuhrman at enetarch dot net
2 years ago
<?
/*
*
    I've noticed strange behavior from readline while using it for user input from a CLI.

    When I press multiple tabs it prints a scandir to the input stream.

    Below is the code:
*
*/

$msg = "";
while (
$msg != "quit")
{
    while ((
$msg == "") || ($msg == "\r"))
       
$msg = readline ("> ");
}
?>
up
4
turdsurfer
7 years ago
If your CLI script accepts input from STDIN and you also want it to prompt for a password (e.g. as mysql client does), then readline() won't work for you.
What you need to do is read from the terminal device as shown below.

function readline_terminal($prompt = '') {
    $prompt && print $prompt;
    $terminal_device = '/dev/tty';
    $h = fopen($terminal_device, 'r');
    if ($h === false) {
        #throw new RuntimeException("Failed to open terminal device $terminal_device");
        return false; # probably not running in a terminal.
    }
    $line = rtrim(fgets($h),"\r\n");
    fclose($h);
    return $line;
}
$pass = readline_terminal('Password: ');
up
3
rojaro at gmail dot com
16 years ago
Note that readline() will return boolean "false" when the user presses CTRL+D.
up
1
Anonymous
7 years ago
a few observations....

I use Cygwin PHP v7 and readline is available. The readline_list_history() function though is not defined.

A prompt with escape sequences are sanitized, so use something like:

<?php
   
echo("\e[0m\e[34mPromt>\e[0m");
   
$inp = readline(' ');
?>

I have not fully documented it, but I see that sometimes strings beginning with punctuation characters do not make it into the history with readline_add_history(). They also sometimes clear the prompt string.
up
1
soletan at toxa dot de
18 years ago
To haukew at gmail dot com:

readline provides more features than reading a single line of input ... your example misses line editing and history. If you don't need that, use something as simple as this:

function readline( $prompt = '' )
{
    echo $prompt;
    return rtrim( fgets( STDIN ), "\n" );
}
up
1
cox at idecnet dot com
22 years ago
In CGI mode be sure to call:

ob_implicit_flush(true);

at the top of your script if you want to be able to output data before and after the prompt.

-- Tomas V.V.Cox
up
0
mfuhrman at enetarch dot net
2 years ago
To stop auto complete , register an auto complete function that returns no matches to auto complete.

function dontAutoComplete ($input, $index)
{ return ([]); }

readline_completion_function ("dontAutoComplete");
up
0
Anonymous
13 years ago
The readline library is not available on Windows.

<?php
if (PHP_OS == 'WINNT') {
  echo
'$ ';
 
$line = stream_get_line(STDIN, 1024, PHP_EOL);
} else {
 
$line = readline('$ ');
}
?>
up
0
taneli at crasman dot fi
15 years ago
If you want to prefill the prompt with something when using readline, this worked for me:

<?php
 
function readline_callback($ret)
  {
    global
$prompt_answer, $prompt_finished;
   
$prompt_answer = $ret;
   
$prompt_finished = TRUE;
   
readline_callback_handler_remove();
  }

 
readline_callback_handler_install('Enter some text> ',
                                   
'readline_callback');

 
$prefill = 'foobar';
  for (
$i = 0; $i < strlen($prefill); $i++)
  {
   
readline_info('pending_input', substr($prefill, $i, 1));
   
readline_callback_read_char();
  }

 
$prompt_finished = FALSE;
 
$prompt_answer = FALSE;
  while (!
$prompt_finished)
   
readline_callback_read_char();
  echo
'You wrote: ' . $prompt_answer . "\n";
?>
up
-1
sean
15 years ago
I wanted a function that would timeout if readline was waiting too long... this works on php CLI on linux:

<?php

function readline_timeout($sec, $def)
{
    return
trim(shell_exec('bash -c ' .
       
escapeshellarg('phprlto=' .
           
escapeshellarg($def) . ';' .
           
'read -t ' . ((int)$sec) . ' phprlto;' .
           
'echo "$phprlto"')));
}

?>

Just call readline_timeout(5, 'whatever') to either read something from stdin, or timeout in 5 seconds and default to 'whatever'.  I tried just using shell_exec without relying on bash -c, but that didn't work for me, so I had to go the round about way.
up
-1
christian at gaeking dot de
20 years ago
A workaround if readline is not compiled into php, because for example the command is only needed within an installation routine. It works as follows under Linux:

$f=popen("read; echo \$REPLY","r");
$input=fgets($f,100);
pclose($f);       
echo "Entered: $input\n";
up
-1
divinity76+spam at gmail dot com
2 years ago
for some reason readline() doesn't support unicode, readline STRIPS æøåÆØÅ - for a readline function with unicode support, try
<?php
function readline_with_unicode_support(?string $prompt = null)/*: string|false*/
{
    if (
$prompt !== null && $prompt !== '') {
        echo
$prompt;
    }
   
$line = fgets(STDIN);
   
// readline() removes the trailing newline, fgets does not,
    // to emulate the real readline(), we also need to remove it
   
if ($line !== false && strlen($line) >= strlen(PHP_EOL) && substr_compare($line, PHP_EOL, -strlen(PHP_EOL), strlen(PHP_EOL), true) === 0) {
       
$line = substr($line, 0, -strlen(PHP_EOL));
    }
    return
$line;
}
up
-2
thflori
6 years ago
If you want to block remove previous text and wonder that an empty string does not work: the workaround is to use an space with cursor left:

<?php

echo "> ";
readline(" \e[D");

?>
up
-4
roddric dot kasen at gmail dot com
8 years ago
<?php

class ConsoleQuestion
{

    function
readline()
    {
        return
rtrim(fgets(STDIN));
    }
}

//Example1
$line = new ConsoleQuestion();
$prompt = "What Is Your Name: ";
echo
$prompt;
$answer = $line->readline();
echo
"You Entered: " . $answer;

//Example2 (comment Ex1 then uncomment Ex2)
/*$prompt = "What Is Your Name: ";
echo $prompt;
$answer =  "You Entered: " . rtrim( fgets( STDIN ));
echo $answer;*/

?>
up
-5
Ixios
6 years ago
Works under windows, and under php 7.2.0 :

$arr = [];

for ($i=0; $i < 3; $i++) {
        $arr[$i] = readline("Commande : ");
}

// Output
print_r($arr);

----------

Output:

Commande : 658
Commande : 965
Commande : 478
Array
(
    [0] => 658
    [1] => 965
    [2] => 478
)
up
-3
divinity76 at gmail dot com
2 years ago
<?php
/**
* readline() with unicode support
* php's builtin readline has dodgy unicode support, it only works
* with the correct environment locale settings, it doesn't seem to work at Cygwin (strips æøåÆØÅ),
* and it has historically had bugs like https://bugs.php.net/bug.php?id=81598
* meanwhile this readline has consistent unicode support across all platforms (including Cygwin)
* and doesn't care about locale settings.
*
* @param string $prompt
* @return string|false
*/
function readline_with_unicode_support(?string $prompt = null)/*: string|false*/
{
    if (
$prompt !== null && $prompt !== '') {
        echo
$prompt;
    }
   
$line = fgets(STDIN);
   
// readline() removes the trailing newline, fgets() does not,
    // to emulate the real readline(), we also need to remove it
   
if ($line !== false && strlen($line) >= strlen(PHP_EOL) && substr_compare($line, PHP_EOL, -strlen(PHP_EOL)) === 0) {
       
$line = substr($line, 0, -strlen(PHP_EOL));
    }
    return
$line;
}
To Top