
本文探讨了如何通过php在web浏览器中实现与外部可执行二进制文件的实时、交互式通信。虽然`proc_open()`能够执行外部程序并管理其i/o,但其默认模式难以满足即时双向交互的需求。为实现类似交互式shell的功能,核心方案是利用websockets建立浏览器与服务器间的持久连接,结合php后端对外部进程的异步控制,从而实现动态输入和实时输出。
在Web开发中,有时我们需要在服务器端执行一个外部的可执行二进制文件,并与它进行交互。例如,运行一个命令行工具、一个编译后的程序,甚至是模拟一个交互式Shell环境。PHP提供了proc_open()函数来启动外部进程并管理其标准输入(stdin)、标准输出(stdout)和标准错误(stderr)流。然而,要实现浏览器端与这些外部进程的实时、双向交互,并非简单地使用proc_open()就能完成。
proc_open() 是PHP中用于执行外部命令并创建管道与子进程进行通信的强大工具。通过定义描述符数组,我们可以将子进程的stdin、stdout和stderr映射到PHP脚本可以读写的管道。
以下是一个典型的proc_open()用法示例,它演示了如何向外部程序一次性发送输入,并一次性读取其所有输出和错误:
<?php
// 假设有一个名为 test.cpp 的C++程序,编译后生成 test.o
// test.cpp 内容可能如下:
// #include <iostream>
// int main() {
// int a, b;
// std::cout << "Enter first number: ";
// std::cin >> a;
// std::cout << "Enter second number: ";
// std::cin >> b;
// std::cout << "Sum: " << a + b << std::endl;
// return 0;
// }
$descriptorspec = [
0 => ["pipe", "r"], // 子进程的 stdin,PHP将写入
1 => ["pipe", "w"], // 子进程的 stdout,PHP将读取
2 => ["pipe", "w"] // 子进程的 stderr,PHP将读取
];
// 定义工作目录,确保编译和执行在正确的位置
$cwd = "/home/ixcoders/Desktop"; // 根据实际情况修改
// 编译C++程序并执行
// 注意:在实际生产环境中,通常不建议在运行时编译代码,而是预先编译好。
// 此处为了演示方便,将编译和执行放在一起。
$command = 'g++ test.cpp -o test.o && ./test.o';
$process = proc_open($command, $descriptorspec, $pipes, $cwd);
if (is_resource($process)) {
// 准备发送给子进程的输入。
// 例如,程序需要两个数字,我们提供 "4\n5"。
// 注意:这里的输入是预先确定的,一次性写入。
$inputs = "4\n5\n"; // 确保以换行符结束,模拟用户按下回车
// 将输入写入子进程的 stdin 管道
fwrite($pipes[0], $inputs);
fclose($pipes[0]); // 关闭 stdin 管道,表示输入已发送完毕
// 从子进程的 stdout 管道读取所有输出
$stdout_output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// 从子进程的 stderr 管道读取所有错误
$stderr_output = stream_get_contents($pipes[2]);
fclose($pipes[2]);
// 等待子进程结束并获取其返回码
$return_value = proc_close($process);
echo "--- Standard Output ---\n";
echo $stdout_output;
echo "\n--- Standard Error ---\n";
echo $stderr_output;
echo "\n--- Process Exit Code ---\n";
echo "Exit Code: " . $return_value . "\n";
} else {
echo "Failed to open process.\n";
}
?>局限性: 上述proc_open()的用法适用于“一次性”批处理任务。它在进程启动后一次性写入所有输入,然后等待进程完成并一次性读取所有输出。这种模式无法满足“当二进制程序产生输出时立即发送到浏览器”或“当二进制程序请求用户输入时,用户从浏览器提供输入”的实时交互需求。HTTP的请求-响应模型本身也不支持这种持久的双向通信。
立即学习“PHP免费学习笔记(深入)”;
要实现浏览器与外部进程的实时、交互式通信,我们需要一个持久的双向通信通道。WebSockets是解决此问题的核心技术。
基本架构思想:
工作流程:
**实现挑战与
以上就是PHP实现浏览器与外部可执行二进制文件的实时交互的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号