从PHP shell_exec传递至Python的sys.argv变量被截断问题
解决PHP通过shell_exec传递URL参数被截断的问题
我来帮你搞定这个头疼的问题!你遇到的URL参数被截断,核心原因是URL里的特殊字符(比如&)在shell环境中会被当作命令分隔符——shell会把&后面的内容当成新的后台命令执行,导致Python脚本只能拿到&之前的部分,自然就出现了截断的情况。而且直接拼接字符串还存在命令注入的安全隐患,得赶紧修复~
快速修复方案:用escapeshellarg()转义参数
PHP提供了专门的函数escapeshellarg(),它会自动把参数转义成shell能正确识别的单个参数,处理所有特殊字符(比如&、?、空格等),完全避免shell解析的问题。
修改你的exec.php代码如下:
<?php $my_url="http://reviews.femaledaily.com/moisturizer-36/lotions/nature-republic/aloe-vera-92-soothing-gel-06?tab=reviews&cat=&cat_id=0&age=&order=nrd&page=1"; // 转义URL参数,确保shell将其视为单个完整参数 $escaped_url = escapeshellarg($my_url); echo shell_exec("python hello.py " . $escaped_url); ?>
这样修改后,Python的sys.argv[1]就能拿到完整的URL了,不会再被截断。
更安全的进阶方案:使用proc_open()
如果你的场景对安全性要求较高,或者需要处理更复杂的参数,推荐使用proc_open()。它可以直接传递参数数组,完全绕过shell解析,从根源上避免命令注入风险,也能更好地处理超长参数。
示例代码如下:
<?php $my_url = "http://reviews.femaledaily.com/moisturizer-36/lotions/nature-republic/aloe-vera-92-soothing-gel-06?tab=reviews&cat=&cat_id=0&age=&order=nrd&page=1"; // 直接定义命令和参数数组,无需手动转义 $cmd = ["python", "hello.py", $my_url]; // 设置进程的输入输出管道 $descriptorspec = [ 0 => ["pipe", "r"], // 标准输入 1 => ["pipe", "w"], // 标准输出 2 => ["pipe", "w"] // 标准错误 ]; // 创建并运行进程 $process = proc_open($cmd, $descriptorspec, $pipes); if (is_resource($process)) { // 读取Python脚本的输出 $output = stream_get_contents($pipes[1]); // 若需要排查错误,可读取标准错误输出:$error = stream_get_contents($pipes[2]); // 关闭管道和进程资源 fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); echo $output; } ?>
这种方式不需要担心任何shell解析的问题,参数会原封不动地传递给Python进程,是生产环境中更推荐的做法。
内容的提问来源于stack exchange,提问作者Billy Gunawan
相关产品推荐
相关产品推荐

