本文详解如何在 python 中通过 subprocess.popen 调用 php -r 模式时,将 python 变量安全注入 php 代码字符串中,并避免语法错误与代码注入风险。
在 Python 中执行 PHP 代码(如使用 php -r)是一种跨语言调用的常见需求,但向 PHP 函数传参时容易因字符串拼接不当导致语法错误或安全隐患。你提供的代码中存在两个关键问题:一是误用了 {val} 这种类 f-string 的写法(但未启用 f-string),二是直接拼接用户可控变量到 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('" 会导致任意命令执行。正确做法是:
import json
safe_val = json.dumps(val).strip('"').replace("'", "\\'")
code = f"""... my_encoder('{safe_val}');"""这样即可安全、清晰地在 Python 中向内联 PHP 代码传递参数。