Step Create Your Directory Structure

Zend Framework can be configured to meet just about any directory configuration. The default configuration that I am describing here is the recommended setup. Do it this way and you will have fewer problems.

A note here about directories: I develop on a Windows based laptop while staging and production are on Linux. Later on, we will discuss ways to minimize the pain of moving between environments. For most of the examples in this book however, I will assume a Windows environment. You Linux and OSX users out there are probably savvy enough to figure out that when I say \ I mean / and so forth.

My development environment is contained entirely in c:\web. This is considered my web server root. Beneath it I have a directory for each project I am working on, as well as directory for common code like {{include PEAR}}PEAR and Zend Framework. So, for this project my c:\web looks like this:

C:\web\ <-- Web Server Root htdocs\ <-- web application root www\ <-- web site root

Now, below the htdocs directory we need to add a space for our application. Zend Framework is designed so that only the bare minimum goes into your www directory. This is a safety feature since the web server can only see and serve files in www. Anything outside of that, it can't serve, therefore it is more difficult to leak sensitive information if it is stored outside of www.

To flesh out our directory structure, let's add the needed directories for Zend Framework as well as one for housekeeping.

htdocs\

<-- Web Server Root <-- web application root lib\ <-- AH 3rd party libraries

Zend\ <-- Where the framework lives application\ <-- Zend Framework based application controllers\ models\ views\ scripts\

index\ <--One dir for each controller www\ <-- web root images\ <--the rounded corners for our apps.

Now our directory structure has been fleshed out. Step 3: Create Your Bootstrap File

When working with Zend Framework, you will often hear people refer to the "bootstrap" file. This is mainly because programmers like to make things sound more complicated than they actually are. (I am pretty sure that it's a Guild law.) For the purposes of our discussion, "bootstrap file" means index.php. It's that simple. It's the file your web server calls when a request is made to your application. Your bootstrap file is always located in the webroot of your application.

Your bootstrap file can be very simple or range into the complex. For our "Hel-loWorld" we just need a simple one. Let's start our index.php with the following lines of code:

$lib_paths[] = "c:/web/htdocs/application"; $lib_paths[] = "c:/web/htdocs/lib";

$inc_path = implode(PATH_SEPARATOR, $lib_paths);

set_include_path($inc_path);

This first part may seem strange to beginners and even stranger to advanced programmers. Here we are manually setting our "include path". Before you scream "scalability!" or "portability!", keep in mind that this is merely sample code. It's also okay to do this in a development environment where you may not have total control over your server. Do not, under penalty of extreme slowness, do this on a production server. Your production environment should be setup by your admin and you should already have your include_path setup properly.

Let's look at what that code is actually doing. Our "HelloWorld" app needs 3 directories in the include_path so that PHP can find everything.

• c:/web/htdocs/application. This is where the application actually lives. It is very important that PHP can find all the pieces of the app. Mess this one up and it's a short trip to the fatal error.

• c:/web/application/lib. This is the home of all libraries not actually part of the application. Among other things, this is where the framework itself actually resides.

Beyond that, we simply take the array we just built, scrunch it up into one long string and shove a PATH_SEPARATOR between each one. Then we use this "FrankenString" we've created as PHP's new "include path".

As I said before, this works fine in a development environment. Heck, it works okay in production if you don't have more than 5 people at a time hitting your site. However, if you deploy this code to a busy site, you will feel the pain. Let's continue our bootstrap file by adding the following code:

require_once 'Zend/Loader.php'; require_once 'Zend/Controller/Front.php';

Here we pull in the basic classes we know we will need to complete the bootstrap. The bigger your application, the longer this list will be. However, "HelloWorld" only needs the bare minimum.

I know that nobody ever writes code with errors in it. I'm probably the only person who has ever seen a fatal error in a production application. However, Zend Framework is loaded with exceptions that can be thrown to signal a variety of conditions. In development, we want those errors to show up so we can fix them. In production, we want to do something different. Either way, one of the worst things that can happen is for an uncaught exception to show in our user's web browser. So, we wrap everything form here on out in a try{}. If nothing else catches the exception, this will and we can deal with it as we see fit. Add the following code to your bootstrap file:

The front controller in Zend Framework is what takes care of everything. It sets up the environment, figures out which controller to call and routes it. Finally it handles routing the output when everything is done. The front controller follows the singleton design pattern, meaning that there is and can be, only one instance of it. Therefore in our bootstrap, we don't instantiate it like a normal class, we make a call to its (static) getInstance() method. This will use the instance of FrontController already in place. Therefore, we add the following lines to our file:

Zend_Loader: : loadClass(' Zend_Cont roller_Front'); $frontController = Zend_Controller_Front::getInstance();

Since Zend Framework works off of configuration instead of convention, here in the bootstrap we do have to set a few parameters for things to work right. The first one tells the FrontController to pass through any uncaught exceptions. This is fine for now, because we are in development but you would almost never want this option set in production. Later on you will see that we parameterize this and put the setting in a config file. This allows us to have different settings for development, staging, and production.

The second parameter tells Zend Framework not to try and find a view script. Our example is a very simple "HelloWord," and all of our code will be contained in the IndexController.php file.

The third parameters tell the FrontController not to try and find an ErrorController when it hits a problem. In a larger application, this could be used to log the error, politely notify the user that an error has occurred, and/or perform any number of housekeeping tasks. However, in our "HelloWorld," we don't need any of that so in this case, we just turn it all off.

The fourth parameter tells the front controller where to find the other controllers. Again, in larger applications, this would not be hard-coded but be parameterized for portability. Add the following code to your file:

$f rontCont roller->throwExceptions(true); $frontController->setParam('noViewRendered', true); $frontController ->setParam('noErrorHandler', true);

$f rontCont roller->setCont rollerDirectory('c:/web/htdocs/app/controllers/');

That's it. Now we throw the switch and watch the magic. $frontController->dispatch();

Should there be an uncaught exception, the following code will print the stack trace to the output device so we can hopefully find the error and correct it.

} catch (Exception $exp) { $contentType = 'text/html';

header("Content-Type: $contentType; charset=utf-8"); echo 'an unexpected error occurred.';

echo '<h2>Unexpected Exception: ' . $exp->getMessage() . '</h2><br /><pre>'; echo $exp->getTraceAsString();

That's one of the simplest bootstrap files you can have. I know I spent a lot of time on this, but going forward we will use a variation of this in every example in the book. In future projects, I'll only show the pieces that change. You can, however, refer back to this one for the complete version.

Was this article helpful?

0 0

Post a comment