Tiger Heron
Tiger Heron
Tiger Heron

First steps with PHP - booting a script, Part 2

No votes yet

If you haven't already, you may want to start with Part 1 of this topic. Part 2 of my discussion on booting begins with a digression.

Frameworks and libraries

Some time ago, I read an article by Rasmus Lerdorf titled The no-framework PHP MVC framework. It got me thinking about my framework, which at the time I was converting from PHP4 to PHP5.

In the good old days, if you wanted to create re-usable code, you would create a library of related functions or objects. Now, the excitement is all around frameworks. Everyone has one. What is the difference between the two?

In my mind, a library:

  • Is under the control of the application
  • Provides a set of functions or objects for performing a closely related set of tasks
  • Has few pre-requisites
  • Works independently of other libraries

A framework:

  • Controls the application
  • Tends to enforce a methodology
  • Performs a wide range of tasks
  • Contains code that is heavily dependent on the framework environment. It would be difficult to extract a single piece of functionality without dragging in most of the rest of the framework.

I like the synergy of the framework, but I also like the flexibility and lighter weight of a library. Frameworks tend to be biased to solving a specific kind of problem. I wanted something more general.

My framework would:

  • Be object-oriented
  • Be under the application's control
  • Provide an architecture that allowed addressing a wide range of tasks
  • Consist of "libraries" which worked synergistically but which would also allow integration of external functionality (through base classes and interfaces)
  • Minimize the amount of core classes needed to use the framework

I know that calling my framework a "framework" creates some confusion. It is not a framework like CakePHP but it is a framework like the Java framework. Until a better term comes along, I'll stick with it.

Back to booting

Let's return to our main topic. The digression was necessary because it led me to completely separate the boot and framework code. Each operates independently from the other.

Returning to where we left off last week, we know that each Web page begins with

require 'include.inc';

where include.inc contains:

$fileTop = ...;
require "$fileTop/res/boot/boot.inc";

The boot.inc performs certain tasks but never directly accesses the framework code. The framework, in return, never directly uses any of the variables or functions defined in boot.inc.

Directory structure

This is the directory structure I use:

1 res 2 boot 3 boot.inc 1 site 2 php 3 conf.inc 3 setup.inc 1 th

Notes:

  • The "res" directory contains all resources except images. This includes CSS, Javascript and PHP code.
  • The "boot" directory contains just one file, boot.inc. I just the same boot.inc file to boot many sites.
  • The "site" directory contains all the site-specific files. The boot system requires two files in res/site/php: conf.inc and setup.inc.
  • The "th" directory contains the Tiger Heron framework which I will cover in future articles.

The boot sequence

I can finally describe the boot sequence:

  1. The server loads the Web page
  2. The Web page loads include.inc
  3. In include.inc, define $fileTop and load res/boot/boot.inc
  4. In boot.inc, load res/site/php/conf.inc
  5. Define some variables, set the include path and perform some basic initialization
  6. Finish boot.inc by loading res/site/php/setup.inc

The conf.inc file gives the site a "hook" for any special setup that must be performed immediately. It also allows the site to configure some site-specific values for boot.inc. Code in conf.inc is limited by the fact that the include path has not been set up. It also cannot rely on any functionality other than what is in boot.inc and what is bundled with PHP.

While conf.inc is customized for each site, I usually start with a template. The template indicates some values I may want to define and speeds up construction of new Web sites.

Boot.inc will:

  1. Define $webTop, the relative path to the top of the site. This is usually, but not always, the same as $fileTop. I use $fileTop to reference files in the file system and $webTop to reference files through the Web server (e.g. CSS files, Javascript files, etc.).
  2. I determine whether this site is running on my PC, on a staging site or on a production site.
  3. The error reporting is set based on where the code is running. On production sites, all error reporting is suppressed, while PC and staging sites report all errors.
  4. I set up the include path based on the system type and values passed in by conf.inc.
  5. I turn off user aborts, as these can wreck a database.
  6. I remove magic quotes if they have been applied.
  7. I allow for Macintosh line endings.
  8. I set the content type to either text/html or application/xhtml+xml depending on whether I am using XHTML (a conf.inc option) and whether the browser supports application/xhtml+xml.
  9. I use UTC as the timezone.
  10. I define some absolute and relative paths to various commonly accessed places.

Having completed this list of tasks, res/sites/setup.inc is called to finish off any site-specific setup. It is the setup.inc file that determines whether the framework code will or will not be included.

I've left off one important step. The Web page, before including any code, can set define some values of its own. Let's say, for example, that you wanted to enable caching for some files and not others. The conf.inc file could include the default choice and each Web page could override that choice.

To make this clear, the Web page would start with:

$useCache = false;
require 'include.inc';

And the conf.inc file would contain:

if (!isset($useCache)) $useCache = true;

Finally, the setup.inc file would set up the caching based on the value of $useCache.

The caching example points out that boot.inc doesn't include all the tasks you may need for some Web sites. For instance, there is nothing in boot.inc for handling caching and sessions. These are more complicated tasks and are supported by the framework. Since the boot sequence can't depend on the framework, these additional tasks are left to setup.inc. For rapid site building, I have a template for setup.inc, but I am free to change it as appropriate for the site.

The .htaccess file

One of my goals was to be able to copy the entire site from my PC to the staging or production servers without requiring any code changes. Sometimes, code in the .htaccess file cannot be written to be system independent.

I used to have to maintain two copies of the .htaccess file, one for my PC and one for the hosting site. It occurred to me one day that I could start up my PC's Apache server with a -D DEVELOPMENT_ENV command-line option. This allows me to separate PC and hosting options using

<IfDefine DEVELOPMENT_ENV>
  ...
</IfDefine>

and

<IfDefine !DEVELOPMENT_ENV>
  ...
</IfDefine>

Mission accomplished

If you go back to Part 1 of this topic, you'll see I have met all the goals I set for myself without violating any of the restrictions I listed.

The boot sequence is fast, performing only what I need to support my PC/staging/production development approach. It also initializes the PHP environment, since I can't count on being able to set php.ini or using php_flag and php_value in my .htaccess file.

The boot sequence provides two hooks for site customization. I can also choose to use it with or without my framework. This gives me a lot of flexibility.

If you want a closer look at this, I have packaged up the boot code for a site at www.sample.com. The package includes two Web pages, index.php and subdir/index.php with the supporting boot files. It does not include any framework code.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.

 

Privacy policy Tiger Heron LLCinfo@tigerheron.com • (503) 771-7724

Copyright © 2005-2007, Tiger Heron LLC