Getting started with Zend Framework
So you are about to download the Zend Framework and create your first Zend project? If that is the case continue reading – I am going to describe step by step installation and creation of your first application in the Zend Framework.
First, you will need to download the framework from the official website. Go here to download the latest Zend Framework release. Personally, I prefer a minimal package because I rarely use anything that’s not covered in it.
Second, you will need some AMP (Apache MySQL PHP) software package to test your applications offline on your computer before uploading them to the Web. Here are my two favorites:
Of course, there are other AMP packages for you Mac or Linux users
After you install an AMP package of your choice you have everything you need to get started with the Zend Framework.
Installation
Create a folder in your document root. Name it for example MyZendProject – all your project’s files will be stored there.
Create the following directory structure under the MyZendProject:
MyZendProject
application
config
application.ini
layouts
scripts
default.phtml
modules
default
controllers
ErrorController.php
IndexController.php
forms
models
views
helpers
scripts
error
error.phtml
index
index.phtml
bootstrap.php
library
My
Controller
Action
Helper
Decorator
View
Helper
Zend
public
css
fonts
arial.ttf
images
captcha
js
.htaccess
index.php
The above directory structure is what I use but you are free to customize it to your needs. I always use the modular structure even when I’m just coding a simple application. The reason being an easier future extension of the application.
There are three files already. Important ones for now: bootstrap.php, .htaccess, index.php. I will describe these just few paragraphs bellow.
Now unpack the downloaded Zend Framework and copy the content of the Zend folder to the MyZendProject/library/Zend.
Finally, change your document root to the MyZendProject/public (the main Apache configuration file is usually called httpd.conf). That’s it – you have just successfully installed the Zend Framework!
Configuration
As promised, let’s take a look at three abovementioned files.
First, MyZendProject/public/.htaccess. The Zend Framework utilizes the MVC (Model View Controller) design pattern which means a default URI looks like this:
http://myzendproject.com/controller/action/parameter1/value1/parameter2/value2
To achieve this, the Apache mod_rewrite module is used. Open the .htaccess file an fill in:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
#php_flag magic_quotes_gpc off
The last line turns off the dreadful magic quotes feature in PHP. Not all web hosting providers allow this directive to be used in .htaccess that’s why I commented the line.
It would be useful to know a little bit about the MVC design pattern before continuing.
MVC is a design pattern used to separate the businnes logic and the presentation which brings many benefits such as a much much easier future maintainance and less copying and pasting of similar code across the application. MVC stands for Model View Controller:
- Model represents an information (a data) and operations you can use with it (retrieving, updating etc). The data can be stored in various ways but in the web development databases are the most often used data access layer. Therefor, each model represents a single database table and its available operations in the Zend Framework.
- View represents an user interface of a website or to put it bluntly each view equals to a single website page.
- Controller contains all business logic and is the most important part of any Zend application. In controllers, you define actions that will take place after some user interaction. Quite often you will create instances of models and work with them (retrieve, update the data etc).
For a better and more detailed explanation take a look at the Wikipedia MVC page.
Second, MyZendProject/public/index.php. Because your document root is set to MyZendProject/public the index.php file will be the one to get interpreted by the PHP. The important thing bellow is to set the include path to the MyZendProject/library directory as all Zend files are there (plus you will probably place all other libraries there). Next, the bootstrap.php file is included and the front controller instance dispatched:
-
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application/'));
-
-
// Set the include path
-
set_include_path(APPLICATION_PATH
-
. '/../library'
-
. PATH_SEPARATOR
-
. get_include_path());
-
-
try {
-
include '../application/bootstrap.php';
-
} catch (Exception $exception) {
-
echo $exception->getMessage();
-
exit(1);
-
}
-
-
Zend_Controller_Front::getInstance()->dispatch();
Third, MyZendProject/application/bootstrap.php. Right at the beginning set error_reporting to E_ALL (helps catch potential problems early), start a session and define an __autoload() function. Zend_Loader is the usual way to load Zend classes dynamically but I have found the __autoload() function to be much faster:
-
error_reporting(E_ALL); // goes away in a production
-
Zend_Session::start();
-
function __autoload($class) {
-
include str_replace('_', '/', $class) . '.php';
-
}
Double-check that APPLICATION_PATH and APPLICATION_ENVIRONMENT constants have been created:
-
defined('APPLICATION_PATH')
-
or define('APPLICATION_PATH', dirname(__FILE__));
-
defined('APPLICATION_ENVIRONMENT')
-
or define('APPLICATION_ENVIRONMENT', 'development');
Now the important part. Create an instance of the Zend_Controller_Front and set the modules directory and the environment:
-
$frontController = Zend_Controller_Front::getInstance();
-
$frontController->addModuleDirectory(APPLICATION_PATH . '/modules');
-
$frontController->setParam('env', APPLICATION_ENVIRONMENT);
The following line is optional, it adds a new controller action helpers path so you can store your helpers outside the Zend library directory.
-
Zend_Controller_Action_HelperBroker::addPath('My/Controller/Action/Helper',
-
'My_Controller_Action_Helper');
Let’s set a path to the layout scripts:
-
Zend_Layout::startMvc(APPLICATION_PATH . '/layouts/scripts');
Another important thing. Create an isntance of the view object and configure it (default doctype, charset and language):
-
$view = Zend_Layout::getMvcInstance()->getView();
-
$view->doctype('XHTML1_STRICT');
-
$view->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8');
-
$view->headMeta()->appendHttpEquiv('Content-Language', 'en-US');
One more optional line, this one adds a new view helpers path similar to the controller action helpers path above:
-
$view->addHelperPath('My/View/Helper', 'My_View_Helper');
Those were essentials, now few more useful lines at the end of the bootstrap.php file. First line unsets variables used above to free some memory and then there is a snippet to make sure the magic quotes are taken care of even in case they are still enabled on your server:
-
unset($frontController, $view);
-
-
// Get rid of magic quotes
-
if (get_magic_quotes_gpc()) {
-
function stripslashes_deep($value) {
-
$value = is_array($value) ?
-
array_map('stripslashes_deep', $value) :
-
stripslashes($value);
-
return $value;
-
}
-
-
$_POST = array_map('stripslashes_deep', $_POST);
-
$_GET = array_map('stripslashes_deep', $_GET);
-
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
-
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
-
}
Here is the bootsrap file in its entirety:
-
error_reporting(E_ALL); // goes away in a production
-
Zend_Session::start();
-
function __autoload($class) {
-
include str_replace('_', '/', $class) . '.php';
-
}
-
-
defined('APPLICATION_PATH')
-
or define('APPLICATION_PATH', dirname(__FILE__));
-
defined('APPLICATION_ENVIRONMENT')
-
or define('APPLICATION_ENVIRONMENT', 'development');
-
-
$frontController = Zend_Controller_Front::getInstance();
-
$frontController->addModuleDirectory(APPLICATION_PATH . '/modules');
-
$frontController->setParam('env', APPLICATION_ENVIRONMENT);
-
Zend_Controller_Action_HelperBroker::addPath('My/Controller/Action/Helper',
-
'My_Controller_Action_Helper');
-
-
Zend_Layout::startMvc(APPLICATION_PATH . '/layouts/scripts');
-
$view = Zend_Layout::getMvcInstance()->getView();
-
$view->doctype('XHTML1_STRICT');
-
$view->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8');
-
$view->headMeta()->appendHttpEquiv('Content-Language', 'en-US');
-
$view->addHelperPath('My/View/Helper', 'My_View_Helper');
-
-
unset($frontController, $view);
-
-
// Get rid of magic quotes
-
if (get_magic_quotes_gpc()) {
-
function stripslashes_deep($value) {
-
$value = is_array($value) ?
-
array_map('stripslashes_deep', $value) :
-
stripslashes($value);
-
return $value;
-
}
-
-
$_POST = array_map('stripslashes_deep', $_POST);
-
$_GET = array_map('stripslashes_deep', $_GET);
-
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
-
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
-
}
Creating your first project
There are three simple things you need to do to create your first Zend application:
- Create an XHTML layout.
- Create a controller.
- Create a view script (template).
Open the MyZendProject/application/layouts/script/default.phtml file – this will be the default layout for your website pages. The contents of the layout file might for example look like this:
-
<?php echo $this->doctype(); ?>
-
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-
<head>
-
-
<?php echo $this->headTitle(); ?>
-
-
<?php echo $this->headMeta(); ?>
-
-
<?php echo $this->headLink(); ?>
-
-
<?php echo $this->headScript(); ?>
-
-
-
</head>
-
<body>
-
-
<?php echo $this->layout()->content; ?>
-
-
<?php echo $this->inlineScript(); ?>
-
-
-
</body>
-
</html>
The most important line:
-
<?php echo $this->layout()->content; ?>
This is where the content from your page templates will be inserted. There are few other view helpers:
- $this->doctype()
- $this->headTitle()
- $this->headMeta()
- $this->headLink()
- $this->headScript()
- $this->inlineScript()
Their names are descriptive so I don’t think there is a need for explanation. Notice that inline JavaScript is placed almost at the end of the layout behind all body content. Otherwise it could negatively affect the loading time. As you have probably already guessed, you can change the output of these view helpers in controllers. Let’s create your first one.
Open the MyZendProject/application/modules/default/controllers/IndexController.php file. Controllers in Zend applications extend Zend_Controller_Action and contain methods each of which represents a single action. Write the following:
-
class IndexController extends Zend_Controller_Action
-
{
-
public function indexAction()
-
{
-
// Choose the default layout
-
$this->_helper->layout->setLayout('default');
-
-
// Set the page title
-
$this->view->headTitle('Hello World!');
-
}
-
}
All following URIs will execute the indexAction() method:
- http://myzendproject.com/index/index/
- http://myzendproject.com/index/
- http://myzendproject.com/
As you can see, the first parameter defines the controller and the second parameter defines the action.
The last thing left to do is to create a view script for the index action of the index controller. Every controller has a folder named after it where its actions templates are stored. Therefor, open the MyZendProject/application/modules/default/views/scripts/index/index.phtml template and write:
-
<h1>Hello World</h1>
Now go to http://myzendproject.com/index/index/ and you should see your first Zend application say “Hello World!” to you.
Error controller
Error controller is an important part of every application. It is very useful while developing (nicely formatted error information for debugging) as well as during a production phase of a project (404 page). I am just going to copy and paste the default controller and template I use here.
MyZendProject/application/modules/default/controllers/ErrorController.php:
-
class ErrorController extends Zend_Controller_Action
-
{
-
public function errorAction()
-
{
-
$errors = $this->_getParam('error_handler');
-
switch ($errors->type) {
-
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
-
-
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
-
// 404 error – controller or action not found
-
$this->getResponse()->setHttpResponseCode(404);
-
$this->view->headTitle('Page not found');
-
$this->view->message = 'Page not found';
-
break;
-
default:
-
// Application error
-
$this->getResponse()->setHttpResponseCode(500);
-
$this->view->headTitle('Application error');
-
$this->view->message = 'Application error';
-
break;
-
}
-
-
$this->_helper->layout->setLayout('error');
-
$this->view->env = $this->getInvokeArg('env');
-
$this->view->exception = $errors->exception;
-
$this->view->request = $errors->request;
-
}
-
}
MyZendProject/application/modules/default/views/scripts/error/error.phtml:
-
<h1><?php echo $this->message; ?></h1>
-
<?php if ('development' == $this->env): ?>
-
<h2>Exception information:</h2>
-
<p><b>Message:</b> <?php echo $this->exception->getMessage(); ?></p>
-
<h2>Stack trace</h2>
-
<code><?php echo $this->exception->getTraceAsString(); ?></code>
-
<h2>Request parameters:</h2>
-
<code><?php var_dump($this->request->getParams()); ?></code>
-
<?php endif; ?>
Thanks a lot for such a nice documentation.
I was searching for such type of content since long.