From:

An Example Zend Framework Blog Application - Part 3: A Simple Hello World Tutorial

It's almost obligatory when introducing a new programming topic, that the author present the simplest possible example. Usually this means getting a programming language or framework to print "Hello World" to the screen. I'm going to be no different. So much for originality...

Previously: Part 2: The MVC Application Architecture

Step 1: Creating A New Application

Before we jump into programming with the Zend Framework there are a few setup tasks. We need to install the Zend Framework, get a virtual domain running, and have a basic collection of directories and emtpy files created to hold our source code.

You'll need to download the Zend Framework 1.5 (latest minor release) from http://framework.zend.comand put it somewhere on your include path. I try to minimise the number of include paths I end up having so I sometimes pick very odd places (like the PEAR directory which is usually already in the include_path) or another central library location like PEAR where I might have a dozen libraries all congregated.

A common solution found on blogs and articles is to put the framework into a "library" directory within your application directory tree. Ordinarily I don't recommend this unless your application needs a specific version of the Zend Framework - centralising a Zend Framework location for multiple applications to access can make maintenance a bit easier.

I've settled on using a virtual host mainly because it's easy to setup, and it helps avoid some of those annoying base path issues you get in your HTML when using mod_rewrite pretty urls - especially in development where, otherwise, the locahost document root becomes a mass of sub-directories upon sub-directories that end up causing base href issues so easily. Usually I open up the virtual-hosts.conf file from Apache's conf directory and add something like:

NameVirtualHost ∗:80

<VirtualHost ∗:80>
DocumentRoot "/path/to/htdocs"
ServerName localhost
</VirtualHost>

<VirtualHost ∗:80>
ServerName zfblog
DocumentRoot "/path/to/project/trunk/public"
</VirtualHost>


This should result in all HTTP queries for http://zfblog/ reaching the selected document root (which is the public directory for the project containing index.php, located in our subversion's working copy "trunk" directory). We'll create this directory structure a little later. We usually also need to reference localhost to ensure it's recognised as a host correctly - otherwise any localhost addresses you already have will suddenly divert to zfblog's document root myseriously .

For those of you on Windows XP or Vista, you also need to add the new virtual domain to your hosts file (usually at C:\WINNT\system32\drivers\etc\hosts). This is tricky in Vista - you will probably need to alter the file's permissions using an Administrator account to grant the local user additional Modify privileges. Make sure to reverse the privileges after! Edit it to look this:

# Copyright (c) 1993-1999 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.

127.0.0.1 localhost
127.0.0.1 zfblog


Restart your browser and with a little luck the browser will at least give us a directory listing (once you add the document root "public" directory as shown below).

The least exciting part is the creation of a tree of directories to contain our source code. Wil Sinclair over at Zend is working on a Zend_Build component and this will one day hopefully eliminate too much of the repetition in creating these directories and default files. Until then let the monotony ensue (or keep a skeleton setup handy for copy and pasting ).

Here's a snapshot of what the Hello World example looks like in the directory view from Eclipse:



Copy this and create the same directory structure in a new directory called something like "zfblog". Putting it all in "trunk" is optional - I've using subversion here which is why that directory exists. If you haven't used Subversion before I highly recommend it - it's simple to learn and use.

Let's examine each of these directories briefly.

The "application" directory is where we place all the components of an application implementing the Model-View-Controller. Inside "application", "controllers", "models" and "views" represent respective locations of controller, model and view source code and templates. Inside "views" there is a subdivision between "filters", "helpers", "layouts" and "scripts". For now, remember we put all templates rendered by the View inside "scripts". In the screenshot, we see and index directory which will contain an "index.phtml" file, which is the view template for indexAction of an IndexController class. The others we'll meet later.

The "modules" directory is also for controllers, models, and views, but in this case they are catagorised into multiple divisions of an application. If you think about it, an application can be broken into several parts, for example, the main application and an administration part. The administration section could be partitioned into the Admin Module so it's not intermixed with the main application.

A Bootstrap.php file exists in the "application" directory which represents a class called "Bootstrap". It's purpose is to initialise the Zend Framework, adjust environment settings (for example, timezone and error_reporting level), and otherwise make application specific tweaks and additions before a HTTP request is processed. Most tutorials take an alternative view and put Bootstrap code into index.php. I strongly suggest you avoid this and use an actual class to organise the Bootstrap code - it makes it a lot easier to read if nothing else!

