[EDIT]
Use php -r "code" with subprocess.Popen:
def php(code):
p = subprocess.Popen(["php", "-r", code],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out = p.communicate() #returns a tuple (stdoutdata, stderrdata)
if out[1] != b'': raise Exception(out[1].decode('UTF-8'))
return out[0].decode('UTF-8')
code = """ \
$a = ['a', 'b', 'c'][2]; \
echo($a);"""
print(php(code))
[Original Answer]
I found a simple class that allows you to do that.
The code is self-explanatory. The class contains 3 methods:
- get_raw(self, code): Given a code block, invoke the code and return the raw result as a string
- get(self, code): Given a code block that emits json, invoke the code and interpret the result as a Python value.
- get_one(self, code): Given a code block that emits multiple json values (one per line), yield the next value.
The example you wrote would look like this:
php = PHP()
code = """ \
$a = ['a', 'b', 'c'][0]; \
echo($a);"""
print (php.get_raw(code))
You can also add a prefix and postfix to the code with PHP(prefix="",postfix"")
PS.: I modified the original class because popen2 is deprecated. I also made the code compatible with Python 3. You can get it here :
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)
-r --runcommand line flag on php.net/manual/en/features.commandline.options.php