【问题标题】:Why would a python library run from the desktop, but not when called from PHP?为什么 python 库会从桌面运行,但从 PHP 调用时却不行?
【发布时间】:2021-12-24 11:12:37
【问题描述】:

我编写了一个 Web 应用程序,它在某些地方调用 python 代码来检索和存储信息。直到今天我有理由安装 jsonpickle 库时它工作得很好。当 python 代码从 shell 运行时,该库完全符合预期(它将嵌套结构转换为 JSON;这种情况下的数据对于 json.dumps() 来说太复杂了,否则我会使用它)。但是当从 php 调用时,它无法加载。我从未在任何其他库中看到过这种情况。

下面是极其简化的代码:

Python:

#!/usr/bin/env python

import datetime
import jsonpickle

nowS = datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
nowJ = jsonpickle.encode({"now": nowS})
print(nowJ)

无论我打印nowS 还是nowJ,上述操作都很好。

但是,当它从 PHP 调用相同的代码时,它会失败。

<!DOCTYPE html>
<html>
<body>
<?php
   $json = shell_exec('python3 /var/www/py/trivial.py');
   $json = trim($json);
   echo "<p>json: " . addslashes($json) . "</p>";
?>
</body>
</html>

如果我打印nowS 并注释掉所有对jsonpickle 的引用,它就可以工作。 import jsonpickle 行会阻止 PHP 执行此代码,即使以后永远不会调用 jsonpickle。

较早安装的日期时间和其他库不会导致类似问题。

我很困惑。我在这里错过了什么?


附录,11 月 15 日。

以下出色的选择均无效。我放弃并使用sudo pip3而不是pip3安装了jsonpickle库,这似乎已经解决了。

【问题讨论】:

  • 由于 PATH 的不同,PHP 运行的“python3”可能与您在终端中运行的不同。与 datetime 不同,jsonpickle 不是默认的 python 模块 - 它需要与 pip install jsonpickle 一起安装并且在“python 路径”上可用才能被导入。运行 which python3 以获取完整路径,然后在 PHP 中使用该完整路径,例如 shell_exec('/usr/local/bin/python3 /var/www/py/trivial.py')。您还可以将 import jsonpickle 包装在 try 语句中,并在导入失败时打印出调试信息(如 sys.path)。

标签: python php json libraries


【解决方案1】:

更强大的方法是使用虚拟环境。

你可以在 bash 中做到这一点

python3 -m venv /var/www/py/venv
source /var/www/py/venv/bin/activate && pip install jsonpickle

然后在PHP中你可以这样做

$json = shell_exec('source /var/www/py/venv/bin/activate && python3 /var/www/py/trivial.py');

【讨论】:

  • strftime 只是在简单的演示代码中使用。实际数据来自第三方 API,与 json.dumps() 不兼容。而且由于它来自第三方,我无法从源头修改它。
  • 尝试了上述方法;如果import jsonpickle 出现在源代码中,即使从未使用过 jsonpickle,python 也不会运行。没有 jsonpickle,它可以工作。可悲的是。我需要 jsonpickle。
  • 改成虚拟环境的方法,也许对你有用
【解决方案2】:

它必须使用完整路径。像这样:

shell_exec('/usr/bin/python3 /var/www/py/trivial.py');

或者尝试创建一个venv(虚拟环境)并安装所有需要的包。

shell_exec('/var/www/py/venv/bin/python3 /var/www/py/trivial.py');

仅供参考:如果您使用 apache 托管您的 php,您还需要检查用户(例如 www-data)权限。

【讨论】:

  • 与我尝试过的其他方法一样,在import jsonpickle 出现在python 代码的顶部之前,上述方法都可以正常工作。如果它在那里。该代码在 shell 中运行良好,但在 PHP 中失败。
猜你喜欢
  • 2014-11-18
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
相关资源
最近更新 更多