WordPress插件调用Python实时脚本页面加载异常解决方案咨询
问题描述
我为WordPress开发了一款简易插件,用于运行Python脚本并在文章中展示结果。该Python脚本通过WebSocket采集实时数据,会持续运行。但打开页面时会一直处于加载状态,我推测是PHP代码的问题(我不太熟悉PHP),想请教如何实现WordPress页面正常展示Python输出的实时数据。
当前PHP代码
function embed_python( $attributes ) { $data = shortcode_atts( [ 'file' => 'run.py' ], $attributes ); $handle = popen( __DIR__ . '/' . $data['file'], 'r' ); $read = ''; while ( ! feof( $handle ) ) { $read .= fread( $handle, 2096 ); } pclose( $handle ); return $read; } add_shortcode( 'python', 'embed_python' );
解决方案
你的问题核心是PHP同步等待持续运行的Python脚本结束,而Python脚本是实时采集数据的长期进程,所以PHP会一直卡在循环里,导致页面无限加载。要实现实时展示,需要改成「前端+后端异步通信」的模式,具体步骤如下:
1. 调整短代码逻辑,启动后台Python进程
修改PHP短代码,不再同步等待脚本输出,而是启动后台进程将数据写入临时文件,同时返回前端容器和实时读取的JS代码:
function embed_python( $attributes ) { $data = shortcode_atts( [ 'file' => 'run.py', 'output_file' => '/tmp/python_realtime_output.txt' ], $attributes ); $python_file = __DIR__ . '/' . $data['file']; $output_file = $data['output_file']; // 启动后台Python进程,输出重定向到文件,避免阻塞PHP $command = "nohup python3 $python_file > $output_file 2>&1 &"; exec($command); // 返回前端展示容器和轮询脚本 return '<div id="python-realtime-output" style="white-space: pre-wrap;"></div> <script> setInterval(() => { fetch(`/wp-json/python-realtime/v1/get-output?file=' . $output_file . '`) .then(res => res.text()) .then(content => { document.getElementById("python-realtime-output").textContent = content; }); }, 1000); // 每秒刷新一次数据 </script>'; } add_shortcode( 'python', 'embed_python' );
2. 添加REST API接口读取输出文件
创建WordPress REST接口,让前端可以安全读取Python的输出内容:
add_action('rest_api_init', function () { register_rest_route('python-realtime/v1', '/get-output', [ 'methods' => 'GET', 'callback' => 'get_python_realtime_output', 'permission_callback' => '__return_true' // 可根据需求调整权限校验逻辑 ]); }); function get_python_realtime_output($request) { $output_file = $request->get_param('file'); // 安全校验:限制仅读取指定目录下的文件,防止任意文件读取漏洞 if (strpos($output_file, '/tmp/') !== 0) { return new WP_Error('invalid_path', '无效文件路径', ['status' => 403]); } return file_exists($output_file) ? file_get_contents($output_file) : '暂无数据'; }
3. 优化Python脚本输出逻辑
让Python脚本将实时采集到的数据追加写入指定文件,示例:
import websocket import time OUTPUT_FILE = '/tmp/python_realtime_output.txt' def on_message(ws, message): # 追加写入数据,带上时间戳便于查看 with open(OUTPUT_FILE, 'a', encoding='utf-8') as f: f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {message}\n") def on_error(ws, error): with open(OUTPUT_FILE, 'a', encoding='utf-8') as f: f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 错误: {str(error)}\n") def on_close(ws): with open(OUTPUT_FILE, 'a', encoding='utf-8') as f: f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 连接已关闭\n") def on_open(ws): ws.send("请求实时数据") if __name__ == "__main__": ws = websocket.WebSocketApp("ws://你的WebSocket地址", on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close) ws.run_forever()
4. 关键注意事项
- 确保服务器安装了
python3和nohup命令,且WordPress进程有权限写入指定的临时文件目录 - 可以根据需求调整前端刷新间隔,或者改用WebSocket直接通信(更高效,无需轮询)
- 需处理Python进程重复启动问题:可通过记录PID文件,启动前检查是否已有运行的进程
内容的提问来源于stack exchange,提问作者marco aurelio
相关产品推荐
相关产品推荐

