Chapter 1. Getting Started

Before you get into building your CMS project, it is important to understand a few things about Zend Framework (ZF). The core of ZF is a loosely coupled application framework that consists of a library of components.

These components are all written in object-oriented PHP, closely following the current best practices. They can be used independently, much like components in many other code libraries. For example, a developer can use the Zend_Service_Amazon component without using the Zend_Db abstraction layer.

What differentiates ZF from many other PHP code bases is the model-view-controller (MVC) implementation. MVC is a pattern where an application is broken into three distinct parts:

  • Business logic: The controller handles the logic behind the application.

  • Data: The model handles managing the application data.

  • Presentation: The view handles rendering the dynamic pages.

Note

There are a number of differing opinions regarding the structure of an MVC application. The approach I just described is referred to as the fat controller approach.

This pattern is rapidly becoming the standard for web application development, because this clean separation makes complicated sites significantly easier to develop and maintain. This is particularly true in the case of a development team; the developers can focus on their areas of expertise without having to work around unrelated code.

Introducing Zend Framework MVC Implementation

Zend Framework's MVC implementation consists of three main components:

  • Zend_Controller

  • The model, which often consists of a Zend_Db_Table class but can be any data source

  • Zend_View

At its simplest, Zend_Controller processes the request, fetches data from Zend_Db, and then passes this data to Zend_View to render the dynamic XHTML. Bear in mind that ZF is a very flexible framework, and any of these components can be used on their own, but they provide a rich application platform when used together.

The Controller: Zend_Controller_Front

Zend_Controller_Front implements the front controller pattern. All requests are ported through this single point of entry, which is responsible for building and returning the response. The front controller's workflow consists of several components, which represent the following sequential process:

  1. The request object (Zend_Controller_Request_Abstract): This represents the unprocessed request and is responsible for evaluating the user request and providing information about the request to the rest of the process.

  2. The router (Zend_Controller_Router_Interface): The router inspects the request object and then determines which controller and action should be run to process the request. By default, the router breaks down the URL into the controller, actions, and key/value pairs of parameters. For example, http://localhost/user/profile/id/234 would be evaluated to the user controller and profile action, and the parameter id would equal 234.

  3. The dispatcher (Zend_Controller_Dispatcher_Interface): The dispatcher takes the information that the router provides, instantiates the proper action controller, and runs the action method. Bear in mind that this process occurs in a loop and can happen several times during the scope of a request. This is commonly used with modular applications that may run several actions prior to returning the response. I often use this approach to enable developers to embed the response from a module in a CMS page.

  4. The response (Zend_Controller_Response_Abstract): The response object is responsible for collecting and returning the responses from the controller actions.

The Model: Zend_Db

A web application can serve data from many sources, but the most common source is a database. Zend_Db provides a SQL database interface for ZF. A number of adapters for different database systems are available that provide an abstraction layer to these databases. This abstraction layer enables you to use a common set of tools for a range of different database systems.

Zend_Db_Table, which is the class that you will use to create your models, provides an object-oriented interface to these database tables. It implements the Table Data Gateway pattern. This pattern manages all the SQL for common database functions. This is a more generic approach to database abstraction, as opposed to other ORM systems that map data objects and their relationships to a relational database.

It also includes an implementation of the Row Data Gateway pattern, which creates data objects that provide access to all the underlying information in a database row.

The View: Zend_View

Zend_View is a lightweight class that provides the view for the ZF MVC implementation. The front controller creates an instance of Zend_View, which maps to the action methods in the controller classes. The action method sets view variables with data that it loads from the model, and then Zend_View takes this data and generates the XHTML response. It includes a number of tools to make this process as flexible as possible, including helpers and filters. Bear in mind that although Zend_View uses PHP as its default template system, you can use it with a variety of different systems such as Smarty.

Setting Up Your Development Environment

The first thing you will need to set up for the framework is a development server to build and test your projects on. There are a wide range of options for both Linux and Windows operating systems. One of these solutions, which includes Zend Framework and command-line tools, is Zend Server. There are two versions of this package: the community version and a commercial version that includes support, updates, and additional features. For your local development environment, the community version should suffice.

Installing Zend Server CE

Zend Server includes installers for both Linux and Windows. In this section, I will describe the installation process for the Windows version.

