Introduction
Last October, Zend, the company behind PHP, announced the PHP Collaboration Project, whereby an Enterprise Level framework will be developed called the Zend Framework. A few days ago, on March 3rd, a preview version of the framework has been released, and it contains some very some interesting components.

In this article we’ll have a look at what the framework has to offer, and why you should or should not use it in your PHP scripts. Please note that the Zend Framework requires PHP 5.
What the framework has to offer
The framework comes with several components, which together can handle most of the common PHP tasks. An extensive list can be found on the download page, but here’s a short listing of all the current components:
- Zend_Controller and Zend_View (used for controllers, views)
- Zend_Db (database related)
- Zend_Feed (consumes RSS and Atom feeds)
- Zend_HttpClient (provides a client for the HTTP protocol)
- Zend_InputFilter (used to handle raw input data)
- Zend_Json (converts PHP structures into JSON)
- Zend_Log (logs data)
- Zend_Pdf (create PDF files without the need for extensions)
- Zend_Search_Lucene (adds a site search)
- Zend_Service: Flickr, Yahoo and Amazon (provides tools to query these web services)
- Zend_XmlRpc (a XML-RPC library)
Let’s go through each component, and see what it can do, and how it works.
Zend_Controller and Zend_View
These two components actually form the basis of a simple MVC framework, and consist of a Front Controller which dispatches requests to page controllers. It’s a simple implementation, and Zend is actually working on making it even simpler.
Unfortunately, documentation for these components is virtually non-existent, but it’s fairly easy to read the framework source to learn how it works. Full instructions on how to set it up can be found at http://wiki.cc/php/Zend_Controller.
There is one (major) problem with the MVC framework though. The framework expects your index.php to be in your document root, just like Ruby on Rails. For example, you can’t run your Zend framework from http://localhost/framework/, but instead you must run it from http://localhost. In the linked setup instructions I gave you above you are shown how to setup a separate virtual host for the framework, but this isn’t always possible, especially not on shared hosting.
Maybe this will be fixed in the future, but until then you can find instructions at http://www.akrabat.com/2006/03/04/zend-framework-front-controller/ on how to fix this, although it does make the framework a little less elegant, as it involves writing your own dispatcher.
Let’s have a look at the database component.
Zend framework download page
Zend_Db
The Zend_Db component comes with several different sub-components, used for various things. Let’s begin with the main database API component, called Zend_Db_Adapter, which makes it extremely simple to use any database that supports SQL, like MySQL, Microsoft SQL Server, or others. The following code is used to connect to a MySQL database:
1 2 3 4 5 6 7 8 9
| <?php
require_once 'Zend/Db.php';
$db = Zend_Db::factory('pdo_Mysql', array('host' => '127.0.0.1',
'username' => 'malory',
'password' => '******',
'dbname' => 'camelot'
));
?> |
When connecting to a database you must specify the right adapter, which is pdo_Mysql for MySQL and pdo_Sqlite for a SQLite database.
Zend_Db_Adapter also comes with two quoting functions to prevent SQL injection. The first one, $db->quote(), is pretty much just like the regular mysql_real_escape_string() function, but the second one $db->quoteInto() is much more useful, because it allows you to quote parameters into a string, for example:
1 2 3 4 5 6 7 8 9 10 11
| <?php
// create a $db object, assuming Mysql as the adapter.
// quote a scalar into a WHERE clause
$where = $db->quoteInto('id = ?', 1);
// $where is now 'id = "1"' (note the surrounding quotes)
// quote an array into a WHERE clause
$where = $db->quoteInto('id IN(?)', array(1, 2, 3));
// $where is now 'id IN("1", "2", "3")' (a comma-separated string)
?> |
As you can see in the above example, this allows you to prepare SQL statements with safe parameters.
Another neat piece of functionality is the inbuilt support for transactions. With the Zend_Db_Adapter it’s possible to do transactions by calling the beginTransaction() function, and then either using commit() or rollBack() to save or undo the changes. See the following example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php
// create a $db object, and then start a transaction.
$db->beginTransaction();
// attempt a query.
// if it succeeds, commit the changes;
// if it fails, roll back.
try {
$db->query(...);
$db->commit();
} catch (Exception $e) {
$db->rollBack();
echo $e->getMessage();
}
?> |
The rest of the Zend_Db_Adapter is fairly standard, like update, delete and fetching functions.
Let’s look at the Zend_Db_Select, which makes it really easy to select records. First create the db object:
1 2 3 4 5 6 7 8 9 10 11
| <?php
require_once 'Zend/Db.php';
$params = array (
'host' => '127.0.0.1',
'username' => 'malory',
'password' => '******',
'dbname' => 'camelot'
);
$db = Zend_Db::factory('pdo_Mysql', $params);
?> |
And after that, create the Zend_Db_Select object, by calling the select() function on the db object:
1 2 3 4
| <?php
$select = $db->select();
// $select is now a Zend_Db_Select_PdoMysql object
?> |
The advantage of the Zend_Db_Select object, over a regular SQL query, is that it allows you to use a fluent statement to select records, which is extremely easy to read, and completely prevents SQL injection mistakes. See the below example on how to use the Zend_Db_Select object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php
//
// SELECT *
// FROM round_table
// WHERE noble_title = "Sir"
// ORDER BY first_name
// LIMIT 10 OFFSET 20
//
// you can use an iterative style...
$select->from('round_table', '*');
$select->where('noble_title = ?', 'Sir');
$select->order('first_name');
$select->limit(10,20);
// ...or a "fluent" style:
$select->from('round_table', '*')
->where('noble_title = ?', 'Sir')
->order('first_name')
->limit(10,20);
// regardless, fetch the results
$sql = $select->__toString();
$result = $db->fetchAll($sql);
// alternatively, you can pass the $select object itself;
// Zend_Db_Adapter is smart enough to call __toString() on the
// Zend_Db_Select objects to get the query string.
$result = $db->fetchAll($select);
?> |
As you can see, it makes selecting records really easy, and so much easier. The Zend_Db_Select object supports pretty much everything, except for LEFT, RIGHT JOINs, etc. It only supports regular JOINs.
There are a few more database objects, which automate tasks even more, but to learn more about those have a look at the manual, and you can ignore the Zend_Db_DataObject as it does NOT exist (yet).
Let’s have a look at the Zend_Feed component now.