在PHP中调用Python


82

我有一个最近写的Python脚本,我使用命令行中的某些选项进行了调用。我现在想要一个非常薄的Web界面在Mac上本地调用此脚本。

我不想在Mac上安装mod_python或mod_wsgi时遇到麻烦,所以我只想从PHP执行system()或popen()来调用Python脚本。

还有更好的主意吗?提前致谢!

Answers:


106

根据您在做什么,system()popen()可能是完美的。如果Python脚本没有输出,或者您希望Python脚本的输出直接进入浏览器,请使用system()。如果要向Python脚本的标准输入中写入数据,或从php中的Python脚本的标准输出中读取数据,请使用popen()。popen()仅允许您读取或写入,而不能两者都读取。如果两者都需要,请签出proc_open(),但是在程序之间进行双向通信时,需要小心避免死锁,因为每个程序都在等待对方做某事。

如果要将用户提供的数据传递给Python脚本,则要注意的主要事情是命令注入。如果您不小心,您的用户可以向您发送诸如“; evilcommand;”之类的数据。并让您的程序违反您的意愿执行任意命令。

escapeshellarg()escapeshellcmd()可以帮助解决这个问题,但是我个人喜欢使用类似以下的方法删除所有不是好的字符

preg_replace('/[^a-zA-Z0-9]/', '', $str)

1
子流程模块已直接使用os.Popen [n]替换。您应该改用它。
Nick Stinemates

6
@Nick Stinemates:我们正在谈论PHP函数;)
Glaslos 2011年

有没有像C的execve()这样不涉及shell的解决方案,除了它在单独的进程上运行而不是必须先进行fork()之外。
Lie Ryan

有并且总是存在解决方案,但是您必须在某个地方运行python才能从中获得一些收益。您可以制作简单的python服务,等待输入直到有输入,或者以某种方式触发您的程序(例如linux inotify),然后是那些PHP扩展,然后是linux服务器的本地套接字。PHP中的Python看起来是最好的NoShell解决方案,因为其他(非插件)在您的python周围总会有某种外壳。
Sampo Sarrala-codidact.org 2014年

27

反引号运算符还将允许您使用与上面类似的语法运行python脚本

在名为python.py的python文件中:

hello = "hello"
world = "world"
print hello + " " + world

在一个名为python.php的php文件中:

$python = `python python.py`;
echo $python;

15

还有一个PHP扩展:Pip-PHP中的Python,我从没有尝试过,但是在这种情况下将其添加为书签


11
请注意,名称“ pip”也用于描述极为流行且相当标准的Python软件包管理工具,因此,对于此PHP工具而言,这真是一个糟糕,令人困惑和注定的名称。也许这就是为什么它这么长时间没有更新。
GregD

2
看起来它还在继续(没有糟糕的名字选择)github.com/jparise/php-python
benekastah 2013年

11

您可以通过php运行python脚本,并在浏览器上输出。

基本上,您必须以这种方式调用python脚本:

$command = "python /path/to/python_script.py 2>&1";
$pid = popen( $command,"r");
while( !feof( $pid ) )
{
 echo fread($pid, 256);
 flush();
 ob_flush();
 usleep(100000);
}
pclose($pid);

注意:如果您在python代码中运行任何time.sleep(),它将不会在浏览器上输出结果。

要获取完整的代码,请访问如何从php执行python脚本并在浏览器上显示输出


如何在此处指定相对和绝对路径。基本上我在letsay文件夹下有我的python脚本,tempmon并且同一文件夹包含我的python脚本。我希望该应用程序具有可移植性,因此只需将其复制到tempmon下的文件夹即可htdocs。同样的应该在不同的机器上工作。
克里希纳(Krishna Oza)2015年

完美的工作。您可以添加打开和关闭php标签<?php?>,以便初学者更好地理解
Zaheer

7

对于无聊的脚本,我一直都在做这种事情。使用仅使用system / popen调用某些外部程序的CGI或PHP脚本是很常见的。

如果您的Web服务器对Internet完全开放,请格外小心。在这种情况下,请确保清理GET / POST输入,以免攻击者在您的计算机上运行任意命令。


3

您的call_python_file.php应该如下所示:

<?php
    $item='Everything is awesome!!';
    $tmp = exec("py.py $item");
    echo $tmp;
?>

这将执行python脚本,并将结果输出到浏览器。在您的python脚本中,(sys.argv [1:])变量将引入所有参数。要将argv显示为字符串,以表示您的php所处的位置,因此,如果要执行文本区域操作:

import sys

list1 = ' '.join(sys.argv[1:])

def main():
  print list1

if __name__ == '__main__':
    main()

0

请注意,如果您使用的是虚拟环境(例如在共享主机中),则必须调整python的路径,例如: /home/user/mypython/bin/python ./cgi-bin/test.py


0

上述方法似乎很复杂。使用我的方法作为参考。

我有这两个文件

运行.php

mkdir.py

在这里,我创建了一个包含GO按钮的html页面。每当您按下此按钮时,都会在您提到的路径中的目录中创建一个新文件夹。

运行.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
    if(isset($_POST['GO']))
    {
        shell_exec("python /var/www/html/lab/mkdir.py");
        echo"success";
    }
?>

mkdir.py

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");

-2

如果要在PHP中执行Python脚本,则必须在php脚本中执行以下命令:

exec('your script python.py')

a)用空格隔开单独的参数,即试图your用参数script和调用程序python.py。b)除非Python脚本具有适当的shebang,否则必须调用Python解释器并将脚本名称传递给它(python script.py)。即使使用适当的shebang,这也是错误的,因为您随后会打电话./script.py而不使用解释器名称。
Tox
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.