如何从Python运行php代码字符串?

如何从Python运行php代码字符串?,php,python,Php,Python,我发现您可以使用以下方法从Python运行php文件: import subprocess proc = subprocess.Popen('php.exe input.php', shell=True, stdout=subprocess.PIPE) response = proc.stdout.read().decode("utf-8") print(response) 但是有没有一种方法可以从字符串而不是文件中运行php代码?例如: <?php $a = ['a', 'b',

我发现您可以使用以下方法从Python运行php文件:

import subprocess

proc = subprocess.Popen('php.exe input.php', shell=True, stdout=subprocess.PIPE)
response = proc.stdout.read().decode("utf-8")
print(response)
但是有没有一种方法可以从字符串而不是文件中运行php代码?例如:

<?php
  $a = ['a', 'b', 'c'][0];
  echo($a);
?>

[编辑]

对subprocess.Popen使用
php-r“code”

[原答覆]

我找到了一个可以让你这么做的方法。
代码是不言自明的。该类包含3个方法:

  • get_raw(self,code):给定一个代码块,调用代码并以字符串形式返回原始结果
  • get(self,code):给定一个发出json的代码块,调用代码并将结果解释为Python值
  • get_one(self,code):给定一个发出多个json值(每行一个)的代码块,生成下一个值
您编写的示例如下所示:

php = PHP()
code = """ \
  $a = ['a', 'b', 'c'][0]; \
  echo($a);"""
print (php.get_raw(code))
您还可以使用
PHP(prefix=”,postfix“”)为代码添加前缀和后缀。

注:我修改了原来的类,因为popen2不推荐使用。我还使代码与Python 3兼容。你可以:


根据Victor Val的回答,这里是我自己的精简版

import subprocess

def run(code):
    p = subprocess.Popen(['php','-r',code], stdout=subprocess.PIPE)
    return p.stdout.read().decode('utf-8')

code = """ \
  $a = ['a', 'b', 'c'][0]; \
  echo($a);"""
print(run(code))

对PHP可以从stdin运行代码。您能演示一下吗?请查看上的
-r--run
命令行标志,非常感谢您的回答。然而,我发现了两个问题,但都不严重。如果包含
close\u fds=True
,我会得到错误
ValueError:close\u fds在Windows平台上不受支持,如果您重定向stdin/stdout/stderr
,但如果将其删除,它将正常运行。然后我仍然在开始时使用
b
以字节为单位获得输出。所以我只是在print语句中添加了
.decode(“utf-8”)
,就像我的第一个示例一样。如果您对答案进行这些更改,将更有帮助。此外,本例中不需要函数
get
get_one
,因此为了简洁起见,可以删除这些函数。请注意:“请注意,在Windows上,您不能将close_fds设置为true,也不能通过设置stdin、stdout或stderr重定向标准句柄。”我意识到它对我有用,因为我正在使用:“在版本3.7中更改:现在可以在重定向标准句柄时将close_fds设置为True”使用close_fds有什么好处吗?我认为最好省去close_fds,让子进程根据您的操作系统和python版本来决定什么是最好的。另外,在阅读文档时,我可以注意到它建议使用shell=False以避免代码注入,并在使用stdout=PIPE时使用communicate()方法而不是read()。如果您不需要发送流式输入,也不需要stdin。我编辑了我的帖子,加入了一个更简单的版本。不过,我添加了异常处理,这在communicate()中变得更容易了
import json
import subprocess

class PHP:
    """This class provides a stupid simple interface to PHP code."""

    def __init__(self, prefix="", postfix=""):
        """prefix = optional prefix for all code (usually require statements)
        postfix = optional postfix for all code
        Semicolons are not added automatically, so you'll need to make sure to put them in!"""
        self.prefix = prefix
        self.postfix = postfix

    def __submit(self, code):
        code = self.prefix + code + self.postfix
        p = subprocess.Popen(["php","-r",code], shell=True,
                  stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        (child_stdin, child_stdout) = (p.stdin, p.stdout)
        return child_stdout

    def get_raw(self, code):
        """Given a code block, invoke the code and return the raw result as a string."""
        out = self.__submit(code)
        return out.read()

    def get(self, code):
        """Given a code block that emits json, invoke the code and interpret the result as a Python value."""
        out = self.__submit(code)
        return json.loads(out.read())

    def get_one(self, code):
        """Given a code block that emits multiple json values (one per line), yield the next value."""
        out = self.__submit(code)
        for line in out:
            line = line.strip()
            if line:
                yield json.loads(line)
import subprocess

def run(code):
    p = subprocess.Popen(['php','-r',code], stdout=subprocess.PIPE)
    return p.stdout.read().decode('utf-8')

code = """ \
  $a = ['a', 'b', 'c'][0]; \
  echo($a);"""
print(run(code))