readline()
(PHP 4, PHP 5, PHP 7)
读取一行
说明
readline([string $prompt]): string
从用户端读取一行.你必须自己使用readline_add_history()将这一行添加到历史记录中
参数
- $prompt
你可以指定一个字符串来作为用户的提示信息
返回值
从用户端返回一个行字符串.返回的该行的行尾换行符会被删除
范例
readline() Example
<?php //get 3 commands from user for ($i=0; $i < 3; $i++) { $line = readline("Command: "); readline_add_history($line); } //dump history print_r(readline_list_history()); //dump variables print_r(readline_info()); ?>
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('$ '); } ?>
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 )
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: ');
Note that readline() will return boolean "false" when the user presses CTRL+D.
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";
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"; ?>
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" ); }
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
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"); ?>
<?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;*/ ?>
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.
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.