杰瑞科技汇

WordPress如何调用Python脚本?

WordPress (PHP) 不能直接执行 Python 代码,它们之间需要一个“桥梁”或“中间人”来通信。

这个“中间人”可以有多种形式,下面我将从最推荐、最专业简单、适合快速测试的顺序,为你详细介绍几种主流的实现方法。


通过 REST API (最推荐、最专业)

这是目前最佳实践,它将 WordPress 作为前端和数据源,Python 脚本作为一个独立的后端服务,两者通过 HTTP 请求进行通信,实现了完美的解耦。

工作流程

  1. WordPress (PHP): 创建一个自定义的 REST API 端点(Endpoint),这个端点接收来自前端的请求。
  2. 触发: WordPress 中的某个操作(比如表单提交、定时任务、用户访问某个页面)会向这个 REST API 端点发送一个 HTTP 请求,并在请求体中携带需要传递给 Python 脚本的数据(文章 ID、用户输入的文本等)。
  3. Python 脚本: Python 脚本作为一个独立的 Web 服务(使用 Flask 或 FastAPI 框架)运行在服务器上,监听特定的端口,它接收 WordPress 发来的 HTTP 请求。
  4. 处理: Python 脚本执行其核心逻辑(分析文本、生成图片、调用 AI API)。
  5. 返回结果: Python 脚本将处理结果(分析报告、生成后的图片 URL、一个状态码)通过 HTTP 响应返回给 WordPress。
  6. WordPress (PHP): WordPress 接收 Python 返回的结果,然后根据需要进行后续操作,比如更新数据库、显示信息给用户。

实现步骤

第一步:在 WordPress 中创建 REST API 端点

你可以使用插件(如 Custom REST API Endpoints)或者直接在主题的 functions.php 文件中添加代码来创建端点。

示例代码 (functions.php):

add_action('rest_api_init', function () {
    // 注册路由: POST 请求到 /wp-json/myplugin/v1/run-python
    register_rest_route('myplugin/v1', '/run-python', array(
        'methods' => 'POST',
        'callback' => 'handle_python_request',
        'permission_callback' => function () {
            // 可以在这里添加权限检查,比如只有管理员能调用
            return current_user_can('manage_options');
        ),
    ));
});
function handle_python_request(WP_REST_Request $request) {
    // 1. 从请求中获取数据
    $params = $request->get_params();
    $text_to_analyze = sanitize_text_field($params['text']);
    // 2. 调用 Python 脚本(通过 shell_exec 或 cURL)
    // 注意:直接使用 shell_exec 有安全风险,请确保对输入进行严格验证和过滤!
    // 更安全的方式是使用 cURL 发送请求到你的 Python Web 服务。
    // 假设你的 Python 服务运行在 http://127.0.0.1:5000/process
    $python_service_url = 'http://127.0.0.1:5000/process';
    $post_data = json_encode(['text' => $text_to_analyze]);
    $ch = curl_init($python_service_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($post_data)
    ]);
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    // 3. 处理 Python 脚本的返回结果
    if ($http_code == 200) {
        $result = json_decode($response, true);
        return new WP_REST_Response(['success' => true, 'data' => $result], 200);
    } else {
        return new WP_Error('python_error', 'Failed to get response from Python service.', ['status' => $http_code]);
    }
}

第二步:创建 Python Web 服务

使用 Flask 或 FastAPI 等轻量级框架来创建服务。

示例代码 (app.py 使用 Flask):

from flask import Flask, request, jsonify
import some_python_library # 导入你需要的库,如 pandas, nltk, requests等
app = Flask(__name__)
@app.route('/process', methods=['POST'])
def process_text():
    # 1. 获取从 WordPress 发来的数据
    data = request.get_json()
    text = data.get('text', '')
    if not text:
        return jsonify({'error': 'No text provided'}), 400
    # 2. 执行你的 Python 逻辑
    # 这里只是一个示例:计算文本长度
    # 在实际应用中,这里可能是复杂的 NLP 分析、图像生成等
    processed_result = {
        'original_text': text,
        'length': len(text),
        'word_count': len(text.split()),
        'analysis': 'This is a sample analysis result from Python.'
    }
    # 3. 返回 JSON 响应
    return jsonify(processed_result)
if __name__ == '__main__':
    # 在开发模式下运行
    app.run(host='0.0.0.0', port=5000, debug=True)

如何运行 Python 服务?

  1. 安装 Flask: pip install Flask
  2. 将上述代码保存为 app.py
  3. 在服务器上运行: python app.py
  4. 确保服务器的防火墙允许 5000 端口的访问(至少允许本地访问)。

通过 Shell 命令调用 (简单直接,但有风险)

这种方法是 PHP 直接在服务器上执行一个 Shell 命令来运行 Python 脚本,它适用于简单的、快速的任务,但不推荐用于生产环境,因为它有严重的安全风险。

