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 — Lê um caractere do ponteiro de arquivo
stream
O ponteiro de arquivo deve ser válido e deve apontar para um arquivo aberto com sucesso por fopen() ou fsockopen() (e ainda não fechado por fclose()).
Retorna uma string contendo um único caractere lido do ponteiro do arquivo
passado por stream
. Retorna false
em EOF.
Esta função pode
retornar o valor booleano false
, mas também pode retornar um valor não booleano que pode ser
avaliado como false
. Leia a seção sobre Booleanos para mais
informações. Use o operador
=== para testar o valor retornado por esta
função.
Exemplo #1 Um exemplo da fgetc()
<?php
$fp = fopen('algumarquivo.txt', 'r');
if (!$fp) {
echo 'Não é possivel abrir algumarquivo.txt';
}
while (false !== ($char = fgetc($fp))) {
echo "$char\n";
}
?>
Nota: Esta função é compatível com dados binários.
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();?>