First you need to get download the server installer. You can get the current download on the Zend Server website (http://www.zend.com/en/products/server/).

Once you have downloaded the installer, start it, and you should see a screen that looks like Figure 1-1.

The Zend Server Windows installer

Figure 1.1. The Zend Server Windows installer

Click Next, and then read and agree to the license. Next you will be prompted to choose an installation type. Select Custom, and click Next.

You can select any components that you want, but make sure that the following items are selected:

PHP

  • Common Extensions

  • Additional Extensions

Zend Framework

  • Base

  • Extras

MySQL server

Once you have set up your components, click Next. Now select the option install the Apache server, and click Next. The next step is to select the port for Apache to use. In most situations, you can just use the default, port 80. Click Next and then Install to install the server. This may take some time because there are a number of components that need to be downloaded before your installation can be completed. Once the installation is completed, the installer will give you the option of starting to work with Zend Server. Select this option, and click Finish. Your browser should open, and you will be directed to the server administration page. The first time you load the server administration page, Zend Server will prompt you for a password. Once you enter the password, you will be granted access to the main server administration console.

Doing Rapid Application Development with the Zend Command-Line Tool

The Zend command-line tool gives developers access to the Zend Tool Framework through the command-line interface. Zend Tool Project provides a number of tools for creating new projects and adding components to existing projects.

Zend Tool Project is configured as part of the Zend Server installation, but it is not difficult to manually configure it if you are not using Zend Server. Consult the documentation for Zend Framework for more information on this subject.

Next open a terminal window. Next check the current version of the framework using the zf show version command. If everything is properly set up, you should see Zend Framework Version: 1.8. x, as in Figure 1-2.

Running the zf show version command

Figure 1.2. Running the zf show version command

The Zend Tool Framework uses one of two files:

  • zf.bat for Windows users

  • zf.sh for Unix users

The usage of these two commands is identical. In the examples in this book, I will use the Windows version, because I develop on Windows. For Unix-based developers, simply replace zf.bat with zf.sh.

Creating Your Project

Now that you have your development environment installed and tested, you are ready to start building the project.

Building a Project with the Zend Tool Framework

To build your project, open your terminal window. Then navigate to your server's document root. The document root is the folder that contains all the publicly accessible scripts on your server; in a default Zend Server installation, this will be ~/Apache2/htdocs. You create a new project using the create project command. Follow this command with the name of your project, which in this case will be zf_cms. Run this command, and the Zend Tool Framework will build the base project, as in Figure 1-3.

Creating a project with the Zend Tool Framework

Figure 1.3. Creating a project with the Zend Tool Framework

Testing Your New Project

Now if you point your browser to http://localhost/zf_cms/public, you will see the welcome page.

To make the rest of your development process easier, set the server's document root to this folder. To set the document root, locate your httpd.conf file, which is in the Apache2/conf folder. Open this file in a text editor, and then locate the DocumentRoot directive. Update it with the absolute path to the public folder of your project, as in Listing 1-1.

Note

I often set up vhosts using the httpd-vhosts.conf file. This enables you to create multiple virtual hosts on your server, which behave more or less like independent servers. This enables me to manage multiple development sites on a single server instance.

Example 1.1. Updating the Document Root in Apache2/conf/httpd.conf

DocumentRoot "{absolute path to apache}/Apache2/htdocs/zf_cms/public"

You also need to enable rewriting in the zf_cms folder. Add the directive shown in Listing 1-2 to the end of the httpd.conf file, replacing {absolute path to apache} with the root-relative path to your server instance.

Example 1.2. Configuring the zf_cms Project in Apache2/conf/httpd.conf

<Directory "{absolute path to apache}Apache2htdocszf_cms">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

Once you have updated this directive, restart your server, and point your browser to http://localhost again. Now you should see your project rather than the Zend Server welcome screen (Figure 1-4).

Zend Framework project welcome screen

Figure 1.4. Zend Framework project welcome screen

Exploring the Anatomy of Your Project

If you open the folder that the Zend Tool Framework created for your project, you will see that the project is organized into three subfolders:

  • public: All the files that must be publicly accessible will reside in this folder, which will be your document root.

  • library: This folder will contain the framework's library as well as a custom library that you will create for this project.

  • application: This folder is the heart of your project. It is where your models, views, and controllers will be.

You should note that ZF is not nearly as strict as many other application frameworks. This structure represents the standard layout of a ZF application, so many aspects of the framework will work without overriding the default behavior. At the same time, you can customize almost every aspect of the framework to work the way you want it to work. I prefer the "convention over configuration" approach, so I tend to stick with the defaults whenever possible.

The public Folder

The public folder is your document root. Zend Framework follows current best security practices by not exposing any of the core executable files to the public. The only files that are kept in the public web root are files that the browser must be able to access.

Redirecting the Request with .htaccess

When a new request comes to your project, the server loads the .htaccess file (Listing 1-3). The .htaccess file does two things. First it sets the APPLICATION_ENV environmental variable. This enables you to manage multiple environments in the application, which can be configured independently. Once this is set, it redirects every request (that does not map to an existing file) to the index.php file.

Example 1.3. The .htaccess file in /public/.htaccess

SetEnv APPLICATION_ENV development
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

The Index File

When the index.php file (Listing 1-4) receives the request, it builds the application and runs it.

First, it defines the default APPLICATION_PATH and APPLICATION_ENV environment variables. This is important because .htaccess might not be loaded, depending on the request type (a cron job, for example).

Next it ensures that the library is included in the project. At this point, the library is empty, because the Zend Framework library is included by your php.ini file.

Then it creates a new instance of Zend_Application, passing it the APPLICATION_ENV environment variable and the path to the application configuration file. This file is where you define how the application will be built.

Finally, it calls the Zend_Application instance's bootstrap() method and runs the application.

Example 1.4. The index.php File in public/index.php

<?php
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ?
    getenv('APPLICATION_ENV') : 'production'));
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));
/** Zend_Application */
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
            ->run();