The "config" directory simply holds the configuration data for the application, for example, database connection details.

The "library" directory can hold a copy of the Zend Framework. Generally I avoid this since it's fairly easy to just add the Zend Framework to the PHP include_path, but it's still very useful if you want to change Zend Framework versions in use more flexibly. It's also simple to manage if you use it to add an svn::external reference to the Zend Framework subversion repository.

The "public" directory holds all public files accessible by a request to the web server. This includes an index.php file, which handles all application requests by calling on the Bootstrap class, as well as any CSS, HTML, Javascript files, etc.

A note on deployment practice: generally when deploying you'd want to move the "public" directory to your web server to be internet accessible, but keep the non-public directories somewhere below the web root. Since the public index.php ends up only making a simple reference to the Bootstrap file served by including it, this means most of the application files will not be accessible by internet users. It also means that the index.php file will end up deciding where the Bootstrap file is located - so it's the one public file that always needs to be edited by hand for deployment to change that location as needed.

The "tests" directory usually holds any application specific unit, integration and acceptance tests. As I noted previously I'm deliberately taking a test-light approach to stay on topic (I have more than one testing/development article on Zend Devzone if interested in applying TDD or BDD). Main tests I expect to have are for application specific classes: any Model logic for example.

At the end of this step you should have the directory structure in place containing some empty files as follows (create them now, and we'll fill them in later):

/application/Bootstrap.php
/application/controller/IndexController.php
/application/views/scripts/index/index.phtml
/public/index.php
/public/.htaccess


Step 2: Implementing Our Bootstrap File

Bootstrapping is when we setup the initial environment, configuration and Zend Framework initialisation for our application. It's not a difficult file to write, but it can grow ever larger and complex as your application gains features. To manage this I strongly suggest implementing it as a class with bitesize methods. Breaking it up does wonders for your sanity. For our Hello World skeleton application, /application/Boostrap.phpcontains:

<?php

require_once 'Zend/Loader.php';

classBootstrap
{

public static $frontController= null;

public static functionrun ()
{
self:: setupEnvironment();
self:: prepare();
$response= self:: $frontController->dispatch();
self:: sendResponse($response);
}

public static functionsetupEnvironment ()
{
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', true);
date_default_timezone_set ('Europe/London');
}

public static functionprepare ()
{
self:: setupFrontController();
self:: setupView();
}

public static functionsetupFrontController ()
{
Zend_Loader:: registerAutoload();
self:: $frontController= Zend_Controller_Front:: getInstance();
self:: $frontController->throwExceptions(true);
self:: $frontController->returnResponse(true);
self:: $frontController->setControllerDirectory(
dirname(<u>_FILE_</u>). '/controllers'
);
}

public static functionsetupView ()
{
$view= newZend_View;
$view->setEncoding('UTF-8');
$viewRenderer= newZend_Controller_Action_Helper_ViewRenderer ($view);
Zend_Controller_Action_HelperBroker:: addHelper($viewRenderer);
}

public static functionsendResponse (Zend_Controller_Response_Http $response)
{
$response->setHeader('Content-Type', 'text/html; charset=UTF-8', true);
$response->sendResponse();
}

}


Note: Due to some Serendipity bug in processing Geshi output, underline tags replace some underline characters such as for the PHP FILE constant which should have two underscrores proceeding and following "FILE". Sorry about that - S9Y has it's moments.

The Bootstrap class has two main methods here: run() and prepare(). run() executes a full application request, whereas prepare() only sets up (but doesn't execute) the Front Controller. For now let's focus on run() and all the steps our Bootstrap takes when it's called. The prepare() method is something I use when applying TDD or BDD to developing controllers, since I then delegate controller execution to the testing framework.

The first thing is to setup the local environment. So here we've set a timezone (as required by PHP5), enabled PHP's display_errors option, and set a fairly stiff error reporting level. If putting these basics into a class seems counter intuitive, you can simply extract them to the file head. Because I usually test extensively, I usually don't want these running during my tests and interfering with test results.

Secondly we prepare the Front Controller. Zend_Controller_Front is an implementation of the Front Controller Design Pattern, which acts as a single point of entry into a Model-View-Controller architected application. I kid you not - every request which is not for an existing public file will go through it. In our case, since the Bootstrap is included into, and called by public/index.php, "index.php" is our single point of entry.

Here, the prepare() stage involves setting up the Front Controller:
- get an instance of Zend_Controller_Front
- set it to throw all Exceptions (might want to disable this in production)
- set it to return a Response object when dispatched
- tell it where to find the default controllers

The last step of prepare() makes some changes to the View. The reason I've done this is to show how to make an extremely common change - adding support for UTF-8 encoded output (such as my name!). Don't worry too much about the details now - the ViewRenderer Action Helper and the Helper Broker lets one add or modify Action Helpers and is well covered by Matthew Weier O'Phinney over on Zend Devzone - http://devzone.zend.com/article/3350-Action-Helpers-in-Zend-Framework.

Now, what about /public/index.php?

<?php

// Update after deployment for location of non-public files
$root= dirname(dirname(<u>_FILE_</u>));

// We're assuming the Zend Framework is already on the include_path
set_include_path(
$root. '/application'. PATH_SEPARATOR
. $root. '/library'. PATH_SEPARATOR
. get_include_path()
);

require_once 'Bootstrap.php';

Bootstrap::run();


Simplicity itself! The index is our Front Controller's single point of entry into a Zend Framework application, and all it needs to do is determine a valid include_path for the application and then delegate all other tasks to the Bootstrap class's run() method.

The final step is how to make all requests to "http://zfblog/" pass through index.php. This is solved for Apache web servers using it's Rewrite Module, which simply takes an incoming request URL, and rewrites it so it points to index.php. If you've never used Apache Rewrite before, you probably need to enable this module in http.conf before this works. Rewrite rules can be defined in Apache's http.conf file, or simply via a .htaccess file in "public" containing the rules:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .∗ index.php


The .htaccess file here first turns on Rewriting, and then specifies rules. The rules here map all requests to index.php, unless they relate to a file which exists on the server (i.e. it won't rewrite URLs to CSS, Javascript or image files).

Step 4: Implementing The Index Controller

Before we continue, a quick word on controller/view wiring. Some time back it was decided to make automated rendering the default mode of operation for the Zend Framework. This means Controller will rarely need manual intervention to render a View - instead an Action Helper called the ViewRenderer (which should sound familiar since it used it to add UTF-8 encoding in our Bootstrap!) is called upon. This helper locates a View matching the name of the current Controller and Action and automatically renders it. There are ways to disable this automated rendering as documented in the manual - which is often useful when you want to bypass Zend_View (e.g. maybe you're outputting finalised JSON or XML and no further templating or processing is needed).

If a URL to a Zend Framework application does not contain a controller or action reference, then the Zend Framework uses the default "index" value. Since we only intend requesting to the root URL of "http://zfblog/", we'll need an Index Controller containing an Index Action. Let's create one!

Add a file called "IndexController.php" in application/controllerscontaining:

<?php

classIndexController extends Zend_Controller_Action
{

public functionindexAction ()
{
$this->view->title= 'Hello, World!';
}

}


All controllers must extend Zend_Controller_Action, since it contains all later referenced internal methods and properties common to all Controllers. If you need to tweak the basic Controller to add new methods or properties you may do so using a subclass of Zend_Controller_Action and then making all application Controllers extend this subclass instead. Be very careful however in subclassing this way - it's useful for adding new properties to the class, but additional methods are often better added as discrete Action Helpers.

Our new Action method ignores rendering; it's done automatically as discussed earlier. All we need to do is set View data we need. You can add almost anything to a View, since it just becomes a property in a View template. So feel free to add Objects and Arrays. If using Smarty or PHPTAL, this might be different.

Above we've told the View that templates might refer to a variable "title" and given it a value of "Hello, World!". Once the Action method is done, the ViewRenderer will kick in and try to render a template located at "/path/to/application/views/scripts/index/index.phtml".

And what use is a Controller, without a View to display?

Step 5: Implementing The View For IndexController::indexAction()

By default, the Zend Framework or more specifically the ViewRenderer Action Helper, will attempt to render a View template for all Controller Actions using a simple convention. For example, the template for IndexController::indexAction() should be located at "/index/index.phtml" within the "scripts" subdirectory of "views".

The Zend_View component is responsible for rendering all View template, often with a little assistance (e.g. ViewRenderer or Zend_Layout) from the Controller. A Zend_View template is HTML (or some other output type) interspersed with PHP and it doesn't use a separate tag language such as what the Smarty template engine, for example, uses. Here's something to put into your index.phtml file for our first Zend Framework application:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xml:lang= "en"lang= "en">
<head>
<meta http-equiv= "Content-Type"content= "text/html; charset=utf-8"/>
<meta name= "language"content= "en"/>
<title><?php echo $this->escape($this->title)?></title>
</head>
<body>
<p>Hello, World!</p>
</body>
</html>


As you can see, it's almost pure HTML with a single PHP inclusion for the title text (which we set from our indexAction() method earlier!). To ensure security against Cross Site Scripting (XSS) we should escape all output from within the application, and Zend_View uses the PHP htmlspecialchars() function from it's Zend_View::escape() method. Another noteworthy mention is that, since we setup our View to use UTF-8 encoding, this encoding is also passed into htmlspecialchars().

If using escape() everywhere sounds bad - well, it is, and it isn't. It's a pain since it's something that would obviously benefit from automation - so not applying escaping is the exception by default. On the other hand it must be done at all times so if you ever see a variable being echoed that's not surrounded by the escape() method you should proceed with care.

Step 6: Did it work?

Go ahead and open up your browser. The base url of http://zfblog/ should now do it's thing and return a HTML document containing "Hello, World!".

Conclusion

Getting a simple example up and running has already provided a few insights. But don't let your guard down just yet. Like any battle plan, it will not survive first contact with the enemy (Maugrim's Marvellous Blog is so evil ). As we proceed, there will more than likely be a few flaws to the simple approach, our Bootstrap will need to expand yet remain maintainable, and we haven't even looked at Zend_Db yet!

It's a start. If you're lucky, it may be many starts since you can reuse a similar basic skeleton to skip all those setup tasks for other Zend Framework projects.

Note: The source code for this entry is available to browse, or checkout with subversion, from http://svn.astrumfutura.org/zfblog/tags/Part3. The full source code for the entire application (as it exists thus far) from http://svn.astrumfutura.org/zfblog.

Continue to: Part 4: Setting the Design Stage with Blueprint CSS Framework and Zend_Layout

Related Articles

Relatd Projects

JSJaC

JSJaC is a jabber/XMPP client library written in JavaScript to ease implementation of web based jabber/XMPP clients. For communication with a jabber server it needs to support either HTTP Pollingor XMPP Over BOSH(formerly known as HTTP Binding). JSJaC has an object oriented design which should be quite easy to use. Communication is done by using the XML HTTP Request objectalso refered to as AJAX technology. Your browser must support this.

XSTM

What is XSTM?


XSTM
is a n open sourcelibrary which enables high performance object replication between processes. It is an object oriented Distributed Shared Memory, or a Distributed Object Cache.

XSTMhas similarities with technologies like Adobe Flex Data Services , JBoss Cache, Terracotta, Tangosol Coherence , ScaleOut , or IBM's ObjectGrid .

Our model is based on object shares, which work like file shares. When an object is added to a share, it appears on the other machines which have the same share opened. Modifications done to the fields of the object are from this point replicated between machines.

Read more in the project overview.


XSTMis made of three projects. The Java implementation is called JSTMand is the base from which the other versions are derived. An adapted version made with Luciano, the author of GWM , is available for GWT . It allowsthis library to be used in a browser. NSTM is a .NET port based on IKVM.

All implementations are compatible with each other so object replication can take place e.g. between a Java server and a .NET Smart Client.

GWT(Google Web Toolkit)

Google Web Toolkit (GWT) is an open source Java software development framework that makes writing AJAX applications like Google Mapsand Gmaileasy for developers who don't speak browser quirks as a second language. Writing dynamic web applications today is a tedious and error-prone process; you spend 90% of your time working around subtle incompatibilities between web browsers and platforms, and JavaScript's lack of modularity makes sharing, testing, and reusing AJAX components difficult and fragile.

GWT lets you avoid many of these headaches while offering your users the same dynamic, standards-compliant experience. You write your front end in the Javaprogramming language, and the GWT compiler converts your Java classes to browser-compliant JavaScript and HTML.

Facebook API

This JavaScript client library allows you to make Facebook API calls from any web site and makes it easy to create Ajax Facebook applications. Since the library does not require any server-side code on your server, you can now create a Facebook application that can be hosted on any web site that serves static HTML. An application that uses this client library should be registered as an iframe type. This applies to either iframe Facebook apps that users access through the Facebook web site or apps that users access directly on the app’s own web sites. Almost all Facebook APIs are supported.

Highslide JS
Highslide JS is an open source JavaScript software, offering a Web 2.0 approach to popup windows. It streamlines the use of thumbnail images and HTML popups on web pages. The library offers these features and advantages:
  • No plugins like Flash or Java required.
  • Popup blockers are no problem. The content expands within the active browser window.
  • Single click. After opening the image or HTML popup, the user can scroll further down or leave the page without closing it.
  • Compatibility and safe fallback. If the user has disabled JavaScript or is using an old browser, the browser redirects directly to the image itself or to a fallback HTML page.
newjs

A simple command-line tool to create the folders and helper files for a new JavaScript project/library. As a bonus, you can quickly create a website to promote your project.

When you start a new JavaScript library, how do you layout the source files, the tests, the distribution files? Do you have support scripts to generate distributions from source files? Run your JavaScript unit tests? Generators to create new unit test HTMLfiles?

AJAXInterceptor
Project Description
Just by adding this small JavaScript module to the end of your web pages, you get your form's submissions intercepted and, instead of sending request to the server in the usual way, they are done asynchronously and in an AJAX-style smooth way.

As long as it is a client-side library it will work with any server technology: ASP.NET, PHP, JSP, Classic ASP... and even with local HTM files.

I've included extensibility so that you can add easily your own progress indicators (several included) and show error messages the way you prefer (by default it shows an alert).

It's transparent to your server code and could be used to add AJAX capabilities to some applications without writting a single line of code.

Documentation is included.



Features summary

• No-code AJAXification of web apps
• Supports any server technology, including ASP.NET, JSP, PHP, ASP 3.0...
• In ASP.NET it supports all kinds of postbacks: direct and by code.
• Works in any modern browser that supports AJAX.
• Supports cross-posting of forms, that is, you can send the information to any web page in the same domain. If all your web pages have AJAXInterceptor included (for example, you include it in your master page or template) you can hace
• Respects your custom onsumit event handlers.
• Supports browser history so that your users can hit the previous button and get the last rendered page.
• Two versions of the module:
- AJAXInterceptor.js: full commented one. Useful for debugging purposes.
- AJAXINterceptor_r.js: reduced-size version. It downloads faster as it only is 2.6 kB in size. It's better to use this on production apps.
• Automatically show/hide custom progress indicators.
• Support for cancelling operations.
• Support for custom message displaying.
• Supports any form in your page

Obviously this is not substitute at all of full-fledged APIs like Microsoft's ASP.NET AJAX, PHPLiveX or AJAX.NET, but will let you add AJAX support to your apps in a few seconds and without writing any code. Just give it a try!

In the ZIP you will find teh module, a working sample with ASP.NET and a PDF with the help documentation.

This project is just for fun :-)

I will be very glad if you drop me a line in case you use AJAXInterceptor in any real-world application or if you enhance it with new features.

Visit my .NET blog (Spanish) at http://www.jasoft.organd my e-mail marketing blog (English) at http://www.theemailingexperience.com
script.aculo.us
script.aculo.us provides you with easy-to-use, cross-browser user interface JavaScript libraries to make your web sites and web applications fly.
google caja

Using Caja, web apps can safely allow scripts in third party content.
The computer industry has only one significant success enabling documents to carry active content safely: scripts in web pages. Normal users regularly browse untrusted sites with Javascript turned on. Modulo browser bugs and phishing, they mostly remain safe. But even though web apps build on this success, they fail to provide its power. Web apps generally remove scripts from third party content, reducing content to passive data. Examples include webmail, groups, blogs, chat, docs and spreadsheets, wikis, and more.
Were scripts in an object-capability language, web apps could provide active content safely, simply, and flexibly. Surprisingly, this is possible within existing web standards. Caja represents our discovery that a subset of Javascript is an object-capability language

YUI
The Yahoo! User Interface (YUI) Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX. The YUI Library also includes several core CSS resources. All components in the YUI Library have been released as open source under a BSD license and are free for all uses.