在PHP与Python混合开发的项目中,编码不一致是导致参数传递乱码的核心原因,通常PHP默认使用UTF-8编码,而Python2默认使用ASCII编码,Python3默认使用UTF-8编码,两端编码不匹配就会出现乱码问题。

PHP端的编码设置方法
设置PHP自身输出编码
首先需要确保PHP脚本的输出编码是UTF-8,避免自身输出内容就出现乱码。可以在脚本开头添加编码设置代码:
<?php
// 设置PHP默认编码为UTF-8
header("Content-type: text/html; charset=utf-8");
mb_internal_encoding("UTF-8");
mb_http_output("UTF-8");
// 测试输出中文是否正常
echo "PHP端编码设置完成";
?>
传递参数前的编码处理
如果参数包含中文,在传递给Python脚本前,需要确保参数是UTF-8编码,同时可以对参数进行转义处理,避免特殊字符影响命令执行:
<?php
$param = "测试中文参数";
// 确认参数是UTF-8编码,如果不是则转换
if (mb_detect_encoding($param, "UTF-8", true) === false) {
$param = mb_convert_encoding($param, "UTF-8", "GBK");
}
// 对参数进行shell转义,避免命令注入和特殊字符问题
$escaped_param = escapeshellarg($param);
// 调用Python脚本,传递参数
$command = "python test.py " . $escaped_param;
$output = shell_exec($command);
echo $output;
?>
Python端的编码设置方法
Python2的编码设置
Python2默认编码是ASCII,需要在脚本开头声明编码,同时处理输入参数的编码:
# -*- coding: utf-8 -*-
import sys
import os
# 设置标准输出编码为UTF-8
reload(sys)
sys.setdefaultencoding("utf-8")
# 获取传递的参数,Python2中sys.argv获取的是str类型,需要解码为unicode
if len(sys.argv) > 1:
param = sys.argv[1].decode("utf-8")
print "接收到的参数:%s" % param
else:
print "未接收到参数"
Python3的编码设置
Python3默认编码是UTF-8,不需要额外设置默认编码,但需要注意标准输入输出的编码配置:
# -*- coding: utf-8 -*-
import sys
import io
# 设置标准输出编码为UTF-8,避免输出乱码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
# 获取传递的参数,Python3中sys.argv默认是str类型,已经是unicode
if len(sys.argv) > 1:
param = sys.argv[1]
print("接收到的参数:%s" % param)
else:
print("未接收到参数")
常见乱码问题排查
- 检查PHP和Python两端的编码是否统一为UTF-8,避免一端GBK一端UTF-8的情况
- 确认参数传递过程中是否经过转义,特殊字符未转义可能导致参数截断出现乱码
- 如果是通过文件传递参数,检查文件的编码格式是否为UTF-8无BOM格式
- 查看系统默认编码,部分Linux系统默认编码不是UTF-8,会影响命令执行的结果编码
完整调用示例
以下是一个完整的PHP调用Python脚本传参的示例,两端都做了编码设置:
PHP端代码(call_python.php)
<?php
header("Content-type: text/html; charset=utf-8");
mb_internal_encoding("UTF-8");
$chinese_param = "PHP传递的中文参数";
// 转义参数
$escaped_param = escapeshellarg($chinese_param);
// 执行Python脚本
$result = shell_exec("python3 receive_param.py " . $escaped_param);
// 输出结果,确保编码正确
echo "Python返回结果:" . $result;
?>
Python端代码(receive_param.py)
# -*- coding: utf-8 -*-
import sys
import io
# 设置标准输出编码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
if len(sys.argv) > 1:
param = sys.argv[1]
print("成功接收参数:%s" % param)
else:
print("没有接收到参数")
按照以上步骤设置后,PHP调用Python脚本传参的乱码问题基本都可以解决,核心是保证两端编码一致,同时做好参数的转义处理。