Additional Public Folders

At this point you should also add three other subfolders in the public folder: images, css, and javascript. Depending on your application, you may need to add other folders to this, such as one for document downloads.

The library Folder

I prefer to install the library in each project. This is because you may run several ZF projects on a single server, and different projects may be built on different versions of the framework.

Download the most recent version of the framework at http://framework.zend.com. Extract the archive contents, and then copy the Zend folder from the download's library folder into your library folder. The framework is simply a library of classes, so you don't need to perform any other installation procedures.

You will be creating several library classes for the CMS project, and it is a best practice to create your own library folder to do this so your code does not get mixed up with the ZF core. Create a new folder in the library called CMS. Your library folder should look like Listing 1-5.

Example 1.5. The library Folder

/ library
    / Zend
    / CMS

The application Folder

The application folder is where all of your models, views, and controllers are located. This keeps all of your business logic outside the publicly accessible document root.

Zend_Application

As web applications become more advanced, they also become more complicated to manage. In previous versions of the framework, this was handled by a number of files and plug-ins, which were responsible for different areas of the process. Zend_Application provides an object-oriented method for configuring, bootstrapping, and running ZF applications.

The Bootstrap Class

The Bootstrap class (Listing 1-6), by default, initializes the front controller and uses the default application/controllers path as the path to the controllers. As you build your CMS, you will add many more resources to the Bootstrap class, such as the database connection, but for now this is a very simple class that leverages the base Zend_Application_Bootstrap_Bootstrap functionality.

Example 1.6. The Bootstrap Class in application/Bootstrap.php

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {}

Application Configuration

The Zend Tool Framework created the default site configuration file (Listing 1-7) in application/configs/application.ini.

When you open this file, you will notice that four config sections are defined. Each of these sections relates to an application environment. This enables you to configure your different environments independently. For example, you probably want to display any errors that occur on the development environment, but not on the production site. You will also notice that staging, testing, and development extend production using the following coding convention: [testing : production]. This enables you to set your core application settings in the base section and then override any settings that are different in the specific sections.

By default, this config file sets the following:

  • PHP error settings

  • Additional application include paths

  • The path to the bootstrap class

  • The bootstrap class name

  • The path to the default controller directory

As you build this CMS project, you will add many more settings to this file.

Example 1.7. The Default Application Config File in application/configs/application.ini

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

Action Controllers

The action controllers manage your application. When you run the application, it processes the request, loads the appropriate controller class, and then runs the action that was requested. The action, in turn, loads and processes any required data from the models and then renders the proper view script.

The Zend Tool Framework creates the IndexController class (Listing 1-8), which is the default controller. At this point, IndexController and indexAction() are simply handing control over to Zend Framework. Later in the book, when you are building the actual CMS, you will add the application logic to these action methods.