工作流程

WordPress (PHP) -> shell_exec() (或 exec()) -> Python 脚本 -> 返回结果给 PHP

实现步骤

PHP 代码 (functions.php):

add_action('wp_ajax_run_python_simple', 'run_python_simple_handler'); // 用于 logged-in 用户
add_action('wp_ajax_nopriv_run_python_simple', 'run_python_simple_handler'); // 用于未登录用户
function run_python_simple_handler() {
    // 1. 获取数据
    $text = $_POST['text'] ?? '';
    // 2. 安全警告:这是最不安全的方式!
    // 必须对输入进行极其严格的过滤,防止命令注入攻击。
    // 只允许字母、数字和基本标点。
    if (!preg_match('/^[a-zA-Z0-9\s\.\,\!\?\-]+$/', $text)) {
        wp_die('Invalid input.');
    }
    // 3. 构建命令
    // 注意:使用 escapeshellarg() 来转义参数,防止命令注入
    $python_script_path = '/path/to/your/server/python_script.py';
    $escaped_text = escapeshellarg($text);
    $command = "python3 " . escapeshellarg($python_script_path) . " " . $escaped_text;
    // 4. 执行命令并获取输出
    $output = shell_exec($command);
    // 5. 返回结果
    echo $output;
    wp_die(); // WordPress AJAX 请求需要调用 wp_die() 来结束
}

Python 脚本 (python_script.py):

import sys
# 从命令行参数获取输入
text_from_php = sys.argv[1]
# 执行你的逻辑
# 示例:将文本转为大写并计算字符数
uppercase_text = text_from_php.upper()
char_count = len(text_from_php)
# 将结果打印到标准输出
# PHP 的 shell_exec 会捕获这个输出
print(f"Original: {text_from_php}")
print(f"Uppercase: {uppercase_text}")
print(f"Character Count: {char_count}")

优缺点

  • 优点: 实现简单,无需额外的 Web 服务。
  • 缺点:
    • 安全风险极高: 容易受到命令注入攻击。
    • 性能差: 每次调用都要启动一个新的 Python 解释器,非常耗时。
    • 无状态: 不适合需要长时间运行或保持状态的任务。
    • 调试困难: 错误处理和日志记录比较麻烦。

使用队列系统 (高级,用于异步任务)

如果你的 Python 脚本执行时间很长(比如几分钟甚至几小时),同步等待(方法一和方法二)会导致用户请求超时。

这时,可以使用任务队列,如 Redis + RQ (Redis Queue) 或 Celery。

工作流程

  1. WordPress (PHP): 当需要执行 Python 任务时,它不直接调用脚本,而是将任务信息(数据、任务名等)推送到一个队列(如 Redis)中,然后立即返回一个“任务已接收”的响应给用户。
  2. Worker (Python): 一个或多个独立的 Python Worker 进程在后台监听这个队列,一旦有新任务,Worker 就会取出任务并执行。
  3. 结果存储: Worker 执行完毕后,可以将结果存储在数据库或缓存中。
  4. 状态查询: WordPress 可以通过另一个 API 端点来检查任务的执行状态和获取最终结果。

优点

  • 异步: 用户体验好,不会因为长时间任务而阻塞。
  • 可靠: 队列系统可以保证任务即使服务器重启也能被处理。
  • 可扩展: 可以轻松增加 Worker 数量来处理高并发任务。

缺点

  • 架构复杂: 需要额外部署和维护队列服务(如 Redis)和 Worker。
  • 开发成本高: 实现起来比前两种方法复杂得多。

总结与选择建议

方法 优点 缺点 适用场景
REST API 架构清晰、安全、可扩展、易于维护 需要额外部署 Python Web 服务 绝大多数生产环境,特别是需要与 WordPress 解耦、长期维护的项目。
Shell 命令 实现简单,无需额外服务 安全风险高、性能差、不灵活 快速原型验证、个人项目、绝对不要用于生产环境处理用户输入
队列系统 异步、高可靠、高并发 架构复杂,部署和维护成本高 处理耗时长的任务(如视频转码、复杂报告生成、AI 模型推理)。

给你的建议:

  • 如果你是初学者或做一个简单的个人项目:可以从方法二 (Shell 命令) 开始,但请务必注意安全,对输入数据进行严格过滤。
  • 如果你要做一个正式的、面向用户的项目,或者未来有扩展需求:请直接使用方法一 (REST API),这是最专业、最健壮的方案,花时间搭建好 Flask/FastAPI 服务,会让你未来的维护工作轻松很多。
  • 如果你的 Python 任务需要很长时间才能完成:请考虑使用方法三 (队列系统),以避免用户等待。
分享:
扫描分享到社交APP
上一篇
下一篇