diff --git a/demo/Commands/DemoOptionsStrictTypes.php b/demo/Commands/DemoOptionsStrictTypes.php index a52d1be..0b43edf 100644 --- a/demo/Commands/DemoOptionsStrictTypes.php +++ b/demo/Commands/DemoOptionsStrictTypes.php @@ -179,7 +179,7 @@ protected function executeAction(): int // //////////////////////////////////////// Standard input // echo " Qwerty 123 " | php ./my-app examples:agruments - self::getStdIn(); // " Qwerty 123 \n" + $this->_('STDIN: "' . self::getStdIn() . '"'); // " Qwerty 123 \n" // Default success exist code is "0". Max value is 255. return self::SUCCESS; diff --git a/src/CliCommand.php b/src/CliCommand.php index 4fe919d..5420bcc 100644 --- a/src/CliCommand.php +++ b/src/CliCommand.php @@ -429,15 +429,33 @@ protected function askOption(string $question, array $options, null|float|int|st ); } - protected static function getStdIn(): ?string + /** + * Reads input from STDIN with an optional timeout. + * + * @param int $timeout the timeout value in seconds (default: 5) + * @return null|string the string read from STDIN, or null if an error occurred + * @throws Exception if there was an error reading from STDIN or if the read operation timed out + */ + protected static function getStdIn(int $timeout = 5): ?string { - static $result; // It can be read only once, so we save result as internal varaible + static $result; // It can be read only once, so we save result as internal variable if ($result === null) { $result = ''; - while (!\feof(\STDIN)) { - $result .= \fread(\STDIN, 1024); + $read = [\STDIN]; + $write = []; + $except = []; + $streamCount = \stream_select($read, $write, $except, $timeout); + + if ($streamCount > 0) { + while ($line = \fgets(\STDIN, 1024)) { + $result .= $line; + } + } + + if ($result === '') { + cli("Reading from STDIN timed out ({$timeout} seconds)", OutLvl::WARNING); } }