PHP调用Python传参失败主因是shell层参数转义或编码问题;需用escapeshellarg()包裹所有参数,确保UTF-8环境,JSON数据要先json_encode再escapeshellarg,超大数据改用临时文件或stdin。

PHP 调用 Python 脚本传参失败,90% 是 shell 层面的参数转义或编码问题,不是 PHP 或 Python 本身有 bug。
PHP exec() 传参时空格和特殊字符直接崩
PHP 的 exec()、shell_exec() 等函数不自动转义参数,只要 Python 脚本路径、参数里含空格、$、*、`、引号等,shell 就会提前截断或执行意外命令。
- 错误写法:
exec("python3 /path/to/script.py $name $age")——$name是变量,但没加引号,含空格就裂开 - 正确做法:用
escapeshellarg()包每一段参数,包括脚本路径本身 - 示例:
$cmd = 'python3 ' . escapeshellarg('/home/user/my script.py') . ' ' . escapeshellarg($username) . ' ' . escapeshellarg($score); exec($cmd, $output, $return_code); - 注意:
escapeshellarg()会加单引号并转义内部单引号,不能用于拼接带变量的 shell 表达式(比如$($cmd))
Python 端 sys.argv 拿到的参数莫名多出引号或乱码
这不是 Python 解析错了,是 PHP 传入时 shell 已经把引号当字面量传进去了,或者终端编码不一致导致 UTF-8 字符被截断。
- PHP 发起前确认 Web 服务器(如 Apache/Nginx)和 PHP 进程 locale 是 UTF-8,比如在脚本开头加
setlocale(LC_ALL, 'en_US.UTF-8'); - Python 脚本第一行加
# -*- coding: utf-8 -*-,读取sys.argv后立刻用.encode().decode('utf-8', 'surrogateescape')容错处理(尤其 Windows + 中文路径场景) - 更稳的方式:PHP 改用
proc_open()配置env并显式指定LC_ALL=C.UTF-8,避免继承脏环境
传数组或 JSON 给 Python 却变成一长串不可解析的字符串
PHP 无法直接把数组“塞进”命令行,json_encode() 后不转义就拼接,Python 端 json.loads(sys.argv[1]) 必然报 JSONDecodeError。
立即学习“PHP免费学习笔记(深入)”;
- 别手写拼接:
exec("python3 script.py " . json_encode($data))—— 引号嵌套全乱 - 正解:先
escapeshellarg(json_encode($data, JSON_UNESCAPED_UNICODE)),再传给 Python - Python 端用
json.loads(sys.argv[1])即可,无需额外 strip 或 replace - 超大数组或含二进制数据?改用临时文件或 stdin 流式传递,避免命令行长度限制(Linux 通常 2MB 上限)
真正麻烦的从来不是“怎么传”,而是“谁在中间动了参数”——Web 服务器的 suexec、容器里的非标准 shell、甚至 SELinux 策略都可能静默修改参数内容。先跑通一个纯 ASCII、无空格、无中文的最小用例,再逐步放开限制。











