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

PHP exec()调用Python脚本时json.load()失效问题

排查PHP exec()调用Python脚本卡在json.load()的问题

我帮你梳理下这个问题——单独跑正常但通过PHP调用就卡在json.load(),还没错误输出,这种情况基本都是环境/权限/路径的差异导致的,给你几个具体的排查和解决方向:

1. 先把路径问题彻底解决

你单独运行脚本时,当前工作目录是你手动启动的目录,但PHP的exec()调用时,工作目录大概率是Web服务器的运行目录(比如Apache的/var/www/html或者Nginx对应的站点目录)。如果你的find_files用的是相对路径,那PHP调用时根本找不到那些JSON临时文件,后续的open(file)和json.load()自然会出问题,但因为没捕获异常,错误信息又没输出出来。

解决办法:

  • 把脚本里所有涉及文件/目录的路径都改成绝对路径,比如用os.path.abspath("your_temp_dir")来生成绝对路径;
  • 或者在PHP调用脚本时,通过命令行参数传递绝对路径给Python脚本,比如:
    exec("python3 /path/to/your_script.py /absolute/path/to/json_dir 2>&1 > output.txt");
    
    然后在Python脚本里用sys.argv[1]接收这个绝对路径。

2. 强制捕获并输出所有异常

你现在的代码没有异常处理,而且PHP调用时stdout和stderr可能没有被正确重定向,导致错误信息没写到output.txt里。给处理JSON的那段代码加上完整的异常捕获:

首先在脚本开头导入sys:

import sys
import os
import json

然后修改循环部分:

for file in json_files:
    base = os.path.basename(file)
    id = os.path.splitext(base)[0]
    try:
        # 用with语句自动管理文件句柄,更安全
        with open(file, 'r', encoding='utf-8') as opened_file:
            print(f"正在处理文件: {file}")
            json_data[id] = json.load(opened_file)
            print(f"成功加载文件: {file}")
    except Exception as e:
        # 把错误输出到stderr,确保能被重定向捕获
        print(f"处理文件{file}出错: {str(e)}", file=sys.stderr)
        # 也可以直接抛出异常让脚本终止,方便定位
        raise

同时,PHP调用时要把stderr重定向到输出文件:

exec("python3 /path/to/your_script.py 2>&1 > output.txt");

这样不管是正常输出还是错误信息,都会写到output.txt里,你就能看到到底是JSON格式错了,还是文件找不到,或者权限问题。

3. 检查Python环境差异

你手动运行的Python和PHP调用的Python可能不是同一个版本!比如你手动用的是python3.10,但PHP调用的是系统默认的python2.7,那json模块的行为会有差异,甚至可能直接报错。

在脚本开头加一行输出Python版本:

print(f"当前Python版本: {sys.version}")

然后看output.txt里的版本是不是你预期的。如果版本不对,就在exec()里用Python的绝对路径调用,比如:

exec("/usr/bin/python3.10 /path/to/your_script.py 2>&1 > output.txt");

(绝对路径可以通过which python3命令在终端里查到)

4. 检查文件权限

PHP运行时用的是Web服务器的用户(比如www-data、apache),这个用户有没有读取你的JSON临时文件的权限?你手动运行时用的是自己的用户,权限没问题,但Web用户可能没有访问那个临时目录的权限。

解决办法:

  • 在生成临时JSON文件的时候,设置合适的权限,比如:
    os.chmod(temp_json_file, 0o644)  # 让其他用户也能读取
    
  • 或者把临时文件存到Web用户有权限的目录,比如/tmp(这个目录一般所有用户都能读写)。

5. 确认JSON文件的完整性

会不会是PHP调用时,生成JSON临时文件的过程还没结束,Python脚本就开始读取了?比如你的Python脚本是在文件还在被写入的时候执行json.load(),导致JSON格式不完整,从而卡住。

可以在Python脚本里加个简单的判断,比如等待文件大小稳定后再读取:

import time

def wait_file_stable(file_path, wait_time=1):
    prev_size = -1
    while True:
        current_size = os.path.getsize(file_path)
        if current_size == prev_size:
            break
        prev_size = current_size
        time.sleep(wait_time)

# 在读取文件前调用
wait_file_stable(file)
with open(file, 'r', encoding='utf-8') as opened_file:
    json_data[id] = json.load(opened_file)

按照这些步骤排查,应该能很快找到问题所在!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:01:30