You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 01:11:05