The best and simplest way to get input from a user in the CLI with only PHP is to use fgetc() function with the STDIN constant:<?phpecho 'Are you sure you want to quit? (y/n) ';$input = fgetc(STDIN);if ($input == 'y'){ exit(0);}?>
(PHP 4, PHP 5, PHP 7, PHP 8)
fgetc — 从文件指针中读取字符
返回一个包含有一个字符的字符串,该字符从 stream
指向的文件中得到。
碰到 EOF 则返回 false
。
示例 #1 一个 fgetc() 例子
<?php
$fp = fopen('somefile.txt', 'r');
if (!$fp) {
echo 'Could not open file somefile.txt';
}
while (false !== ($char = fgetc($fp))) {
echo "$char\n";
}
?>
注意: 此函数可安全用于二进制对象。
The best and simplest way to get input from a user in the CLI with only PHP is to use fgetc() function with the STDIN constant:<?phpecho 'Are you sure you want to quit? (y/n) ';$input = fgetc(STDIN);if ($input == 'y'){ exit(0);}?>
You can't just simple print separated characters of a text which is encoded in multibyte character set like this;Because fgetc() will break each multibyte character on its every byte. Consider this example: <?php$path = 'foo/cyrillic.txt';$handle = fopen($path, 'rb');while (FALSE !== ($ch = fgetc($handle))) { $curs = ftell($hanlde); print "[$curs:] $ch\n";}/* The result will be something like this:<[1]: <[2]: h[3]: 2[4]: >[5]: �[6]: �[7]: �[8]: �[9]: �[10]: �[11]: [12]: �[13]: �[14]: �[15]: �[16]: �*/ ?>I don't think this is the best, but it can be a workaround:<?php$path = 'path/to/your/file.ext';if (!$handle = fopen($path, 'rb')) { echo "Can't open ($path) file'; exit;}$mbch = ''; // keeps the first byte of 2-byte cyrillic letterswhile (FALSE !== ($ch = fgetc($handle))) { //check for the sign of 2-byte cyrillic letters if (empty($mbch) && (FALSE !== array_search(ord($ch), Array(208,209,129)))) { $mbch = $ch; // keep the first byte continue; } $curs = ftell($handle); print "[$curs]: " . $mbch . $ch . PHP_EOL; // or print "[$curs]: $mbch$ch\n"; if (!empty($mbch)) $mbch = ''; // erase the byte after using}?>
I was using command-line PHP to create an interactive script and wanted the user to enter just one character of input - in response a Yes/No question. Had some trouble finding a way to do so using fgets(), fgetc(), various suggestions using readline(), popen(), etc. Came up with the following that works quite nicely:$ans = strtolower( trim( `bash -c "read -n 1 -t 10 ANS ; echo \\\$ANS"` ) );
To read a single key-press in CLI mode, you can either use ncurses (which will probably require additional modules for PHP) or get nasty with the *nix "/bin/stty" command)<?php function stty($options) { exec($cmd = "/bin/stty $options", $output, $el); $el AND die("exec($cmd) failed"); return implode(" ", $output); } function getchar($echo = false) { $echo = $echo ? "" : "-echo"; # Get original settings $stty_settings = preg_replace("#.*; ?#s", "", stty("--all")); # Set new ones stty("cbreak $echo"); # Get characters until a PERIOD is typed, # showing their hexidecimal ordinal values. printf("> "); do { printf("%02x ", ord($c = fgetc(STDIN))); } while ($c != '.'); # Return settings stty($stty_settings); } getchar();?>