It is hard to compare PHP to a framework like web2py and it would be more fair to compare a PHP based framework (like CakePHP) to web2py. Anyway this is not meant as a comparison. We are just trying to explain web2py to PHP programmers...
In PHP an HTTP request for "/test.php" is mapped into the corresponding file, the file is executed and the output is returned as a web page.
In web2py an HTTP request for "/app/c/f" is mapped into a call to the function f() in file (controller) c.py in the application "app". The file c.py is written in Python. The output of the function f() can be a string (in this case it is returned), or a set of variables (implemented as a python dictionary). In the latter case the variables are rendered into HTML by a file c/f.html, called a view. There is a third type of file called models where one describes database connection, tables and queries in a way independent on the type of database used. File types are identified by the folders: models/ controllers/ views/
This file hierarchy is more complex than the PHP one but, it is a small price to pay to keep your files more organized and readable and your apps will be much easier to maintain.
Views are very similar to PHP files. For example the following PHP code
<html><body>
<?php
for ($i=0; $i<5; $i++) {
echo "Hello World!<br/>";
}
?>
</body></html>
Could be served by a dummy controller function like
def index(): return dict()
and an associated view file index.html that contains
<html><body>
{{for i in range(5):}}
{{='hello world'}}<br/>
{{pass}}
</body><html>
Notice that
In PHP you create one page for displaying a form and a separate page for processing the form. In web2py you'd never do that. Forms are objects (local variables in a controller functions) that know how to process themselves, serialize in html, validate input variables, generate error messages and eventually redirect the use to a different page. Example
def index():
form=SQLFORM.factory(Field('name',requires=IS_NOT_EMPTY()))
if form.accepts(request.vars):
session.name=form.vars.name
redirect('hello')
return dict(form=form)
def hello():
return dict(name=session.name)
and in the view index.html
<html><body>
What is your name? {{=form}}
</body></html>
and in the view hello.html
<html><body>
<h1>Hello {{=name}}</h1>
</body></html>
In PHP if you need to access the database you need to:
In web2py instead:
For example if you create a model file called db.py
db=DAL('sqlite://test.db')
db.define_table('shout',Field('message',requires=IS_NOT_EMPTY()))
web2py creates the sqlite database and creates a table called shouts with a char() field called message (and a hidden auto increment field called id).
Then you can create a controller, for example:
def index():
form=crud.create(db.shout)
rows=db().select(db.shout.ALL)
return dict(form=form,rows=rows)
This complete code make a page that shows the form, does not allow empty submissions, and lists all previous posted messages. The function accepts, builds the form, validates the input, on error changes the form by including error messages, and on accept inserts the record in the db. The function db().select(...) selects records from the database.
Notice that the above code works without a view but we can create a view index.html
{{extend 'layout.html'}}
<h1>Post a new message</h1>
{{=form}}
<h1>Previous messages</h1>
{{for row in rows:}}
<i>{{=row.message}}</i><br/>
{{pass}}
The <html>...</html>
is missing because we choose to extend the standard web2py layout.html.
The developer can easily create layouts and apply them to all pages by extending them. In this way all pages are guaranteed to have similar look and feel.
In web2py:
T('this is a message')
(and as usual no need to import anything since you are supposed to use T)
You can also do
T('this is message %(name)s',dict(name='xxx'))
it-it.py
) in the admin interface.web2py provides a web based administrative interface (not to be confused with the database administrative interface discussed above) that allows you to edit all your files, do various maintenance tasks, bytecode compile apps, and package apps for distribution. Locally or remotely.
If you introduce a bug in your app, soon or later it will manifest itself as an exception been raised. In this case web2py issues a ticket to the visitor and logs the exception, the traceback and the code that caused it. You can browse these tickets via the web based administrative interface.
web2py comes with its own SSL enabled web server but it also works with apache (mod_proxy
, mod_rewrite
, and mod_wsgi
), lighttpd (with fastcgi), andy any server supporting CGI, FastCGI or WSGI.
web2py includes libraries for AJAX, JSON, REST, RSS, ATOM, RTF, CSV, WIKI (markdown) and some more protocols.
web2py has helpers that (like FORM and INPUT above) help you build objects that can be serialized in HTML or XML. Any correct HTML/XML can be generated using exclusively helpers.
web2py code runs on the Google App Engine.
web2py packages everything you need in one binary file that you don't even need to install. I keep mine on a USB stick. You just click on it and it start web server, the sqlite database, fires the browser for access to the administrative interface.
web2py deals with static files for you, streams them when they are large (both in upload and download), and automatically supports IF_MODIFIED_SINCE
and PARTIAL CONTENT
. You can do streaming audio and video without any extra tools or settings.
web2py can map URLs using regular expressions so that you can use it to handle legacy URLs.
web2py has no configuration files. You just create an empty app via the shell or the web based admin interface and create/edit your models, controllers and views (using an editor or the web based admin interface).
There is a repository of free web2py apps here and an interactive FAQ there.