Php 为什么当cmd.exe失去焦点时,STDIN上的stream_select变为阻塞?
目标:在cmd中运行一个PHP文件,脚本循环x次,在每次迭代中检查用户是否输入了任何输入(使用),如果输入了,则暂停循环,直到用户点击enter,然后打印出输入并继续迭代 问题:只要cmd.exe窗口处于焦点位置,脚本就可以正常运行-当我单击另一个窗口时,脚本会在Php 为什么当cmd.exe失去焦点时,STDIN上的stream_select变为阻塞?,php,stream,command-line-interface,stdin,blocking,Php,Stream,Command Line Interface,Stdin,Blocking,目标:在cmd中运行一个PHP文件,脚本循环x次,在每次迭代中检查用户是否输入了任何输入(使用),如果输入了,则暂停循环,直到用户点击enter,然后打印出输入并继续迭代 问题:只要cmd.exe窗口处于焦点位置,脚本就可以正常运行-当我单击另一个窗口时,脚本会在stream\u select处暂停,直到我将cmd窗口调回焦点并向其发送一些输入(只需按enter键即可)。没有错误 问题:为什么对cmd失去关注会影响stream\u选择并阻止循环。。。有解决办法吗?(例如,是否可以检查当前cmd窗
stream\u select
处暂停,直到我将cmd窗口调回焦点并向其发送一些输入(只需按enter键即可)。没有错误
问题:为什么对cmd失去关注会影响stream\u选择并阻止循环。。。有解决办法吗?(例如,是否可以检查当前cmd窗口是否处于焦点?)
代码示例,在工作目录中使用cmdphp script.php
<?php
$loopCount = 20;
while ($loopCount) {
$start = microtime(true);
echo 'check on "' . $loopCount . '"' . PHP_EOL;
$stream = fopen('php://stdin', 'r');
$stream_array = array($stream);
$write = array();
$except = array();
if (stream_select($stream_array, $write, $except, 1, 0)) {
$input = trim(fgets($stream));
if ($input) {
echo 'input was "' . $input . '"' . PHP_EOL;
}
}
fclose($stream);
echo $loopCount . ' in ' . (microtime(true) - $start) . PHP_EOL;
$loopCount--;
}
我认为问题是因为当流接收到EOL时,stream_select()也会为STDIN返回1,我认为当cmd失去焦点时会发生这种情况
从
特别是,流资源也在文件末尾准备就绪,在这种情况下,fread()将返回一个长度为零的字符串
当焦点未丢失且未提供任何输入时,stream_select返回0,传入的$read数组通过引用清空。当焦点丢失或输入给定时,$read数组保持不变,您需要读取每个索引
但这让我们窗口的用户处于一个糟糕的境地,因为我们无法用stream_get_(contents | line)或fread或fgets无阻塞地读取零长度字符串。由于我们无法区分失去焦点和提供实际数据,我认为我们必须等待其中一个bug得到修复:
我目前正在探索一种通过win32 API防止窗口失去焦点的方法,但这对于我的需要来说似乎都是不切实际的
这是我现在使用的解决方法