Windows环境下PHP调用Stockfish出现Bad file descriptor错误求助
Windows下PHP调用Stockfish出现Bad file descriptor错误的解决办法
问题概述
在Windows环境下通过PHP调用Stockfish时,触发PHP Notice: fwrite(): Write of 4 bytes failed with errno=9 Bad file descriptor错误,原代码基于Unix环境编写,存在路径适配、管道逻辑等兼容性问题。
修复步骤
1. 修正Stockfish路径格式
Windows系统使用\作为路径分隔符,相对路径写法与Unix不同,建议使用绝对路径避免歧义:
- 错误写法:
./stockfish-windows-x86-64.exe - 正确写法(示例):
C:\\Users\\asdfs\\OneDrive\\bugs\\stockfish\\stockfish-windows-x86-64.exe(注意转义反斜杠)
若exe与PHP文件同目录,也可直接写stockfish-windows-x86-64.exe或.\stockfish-windows-x86-64.exe。
2. 修复管道读写与进程状态判断逻辑
原代码循环条件错误,导致进程状态判断和管道读取逻辑混乱,同时缺少缓冲区刷新操作,修正要点:
- 写入命令后调用
fflush()确保命令立即发送到Stockfish - 调整while循环条件为
$status['running'] || !feof($pipes[1]),确保进程运行时或管道有内容时持续读取 - 关闭所有管道后再调用
proc_close()关闭进程
3. 检查文件权限与目录限制
OneDrive目录存在额外权限管控,可能导致PHP无法访问Stockfish文件:
- 将Stockfish.exe移至普通目录(如
C:\temp\stockfish\)测试 - 确保PHP运行用户(如IIS_IUSRS、Apache运行用户)拥有该文件的读取和执行权限
修正后的完整代码
<html> <body> <?php $descriptorspec = [ 0 => ["pipe", "w"], // 输入管道(写) 1 => ["pipe", "r"], // 输出管道(读) 2 => ["pipe", "r"] // 错误输出管道(读) ]; // 替换为你的Stockfish绝对路径 $stockfishPath = "C:\\Users\\asdfs\\OneDrive\\bugs\\stockfish\\stockfish-windows-x86-64.exe"; $process = proc_open($stockfishPath, $descriptorspec, $pipes); if (is_resource($process)) { // 检查输入管道有效性 if (is_resource($pipes[0])) { // 写入uci命令,用PHP_EOL适配系统换行符 fwrite($pipes[0], "uci" . PHP_EOL); // 刷新缓冲区确保命令发送 fflush($pipes[0]); } // 持续读取输出直到进程结束且管道为空 $status = proc_get_status($process); while ($status['running'] || !feof($pipes[1])) { if (!feof($pipes[1])) { $line = fgets($pipes[1]); // 转义HTML字符避免页面解析异常 echo htmlspecialchars($line) . "<br>"; } // 更新进程状态 $status = proc_get_status($process); // 短暂休眠降低CPU占用 usleep(10000); } // 关闭所有管道 fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); // 关闭进程并获取退出码 $exitCode = proc_close($process); echo "<br>进程退出代码: " . $exitCode; } else { echo "无法启动Stockfish进程,请检查路径是否正确、文件是否存在且有权限访问。"; } ?> </body> </html>
内容的提问来源于stack exchange,提问作者winapiadmin
相关产品推荐
相关产品推荐

