如何从Bash脚本调用PHP-FPM?需与浏览器执行版本一致
通过socat调用PHP-FPM获取正确输出的解决方案
我懂你想要实现浏览器和命令行用完全一致的PHP版本执行代码的需求,之前直接用echo '<?php echo 1' | socat - UNIX-CLIENT:/var/run/php/php7.2-fpm.sock没拿到输出,核心原因是:PHP-FPM是FastCGI服务器,它不会直接处理纯PHP代码,必须接收符合FastCGI协议规范的请求包。下面给你两种可行的解决办法:
方法一:用cgi-fcgi工具(最简单)
cgi-fcgi是专门用来和FastCGI服务器交互的工具,大部分Linux发行版都能通过包管理器安装:
- Debian/Ubuntu系:
sudo apt install libfcgi-bin - CentOS/RHEL系:
sudo yum install fcgi-devel
安装后,直接用以下命令就能执行PHP代码并得到输出:
echo -n '<?php echo 1; ?>' | cgi-fcgi -bind -connect /var/run/php/php7.2-fpm.sock
这里-bind参数让工具绑定标准输入输出,-connect指定PHP-FPM的Unix socket路径,执行后就能看到预期的1了。
方法二:手动构造FastCGI请求(无需额外工具)
如果你的系统没有cgi-fcgi,可以手动构造符合FastCGI协议的请求头,配合socat发送。下面是一个可以直接用的命令:
( # 设置FastCGI必需的环境变量 echo -n "CONTENT_LENGTH=$(echo -n '<?php echo 1; ?>' | wc -c)\r\n"; echo -n "SCRIPT_FILENAME=/dev/stdin\r\n"; # 告诉PHP-FPM从标准输入读取代码 echo -n "\r\n"; # 分隔头和请求体的空行 echo -n '<?php echo 1; ?>'; ) | socat - UNIX-CLIENT:/var/run/php/php7.2-fpm.sock | awk 'BEGIN {RS="\r\n\r\n"; getline} {print}'
解释一下:
- 首先构造FastCGI的环境变量,
CONTENT_LENGTH是要执行的PHP代码的长度,SCRIPT_FILENAME设为/dev/stdin让PHP-FPM读取标准输入的代码 - 用socat把构造好的请求发送到PHP-FPM的socket
- 最后用awk过滤掉FastCGI响应的头部信息,只提取PHP代码的实际输出
额外提示
如果要做浏览器和命令行通用的接口,你可以把上面的逻辑封装成一个简单的CLI脚本(比如php-fpm-exec.sh),这样命令行调用时更便捷,同时浏览器端正常通过Nginx/Apache转发到PHP-FPM,就能确保两边用的是完全一致的PHP版本了。
内容的提问来源于stack exchange,提问作者Pierre-Antoine Guillaume
相关产品推荐
相关产品推荐

