When several bytes arrive at once, fread(STDIN, 1) reads them all into the
stream's buffer. After that, stream_select() only checks the file
descriptor, so it reports "no data" and the remaining bytes are never read.
PHP counts buffered data as readable.
In a terminal this loses multi-byte keys: an arrow key (ESC [ A) shows up
as just ESC.
Reproduce
<?php
$got = '';
for ($i = 0; $i < 3; $i++) {
$r = [STDIN]; $w = $e = null;
if (stream_select($r, $w, $e, 0, 200_000) < 1) {
break;
}
$got .= fread(STDIN, 1);
}
echo "read: '", $got, "'\n";
(printf abc; sleep 1) | phpr select.php
- PHP 8.5.7:
read: 'abc'
- phpr:
read: 'a'
Environment: macOS 26.6.2 (Apple M1 Pro), Rust 1.96.0, commit 352d4129.
When several bytes arrive at once,
fread(STDIN, 1)reads them all into thestream's buffer. After that,
stream_select()only checks the filedescriptor, so it reports "no data" and the remaining bytes are never read.
PHP counts buffered data as readable.
In a terminal this loses multi-byte keys: an arrow key (
ESC [ A) shows upas just
ESC.Reproduce
read: 'abc'read: 'a'Environment: macOS 26.6.2 (Apple M1 Pro), Rust 1.96.0, commit
352d4129.