PHP 脚本无法从 Python 脚本获取输出

标签 php python apache numpy

我在从 PHP 脚本执行 Python 脚本时遇到问题。我的客户端使用 Bluehost,因此我使用此处描述的 easy_install 方法为 Python 安装了第三方模块 (numpy):https://my.bluehost.com/cgi/help/530?step=530

为了演示我的问题,我创建了两个 Python 脚本和一个 PHP 脚本。

hello.py 包含:

print "Hello, World!"

hello-numpy.py 包含:

import numpy
print "Hello, World!"

PHP 脚本包含:

Output from exec('python hello.py'): <?php echo exec('python hello.py'); ?><br>
Output from exec('python hello-numpy.py'): <?php echo exec('python hello-numpy.py'); ?><br>
Output from exec('whoami'): <?php echo exec('whoami'); ?>

然后我从 PHP 得到这个输出:

Output from exec('python hello.py'): Hello, World!
Output from exec('python hello-numpy.py'):
Output from exec('whoami'): venicetw

但是,从 SSH 窗口运行这些脚本会产生以下结果:

# python hello.py
Hello, World!
# python hello-numpy.py
Hello, World!
# whoami
venicetw

当 Python 脚本导入 numpy 时,PHP 似乎没有得到任何输出,但它在 SSH 中运行良好。此外,PHP 对 hello.py 的返回状态为 0,对 hello-numpy.py 的返回状态为 1。我认为这可能是权限问题,但 PHP 和 SSH 都以“venicetw”用户身份运行。什么会阻止 PHP 和 Apache 从 Python 脚本获取输出?这是我可以与 Bluehost 讨论的事情,还是我应该检查的其他事情?我们正在使用 Apache 2.2.21PHP 5.2.17Python 2.4.3numpy 1.6.0.

更新:SSH 打印以下 Python 路径:

/home8/venicetw/public_html/venicenoise/python
/home8/venicetw/.local/lib/python2.4/site-packages/ogcserver-0.1.0-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/PIL-1.1.7-py2.4-linux-x86_64.egg
/home8/venicetw/.local/lib/python2.4/site-packages/lxml-2.3.2-py2.4-linux-x86_64.egg
/home8/venicetw/.local/lib/python2.4/site-packages/WebOb-1.2b2-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/PasteScript-1.7.5-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/PasteDeploy-1.5.0-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/Paste-1.7.5.1-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/numpy-1.6.0-py2.4-linux-x86_64.egg
/home8/venicetw/.local/lib/python2.4/site-packages
/home8/venicetw/.local/lib/python/site-packages
/home8/venicetw/public_html/venicenoise/python
/usr/lib64/python24.zip
/usr/lib64/python2.4
/usr/lib64/python2.4/plat-linux2
/usr/lib64/python2.4/lib-tk
/usr/lib64/python2.4/lib-dynload
/usr/lib64/python2.4/site-packages
/usr/lib64/python2.4/site-packages/Numeric
/usr/lib64/python2.4/site-packages/PIL
/usr/lib64/python2.4/site-packages/gtk-2.0
/usr/lib/python2.4/site-packages

但是 Apache 只打印这些 Python 路径:

/home8/venicetw/public_html/venicenoise/python
/usr/lib64/python24.zip
/usr/lib64/python2.4
/usr/lib64/python2.4/plat-linux2
/usr/lib64/python2.4/lib-tk
/usr/lib64/python2.4/lib-dynload
/usr/lib64/python2.4/site-packages
/usr/lib64/python2.4/site-packages/Numeric
/usr/lib64/python2.4/site-packages/PIL
/usr/lib64/python2.4/site-packages/gtk-2.0
/usr/lib/python2.4/site-packages

解决方案: 通过从 PHP 和 SSH 执行/usr/bin/env,我能够确定 PHP 缺少安装 numpy 的 Python 路径的环境变量。在这种情况下,通过添加

putenv('PYTHONPATH=/home8/venicetw/.local/lib/python2.4/site-packages:/home8/venicetw/.local/lib/python/site-packages:');

到 PHP 脚本的开头,一切都按预期工作。

最佳答案

如果 PHP 获得返回状态 1,则表示您运行的进程遇到了错误。 (非零退出状态通常表示 Unix 风格系统上的错误。几个程序是不同的,例如,diff。)尝试检查 stderr由子流程生成以查看那里打印的错误消息。

您可以这样显示 stderr:

Output from exec('python hello-numpy.py'):
    <?php echo exec('python hello-numpy.py 2>&1'); ?><br>

2>&1 指示 shell 将 stderrstdout 合并为一个流。您通常不想这样做,但这样做可以很容易地看到错误。

更新:由于您收到的错误是ImportError: No module named numpy,我们可以尝试查看 Python 的路径。有可能你的系统上安装了多个 Python,也有可能 Apache 的环境(根目录等)与你通过 SSH 运行 Python 时得到的环境不同。尝试在两种环境中执行此 Python 脚本:

import sys, os
for path in sys.path:
    print path
print
print 'Root:', os.readlink('/proc/self/root') # Linux only

其中一个路径应该指向 numpy 的安装位置,当您在 Apache 中运行它时,它可能会丢失。或者 Apache 进程可能有一个不同的根目录,该目录将由 Python 进程继承。

解决方案: 缺少环境变量。查看评论。

关于PHP 脚本无法从 Python 脚本获取输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8704519/

相关文章:

apache - 在 Apache POI HSSF 中,单元格类型仍然显示为 "General"Excel,即使它是数字格式的

php - 期末取消订阅

python - 将 numpy 安装到目录后,AWS Lambda 中缺少必需的依赖项 ['numpy' ],如何修复?

python - 我无法使类方法起作用;如果我将方法代码复制粘贴到应该调用该方法的位置,它就可以工作

特定文件夹和路径的 Apache mod_rewrite

php - 将新规则添加到我的 htaccess 文件中以替换?经过/

php - xmlhttp.open(url) 和使用 AJAX 调用 php 函数不起作用?

javascript - css 在不同浏览器中翻转卡片

php - mysql,根据类别的UUID获取产品的总重量

python - 在 pandas DataFrame 中返回具有公共(public)列值的条目 - python