简体   繁体   English

使用 Apache 服务器用 PHP 执行 Python 脚本

[英]Executing a Python script with PHP using Apache server

I'm experiencing an odd issue.我遇到了一个奇怪的问题。 I have a Python script that I'm calling from a PHP script.我有一个从 PHP 脚本调用的 Python 脚本。 This is all running on an Apache server on Ubuntu 18.04.这一切都在 Ubuntu 18.04 上的 Apache 服务器上运行。 Part of the Python script uses the Google Drive API.部分 Python 脚本使用 Google Drive API。 EDIT: See the bottom After a lot of testing and replication,I've concluded that simply having the following Google Drive Python libraries and dependencies imported: 编辑:见底部 经过大量测试和复制,我得出的结论是只需导入以下 Google Drive Python 库和依赖项:

from __future__ import print_function
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from googleapiclient.http import MediaIoBaseDownload

Messes up the script when it is called from the web.从网络调用脚本时会弄乱脚本。 By that I mean the Python script does not seem to execute, and any shell output that I should be getting through print statements do not make their way back to the PHP script.我的意思是 Python 脚本似乎没有执行,并且我应该通过打印语句获得的任何 shell 输出都没有返回到 PHP 脚本。 When calling the script locally (python myscript.py), it works just fine.在本地调用脚本 (python myscript.py) 时,它工作正常。

The weird part is that when I remove these import statements from the Python script, it executes just fine from both PHP, and from directly launching the script from a browser.奇怪的是,当我从 Python 脚本中删除这些 import 语句时,它在 PHP 和直接从浏览器启动脚本时都可以正常执行。 In both of those cases I am also able to get the shell output back to the PHP script.在这两种情况下,我还能够将 shell 输出返回给 PHP 脚本。 I have given the proper permissions for the Python script, and I have configured Apache to be able run CGI scripts.我已为 Python 脚本授予适当的权限,并且已将 Apache 配置为能够运行 CGI 脚本。 Here is what my Python script looks like:这是我的 Python 脚本的样子:

#!/usr/bin/env python3
import cgitb

from __future__ import print_function
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from googleapiclient.http import MediaIoBaseDownload

cgitb.enable()
print("Hello World")

And here is what my PHP script looks like:这是我的 PHP 脚本的样子:

<?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $output = shell_exec("python path_to_my_script/myscript.py");
    echo $output;
?>

EDIT: I ran a couple of tests using another 3rd party Python library that I installed with pip, and this actually seems to be an issue with importing any 3rd party library when executing the script via PHP.编辑:我使用我用 pip 安装的另一个第 3 方 Python 库运行了几个测试,这实际上似乎是通过 PHP 执行脚本时导入任何第 3 方库的问题。

I Figured this out.我想通了。 Hopefully this will help anyone with a similar issue.希望这会帮助任何有类似问题的人。 When you execute a Python or shell script from a PHP script served on an Apache server, the script will be ran as the user, www-data by default.当您从 Apache 服务器上提供的 PHP 脚本执行 Python 或 shell 脚本时,该脚本将作为用户运行,默认情况下为 www-data。

By running the command sudo -u www-data (running the following command as the www-data user) python myscript.py, I got a traceback error that exclaimed that the 3rd party modules could not be found.通过运行命令 sudo -u www-data(以 www-data 用户身份运行以下命令)python myscript.py,我得到了一个回溯错误,提示无法找到第 3 方模块。 What's happening is that by default pip (python package manager) installs its packages on a user level basis.发生的事情是默认情况下 pip(python 包管理器)在用户级别的基础上安装它的包。 That's fine for most applications, but causes a problem in this case as the www-data user understandably cannot find the installed packages, and the script crashes.这对大多数应用程序来说都很好,但在这种情况下会导致问题,因为 www-data 用户可以理解地找不到已安装的包,并且脚本会崩溃。 This becomes particularly tricky from the perspective of the PHP script, as it doesn't understand this and the output is just null.从 PHP 脚本的角度来看,这变得特别棘手,因为它不理解这一点并且输出只是空值。

I understand that installing pip packages with sudo is not preferred as it can cause conflict issues in some cases;我知道使用 sudo 安装 pip 包不是首选,因为它在某些情况下会导致冲突问题; however, this is the easiest way to solve the problem for most packages.然而,这是解决大多数包问题的最简单方法。 For cases where this does not work, check out this answer from infinigrove: How to install Python Package for global use by all users (incl. www-data)对于这不起作用的情况,请查看 infinigrove 的这个答案: 如何安装 Python 包供所有用户全局使用(包括 www-data)

Finally, from what I could see in order to install a pip package as the www-data user (sudo -u www-data pip install package), www-data would have to be granted sudo permissions, which is definitely not a recommended solution.最后,据我所知,为了以 www-data 用户身份安装 pip 包(sudo -u www-data pip install package),www-data 必须被授予 sudo 权限,这绝对不是推荐的解决方案.

Your issue is a user permissions issue.您的问题是用户权限问题。 You should run the Apache server as the user that owns your python environment, or allow the user running the server execute permissions in your python environment.您应该以拥有python 环境的用户身份运行 Apache 服务器,或者允许运行服务器的用户在您的 python 环境中具有执行权限。

This answer should help you figure out your best setup for the server. 这个答案应该可以帮助您找出服务器的最佳设置。

Also read about Apache VirtualHosts Configuration另请阅读Apache VirtualHosts 配置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM