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

Laravel PHP服务调用Python服务传递文件避免死锁方案咨询

解决PHP调用Python服务时的文件传递死锁问题

你遇到的死锁问题核心逻辑很清晰:PHP发起POST请求到Python服务后,会一直持有连接等待响应;而Python服务此时尝试通过HTTP请求从PHP服务器下载文件,如果你的PHP服务器是单进程模式(比如用php -S启动的内置开发服务器),它会被当前的请求完全占用,无法处理Python的下载请求,最终导致两边互相等待,形成死锁。

下面给你几个可行的解决方案,按推荐程度排序:

方案1:直接在POST请求中上传文件内容

最直接的解决方式是跳过“传URL再下载”的冗余环节,PHP在发起POST请求时直接把文件内容作为请求的一部分发送给Python,这样Python不需要再反向请求PHP服务器,从根源上避免死锁。

修改后的PHP代码

我们改用multipart/form-data格式来上传文件(用curl实现更稳定):

<?php
// 替换为你的docx文件路径
$filePath = storage_path('app/documents/test.docx');
$fileName = basename($filePath);

// 初始化curl请求
$ch = curl_init('http://localhost:5000/api/extraction');
curl_setopt($ch, CURLOPT_POST, true);

// 构建上传表单
$postFields = [
    'file' => new CURLFile(
        $filePath,
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        $fileName
    )
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);

// 设置超时和结果返回方式
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// 执行请求并处理结果
$result = curl_exec($ch);
curl_close($ch);

var_dump($result);
?>

修改后的Python代码

Flask直接接收上传的文件即可:

from flask import Flask, request
from werkzeug.utils import secure_filename
import os

app = Flask(__name__)
app.config['UPLOAD_FILE_FOLDER'] = '/path/to/your/python/upload/folder'

@app.route('/api/extraction', methods=['POST'])
def extraction():
    if 'file' not in request.files:
        return 'No file uploaded', 400
    
    file = request.files['file']
    if file.filename == '':
        return 'No selected file', 400
    
    if file:
        filename = secure_filename(file.filename)
        path = os.path.join(app.config['UPLOAD_FILE_FOLDER'], filename)
        file.save(path)
        
        # 这里添加你的Word文档数据提取逻辑
        return 'File processed successfully', 200

if __name__ == '__main__':
    app.run()

方案2:确保PHP服务器支持多并发请求

如果你坚持要使用“传递文件URL”的方式,那必须确保你的PHP服务器能够同时处理多个请求,避免因为当前的POST请求占用进程,无法响应Python的下载请求。

  • 如果你之前用的是php -S启动的内置开发服务器,它是单进程的,这是死锁的核心诱因。可以换成Nginx+PHP-FPM的生产环境配置;如果是Laravel项目,也可以用多进程启动开发服务器:php artisan serve --workers=4。
  • Python这边的代码可以保持你原来的写法,只要PHP服务器能同时处理两个请求(PHP发往Python的POST、Python发往PHP的下载请求),死锁问题就会消失。

方案3:使用共享存储传递文件

另一种思路是把文件放到PHP和Python都能访问的共享存储中,彻底绕开HTTP反向请求:

  • 本地共享目录(如果两个服务部署在同一台机器上)
  • Redis(存储文件二进制内容)
  • 对象存储(比如MinIO、本地自建存储服务)

举个本地共享目录的简单例子:

  1. PHP把docx文件保存到双方都有权限访问的目录,比如/opt/shared_docs/
  2. PHP在POST请求中传递文件的共享路径(比如/opt/shared_docs/test.docx)
  3. Python直接从这个路径读取文件,不需要通过HTTP下载

这种方式也能完美避免死锁,适合两个服务部署在同一机器或同一局域网的场景。


内容的提问来源于stack exchange,提问作者Snakies

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:51:16