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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:41:04