Some of the information here may be outdated, please check the book instead
[edit]

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...

Introduction

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.

PHP files and web2py views

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

  • both PHP and web2py allow you to put code into HTML
  • In PHP you are forced to put all your application logic and database queries into the same file that contains HTML thus mixing data representation, with workflow with data presentation. In web2py there three components are separated in different folders.
  • In PHP you are forced to put HTML into strings in code (<br/> in the example). In web2py you never need to do that.
  • As in PHP, in web2py you can put any code you want in the .html files but you should really try only to put presentation code in there.
  • In PHP if you echo a string that contains special characters and forget to escape them, you may have a XSS vulnerability. In web2py strings are automatically escaped so no vulnerability.
  • In PHP you always start coding by writing HTML. In web2py that is the last step. You start coding by designing you tables (this gives you a web based database administrative interface for browsing your data). You proceed by creating controllers (in python) which describe which pages will comprise you app, which forms are displayed, and now the user is supposed to navigate the pages. At this point the app is working without you writing any html. You add the html as last step to make sure the pages look as you want them to look.

On workflow, web2py controllers and FORMs

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>
  • Upon accepting the self submitted form, the controller stores the user name in a session variable (n), then index redirects to the 'hello' page. web2py takes care of session, session cookies etc. transparently for you.
  • Moreover in most of the case you do not need to create FORMs since web2py will automatically create forms to insert/update/delete records in the database (for all your table) that you can put in your pages.

The Object Relational Mapper and web2py models

In PHP if you need to access the database you need to:

  • create the table outside PHP
  • insert SQL queries into the HTML via the provided PHP API
  • manage the database using third party tools

In web2py instead:

  • you define your tables in a model, if they do not exist they are created by web2py, if they exist but differ, they are altered
  • you build queries using the ORM which provides an abstraction layer on the database back-end and your code will work seamlessly on sqlite, mysql, postgresql, oracle and (with some limitations) on google big table.
  • web2py creates a database administrative interface for your app that changes dynamically as your tables are altered. You can use this interface to do most of the database maintenance tasks.

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.

Internationalization

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'))
  • In both cases the expression is evaluated lazily when displayed in views.
  • In web2py, the web based administrative interface provides a translation page interface.
  • To create a language file in web2py just type its name (for example it-it.py ) in the admin interface.

What else?

  • 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.

© 2008-2010 by Massimo Di Pierro - All rights reserved - Powered by web2py - design derived from a theme by the earlybird
The content of this book is released under the Artistic License 2.0 - Modified content cannot be reproduced.