I have been using PHP
for a while now with my Apache2
web server on my raspberry pi. It works great, but I get tired of always having to think “how do I X in PHP” or “what was the function name for this in PHP”.
I am under the strong impression that there should be something equivalent in which I can replace the <?php ?>
code with python
code, but my search results have been confusing at best.
I am essentially looking for something where I can write whatever python
code I want in an HTML script and have it interpreted and executed and its output inserted into the page when it is requested.
For example, to make a table of users from a list in python
.
<table><tr><td>User list</td></tr> <?python import json library=json.load(open(some_json_file,'r')); for user in library: print "<tr><td>"+user+"</td></tr>" ?> </table>
I’m under the impression that chameleon can do this with its code blocks as described here,(https://chameleon.readthedocs.io/en/latest/reference.html) but as I look deeper, I get the impression it doesn’t work like I am thinking it should. This is the impression I have gotten from all of the template engines I have looked at, as well as WSGI
Are there good drop in python alternatives for PHP? Or are there ways to cleanly wrap semi complex python code into my php in way that doesn’t involve writing an additional python script that is called by PHP? I’ve tried exec()
with python -c
; but this was less than ideal having to escape all the ‘ and ” characters…
Advertisement
Answer
update
The below code works just fine, but can become very slow if run multiple times in a script (takes about 0.4 seconds each time on a raspberry pi3). I have written a program in python that runs in the background and handles requests from php, and runs about 15x faster. I’m now maintaining it here on github.
Original Answer
After messing around I was able to come up with something mostly suitable for what I am trying to do. Inside my php I create a function that executes python scripts.
<?php function py($s){ exec("python -c '$s'",$arr); foreach($arr as $v){ echo $v."n";} } ?>
Then I use php Heredoc
(equivalent to python “”” , means I don’t have to escape every single double quote) to fill the function:
<?php py(<<<python print "Hello world<br>" s="ello world" for x in s: print x+"<br>" python ); ?>
outputs >>>
Hello world e l l o w o r l d
the only real downside I am experiencing at this point is that this method precludes me from using single quotes anywhere in my python script… :(. I’ll get over it.
EDIT
I added a few more tweaks to make this even more useful. The new function is below:
<?php function py($s,$return=false){ $s=str_replace("'","'''",$s); $h=<<<head def cleanup(): for x in globals().keys(): if not x.startswith("_"): del globals()[x] import dill try: dill.load_session("pyworking.pkl") except: pass head; $f=<<<foot import dill dill.dump_session("pyworking.pkl") foot; if ($return==false){ echo shell_exec("python -c '$h$s$f'"); } else { return shell_exec("python -c '$h$s$f'"); } } ?>
this allows you to use single quotes in the script and invoke the py()
function multiple times in the same script and your variables and modules will follow you. At the end of the script you just call the clean up (or using php clear the pyworking.pkl file) and wipe the environment clean.
I also put this function in a file and in my pyp.ini
I used the auto_prepend_file=my/file/location
to automatically include it, so no need to load it before hand.
Overall I am very happy with this method, especially since I can read php variables inside my python script. Passing objects is as simple as:
<?php $data_en=json_encode($data); py(<<<p import json data=$data_en #do something with data p ); ?>
this would be perfect if I could think of a way to assign values to php variables inside the script, but its not a bad workaround if you want a fusion of php and python or just a way to do everything in python without writing a python webserver (which i have also done).