PyPHP the python php bridge
Run your python WSGI web
applications (like QWeb ones) under a php enabled web server without any
setup.
by Antony Lesuisse (Email: al at udev.org) in 2004-2005,
Released in the Public Domain.
Description
PyPHP enables running Python web application using PHP as the interface to the
web server.
Either:
- Your python scripts are run like a php script would be run. (simple mode)
- Your python file define a WSGI conformant app.
With PyPHP you get the best of both Python and PHP world:
- The power, cleanness and robustness of the Python language
- NO config files to edit, like php, just copy files to deploy
- The low level integration of PHP with the web server including:
- HTTP authentification
- Ouput buffering
- header/cookie management
- POST file upload handling
- HTTPS SSL TLS handling
- Session management (using pickle you are able to store your python objects in the PHP sessions)
- Database connection pooling (however we recommand the usage of python db api)
- Access to all the PHP api (even if the python api is in most cases superior)
PyPHP doesn't require any form of installation or configuration !
Just copy the files pyphp.py and pyphp.php to your php-enabled web server
directory and you are ready to run.
Quickstart for the simple mode:
Hello world in pyphp filename must ends with .php and begins with '<?include("pyphp.php");pyphp_run();?>':
<?include("pyphp.php");pyphp_run();?>
print "Hello World"
A global object called "php" allows you to access php objects and functions.
Quickstart for the WSGI mode:
Hello world app the filename must ends with .php and begins with
'<?include("pyphp.php");pyphp_run("wsgiapp");?>', the argument of
pyphp_run() must be the name of the web app.
environ["php"] contains the PHPProxy.
Use that for file uploads, cookies, session etc..
See the examples below demo_wsgi*.
The php object (PHPProxy)
- all the php namespace is acessible from the php object (example: php date() function is is availaible as php.date())
- each time a php function is called, the arguments are serialized from python to
php, and the return value is serialized from php to python.
- the convertion of a php array is a dict in python
- $_GET is availaible as php._GET
- $_POST is availaible as php._POST
- $_SESSION is availaible as php._SESSION
- idem for all $_* global php variables
- php._ARG is the merge of php._GET and
php._POST, it is a python dict with an additional int(key)
method that return the corresponding int() value or 0 if not found.
Useful to handle parameters like database ids.
- use php.exit() to exit your script instead of sys.exit()
All examples:
Example : demo_hello.php
<?include("pyphp.php");pyphp_run();?>
# vim:syntax=python:
print "Hello World"
Example : demo_wsgi1.php
<?include("pyphp.php");pyphp_run("mywsgiapp");?>
# vim:syntax=python:
def mywsgiapp(environ, start_response):
start_response('200 OK', [('Content-type','text/plain')])
# access the php api via environ['php']
ver = environ['php'].phpversion()
return ['Hello world! via (php %s) \n'%ver]
Example : demo_wsgi2.php
<?include("pyphp.php");pyphp_run("test_app");?>
# vim:syntax=python:
import cgi, time
def test_app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
# php proxy
php=environ['php']
# calling a php function
php.header("Content-Type: text/html")
yield '''<html><head><title>Hello World!</title></head>
<body><p>Hello World!</p>
<br/>
<form action="demo_wsgi2.php" method="GET">
<input type="text" name="a" value="test value"/>
<input type="submit" name="s" value="submit"/>
</form>
<br/>
<br/>
'''
# printing from python
print "Hello from python time is ", time.ctime(), "<br><br>"
# access php $_GET array
print "php._GET acessible as python dict:", php._GET ,"<br><br>"
# use a php function
print "php exlode ", php.explode("/","/file/path/example"), "<br><br>"
# use the php function eval()
php.eval("print_r(array());")
# use php sessions
if not "count" in php._SESSION:
php._SESSION["count"]=1
else:
count=php._SESSION["count"]
print "session: count,",count, "<br><br>"
php._SESSION["count"]=count+1
# use php mysql api
print "Try to list mysql users this wont work if root has a mysql password<br><br>"
php.mysql_connect(':/var/run/mysqld/mysqld.sock','root')
php.mysql_select_db('mysql')
q=php.mysql_query('select User from user LIMIT 0,10')
while 1:
r=php.mysql_fetch_assoc(q)
if not r: break
print r, '<br>'
Example : demo_wsgi3.php
<?include("pyphp.php");pyphp_run("testapp");?>
# vim:syntax=python:
from demo_wsgi3_testapp import testapp
Example : demo_wsgi3_testapp.py
#/usr/bin/python
def testapp(environ, start_response):
start_response('200 OK',[('Content-type','text/plain')])
php=environ['php']
if 'PHP_AUTH_USER' not in php._SERVER:
php.header('WWW-Authenticate: Basic realm="My Realm"')
php.header('HTTP/1.0 401 Unauthorized')
print 'Text to send if user hits Cancel button';
php.exit()
else:
print "<p>Hello '%s'.</p>"%(php._SERVER['PHP_AUTH_USER'],)
print "<p>You entered '%s' as your password.</p>"%(php._SERVER['PHP_AUTH_PW'])
return ['done\n']