XAMPP环境下如何将PHP获取的上传文件名传递给Python脚本并解决参数读取报错
问题原因
- 文件上传逻辑错误:PHP中
$_FILES["loadfile"]["name"]仅为用户本地的原始文件名,上传后的文件实际存储在临时路径$_FILES["loadfile"]["tmp_name"]中,你没有将临时文件移动到项目可访问的目录,Python脚本根本找不到对应名称的文件。 - 参数传递&路径问题:
- XAMPP的Apache进程运行时的工作目录不是你项目目录,直接调用
python formatfiletoJSON.py可能找不到脚本,也无法按相对路径定位上传的文件。 - 你没有对传递的文件名做shell转义,特殊字符会导致参数传递截断。
- Python脚本中硬编码了
filename +'.py'的后缀拼接逻辑,如果用户上传的文件本身就带.py后缀,会导致查找的文件名变成xxx.py.py,文件不存在直接报错中断执行。
- XAMPP的Apache进程运行时的工作目录不是你项目目录,直接调用
- 终端运行报错属于正常现象:你直接运行Python脚本时没有传递参数,
sys.argv只有脚本名一个元素,取sys.argv[1]自然会触发索引越界错误。 - PHP判断逻辑错误:
isset($_FILES["loadfile"]) > 0写法无效,isset返回布尔值,无法正确判断文件是否上传成功。
解决方法
1. 修改PHP代码
<?php // 定义项目根目录绝对路径,按需修改成你自己的路径 define('PROJECT_PATH', 'C:/xampp/htdocs/project_real/'); // 判断文件上传成功 if (isset($_FILES["loadfile"]) && $_FILES["loadfile"]["error"] == UPLOAD_ERR_OK) { // 原始文件名 $nameOfTheFile = $_FILES["loadfile"]["name"]; // 临时文件路径 $tmp_path = $_FILES["loadfile"]["tmp_name"]; // 移动临时文件到项目目录 $target_path = PROJECT_PATH . basename($nameOfTheFile); move_uploaded_file($tmp_path, $target_path); // 转义参数防止shell注入,路径全用绝对路径 $escaped_file = escapeshellarg($target_path); $python_path = escapeshellarg("C:/Python/Python39/python.exe"); $py_script_path = escapeshellarg(PROJECT_PATH . "formatfiletoJSON.py"); // 执行命令 $temp = shell_exec("$python_path $py_script_path $escaped_file"); echo $temp; } ?> <form action="<?php htmlentities($_SERVER['PHP_SELF'])?>" method="post" enctype="multipart/form-data"> Select image to upload: <input type="file" name="loadfile" id="loadfile"> <input type="submit" value="Upload Image" name="submit"> </form>
2. 修改Python脚本
#!C:\Python\Python39\python.exe import json import sys print ('Content-type: text/html\n\n') # 先判断是否有传参数 if len(sys.argv) < 2: print(json.dumps({"error": "未接收到文件名参数"})) sys.exit() filename = sys.argv[1] # 加异常捕获,排查文件读取问题 try: with open(filename, 'r', encoding='utf-8') as inFile: funcs = inFile.read().split('\n\n') result = {} for elem in funcs: if elem.startswith('def'): sign, commands = elem.split(':', 1) commands = list(map(str.strip, commands.split('\n')))[1:] result.update({sign.strip() : commands}) y = json.dumps(result, ensure_ascii=False) print(y) except Exception as e: print(json.dumps({"error": f"文件处理失败:{str(e)}"}))
修改点说明:
- 新增参数长度判断,无参数时返回明确错误
- 去掉了
+'.py'的后缀拼接,PHP传递的是完整的文件绝对路径,不需要额外加后缀 - 新增异常捕获,文件读取/处理出错时返回错误信息方便排查
split(':')改成split(':',1),避免函数定义里有冒号时拆分错误- 新增编码指定,避免中文乱码
3. 终端测试说明
如果要在VS Code终端测试Python脚本,需要传入完整的文件路径参数,示例:
python C:\xampp\htdocs\project_real\formatfiletoJSON.py C:\xampp\htdocs\project_real\function.py
就不会触发索引越界错误。
内容的提问来源于stack exchange,提问作者Gerald
相关产品推荐
相关产品推荐

