使用 fgetc() 函数和 STDIN 常量是使用仅 PHP 在 CLI 中获取用户输入的最佳和最简单方法
<?php
echo '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";
}
?>
注意: 此函数是二进制安全的。
使用 fgetc() 函数和 STDIN 常量是使用仅 PHP 在 CLI 中获取用户输入的最佳和最简单方法
<?php
echo 'Are you sure you want to quit? (y/n) ';
$input = fgetc(STDIN);
if ($input == 'y')
{
exit(0);
}
?>
我使用命令行 PHP 创建一个交互式脚本,并希望用户输入一个字符的输入 - 作为对是/否问题的响应。在使用 fgets()、fgetc()、各种使用 readline()、popen() 等的建议方面遇到了一些麻烦。想出了以下工作效果很好
$ans = strtolower( trim( `bash -c "read -n 1 -t 10 ANS ; echo \\\$ANS"` ) );
要在 CLI 模式下读取单个按键,您可以使用 ncurses(这可能需要为 PHP 安装额外的模块)或使用 *nix "/bin/stty" 命令进行操作
<?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();
?>
您不能像这样简单地打印以多字节字符集编码的文本的独立字符;
因为 fgetc() 会将每个多字节字符分解为其每个字节。考虑以下示例
<?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]: �
*/ ?>
我认为这不是最好的,但它可以作为一种解决方法
<?php
$path = 'path/to/your/file.ext';
if (!$handle = fopen($path, 'rb')) {
echo "无法打开 ($path) 文件';
exit;
}
$mbch = ''; // 保留 2 字节西里尔字母的第一个字节
while (FALSE !== ($ch = fgetc($handle))) {
// 检查 2 字节西里尔字母的标志
if (empty($mbch) && (FALSE !== array_search(ord($ch), Array(208,209,129)))) {
$mbch = $ch; // 保留第一个字节
continue;
}
$curs = ftell($handle);
print "[$curs]: " . $mbch . $ch . PHP_EOL;
// 或 print "[$curs]: $mbch$ch\n";
if (!empty($mbch)) $mbch = ''; // 使用后擦除字节
}
?>