
本文详解如何在 python 中通过 subprocess.popen 调用 php -r 模式时,将 python 变量安全注入 php 代码字符串中,并避免语法错误与代码注入风险。
在 Python 中执行 PHP 代码(如使用 php -r)是一种跨语言调用的常见需求,但向 PHP 函数传参时容易因字符串拼接不当导致语法错误或安全隐患。你提供的代码中存在两个关键问题:一是误用了 {val} 这种类 f-string 的写法(但未启用 f-string),二是直接拼接用户可控变量到 PHP 字符串中,存在潜在的代码注入风险。
✅ 正确做法:使用 Python 字符串格式化 + PHP 安全转义
首先,修复语法错误:Python 的三重引号字符串中,{val} 不是合法占位符(除非使用 f-string)。应改为标准字符串拼接或 .format() / f"":
import subprocess
def php(code):
p = subprocess.Popen(["php", "-r", code],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if err:
raise Exception(err.decode('UTF-8'))
return out.decode('UTF-8')
val = "1234" # 注意:此处为字符串,避免 int 直接拼接引发类型错误
code = f"""\
function my_encoder($in) {{
return base_convert($in, 16, 36);
}}
echo my_encoder('{val}');
"""
print(php(code))? 关键修改说明:使用 f"""...""" 启用 f-string,使 {val} 正确插值;PHP 代码中的花括号 {} 需双写 {{ 和 }}(Python f-string 中转义);使用 echo 替代 print()(更符合 PHP CLI 习惯,且 print 在 -r 模式下行为一致,但 echo 更简洁);显式用单引号包裹 '${val}',确保 PHP 将其作为字符串字面量处理。
⚠️ 重要安全提醒:防范代码注入
若 val 来自用户输入(如表单、API 参数),绝不可直接拼接!例如 val = "1234'); system('rm -rf /'); echo('" 会导致任意命令执行。正确做法是:
- ✅ 对 PHP 字符串内容进行 JSON 编码并转义单引号:
import json safe_val = json.dumps(val).strip('"').replace("'", "\\'") code = f"""... my_encoder('{safe_val}');""" - ✅ 或更推荐:改用临时文件 + php filename.php 方式,完全隔离执行环境;
- ✅ 或使用 shlex.quote()(适用于 shell 层面参数隔离,但对 -r 内联代码帮助有限)。
? 总结
- 用 f-string 替代错误的 {val} 写法,注意 PHP 花括号需双写;
- 始终假设输入不可信,对动态插入的值做严格转义;
- 简单场景可用字符串插值,复杂逻辑建议拆分为独立 .php 文件调用;
- subprocess.Popen 后务必检查 stderr 并捕获异常,便于调试。
这样即可安全、清晰地在 Python 中向内联 PHP 代码传递参数。
立即学习“PHP免费学习笔记(深入)”;











