exec()默认只返回最后一行且不捕获stderr,应改用shell_exec()并重定向2>&1;Python需print(JSON)输出,PHP用json_decode解析;注意UTF-8编码与绝对路径。

PHP调用Python脚本时为什么exec()拿不到输出?
因为exec()默认只返回最后一行,且不捕获stderr。如果你的Python脚本用print()输出多行,或出错时抛异常,PHP里看到的可能是空字符串或截断内容。
- 改用
shell_exec()——它返回完整的stdout字符串(含换行) - 显式重定向
stderr:在命令末尾加2>&1,否则Python的报错(比如ModuleNotFoundError)完全看不到 - 确保Python脚本有可执行权限(
chmod +x script.py),或显式调用python3 /path/to/script.py
Python脚本怎么写才能让PHP安全读取返回值?
别依赖sys.exit(123)传数值——PHP的exec()第3个参数返回的是进程退出码,不是你想要的业务结果。真正要传数据,得走标准输出。
- Python里统一用
print(json.dumps({...}))输出结构化数据,避免空格、换行、编码混乱 - PHP侧用
json_decode($output, true)解析,失败时检查$output是否为空或含Traceback - 加
#!/usr/bin/env python3开头并设好shebang,或在PHP中硬编码/usr/bin/python3路径,避免环境差异
中文乱码和路径问题怎么快速定位?
常见于Windows本地开发或Linux上Python用了非UTF-8 locale。PHP拿到的字节流解码失败,json_decode()直接返回null。
- Python脚本开头加
import sys; sys.stdout.reconfigure(encoding='utf-8')(Python 3.7+) - 或者更稳妥:PHP中用
mb_convert_encoding($output, 'UTF-8', 'auto')预处理 - 路径别用相对路径——PHP的
getcwd()不一定是你预期的目录,全部用绝对路径,比如/var/www/scripts/tool.py
有没有比shell_exec()更可控的方式?
有。proc_open()能同时控制stdin、stdout、stderr,还能设超时,适合需要交互或防卡死的场景。
立即学习“PHP免费学习笔记(深入)”;
- 示例关键片段:
$descriptors = [ 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w'] ]; $proc = proc_open('python3 /path/to/script.py', $descriptors, $pipes); if (is_resource($proc)) { $output = stream_get_contents($pipes[1]); $error = stream_get_contents($pipes[2]); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($proc); } - 注意:必须
fclose()所有管道,否则可能阻塞;$error非空时优先查它,而不是盲解析$output