Example 1.8. The IndexController Class in application/controllers/IndexController.php

<?php
class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        /* Initialize action controller here */
    }
    public function indexAction()
    {
        // action body
    }
}

Views

Once indexAction() hands the control over, the framework will map the request to the view scripts and render this as the response. By default the framework will look for a view script named index.phtml (Listing 1-9) in the /views/scripts/index folder that resides in the same folder as your /controllers folder.

Note the .phtml file extension; using this file extension is the current best practice in Zend Framework development. It differentiates the view scripts from standard PHP files.

Example 1.9. The index.phtml View Script in application/views/scripts/index/index.phtml

<style>
    a:link,
    a:visited
    {
        color: #0398CA;
    }
    span#zf-name
    {
        color: #91BE3F;
    }
    div#welcome
    {
        color: #FFFFFF;
        background-image: url(http://framework.zend.com/images/bkg_header.jpg);
        width:  600px;
        height: 400px;
        border: 2px solid #444444;
        overflow: hidden;
    }
    div#more-information
    {
        background-image: url(http://framework.zend.com/images/bkg_body-bottom.gif);
        height: 100%;
    }
</style>
<center>
    <div id="welcome">
        <center>
        <br />
        <h1>Welcome to the <span id="zf-name">Zend Framework!</span><h1 />
        <h3>This is your project's main page<h3 /><br /><br />
        <div id="more-information">
            <br />
            <img src="http://framework.zend.com/images/PoweredBy_ZF_4LightBG.png" />
            <br /><br />
            Helpful Links: <br />
            <A href="http://framework.zend.com/">Zend Framework Website</a> |
            <A href="http://framework.zend.com/manual/en/">Zend Framework Manual</a>
        </div>
    </div>
</center>

Error Handling

It is probably safe to assume that everything worked fine in this simplistic example, but errors are a fact of life in programming. Zend Framework includes an error plug-in that handles these issues.

The error plug-in captures any exceptions that are thrown by your application. This includes the exceptions that occur when a controller or action is not found as well as any exceptions that occur in your action controllers. These exceptions relate to 404 and 500 errors.

Once the error plug-in encounters an exception, it redirects the request to ErrorController's errorAction() in the default module. At that point, it hands the control over to you, which enables you to determine how much information to give the user about the issue and how to present it.

The Zend Tool Framework creates the ErrorController class (Listing 1-10) and its associated view (Listing 1-11) for you.

The error controller's errorAction() fetches the error handler and evaluates which type of error occurred. Then it sets the response code and sets the error message. It also passes the exception and the request object to the view, so the view has all the information required to display a complete error report.

Example 1.10. The ErrorController in application/controllers/ErrorController.php

<?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->message = 'Page not found';
                break;
            default:
                // application error
                $this->getResponse()->setHttpResponseCode(500);
                $this->view->message = 'Application error';
                break;
        }
        $this->view->exception = $errors->exception;
        $this->view->request   = $errors->request;
    }
}

The error view script renders the error message that was set in the error controller. If the current environment is development, it also renders the complete exception, the stack trace, and any request parameters that were set. This makes it easier for you to track down the issue.

Example 1.11. The Error View Script in application/views/scripts/error/error.phtml

<!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">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Zend Framework Default Application</title>
</head>
<body>
  <h1>An error occurred</h1>
  <h2><?= $this->message ?></h2>

  <? if ('development' == APPLICATION_ENV): ?>

  <h3>Exception information:</h3>
  <p>
      <b>Message:</b> <?= $this->exception->getMessage() ?>
  </p>

  <h3>Stack trace:</h3>
  <pre><?= $this->exception->getTraceAsString() ?>
  </pre>

  <h3>Request Parameters:</h3>
  <pre><? var_dump($this->request->getParams()) ?>
  </pre>
  <? endif ?>
</body>
</html>

Now when you point your browser to a page that does not exist, such as http://localhost/missing/page, you will be directed to this view, which should display your error like Figure 1-5.

The error page

Figure 1.5. The error page

Summary

In this chapter, you set up your development server and created the base for your CMS project, learning about many of the most important Zend Framework components and concepts in the process. Over the course of the rest of this book, you will add more complex designs, database access, interactivity, and security to these simplistic roots. Many of these items may seem complicated at the outset, but always bear in mind that these simple concepts are the basis for every Zend Framework MVC application, no matter how complex.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset