<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.tigerheron.com" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>PHP</title>
 <link>http://www.tigerheron.com/category/php</link>
 <description>The taxonomy view with a depth of 0.</description>
 <language>en-US</language>
<item>
 <title>First steps with PHP - booting a script, Part 2</title>
 <link>http://www.tigerheron.com/article/2008/04/first-steps-php-booting-script-part-2</link>
 <description>&lt;p&gt;
  If you haven&#039;t already, you may want to start with
  &lt;a href=&quot;/article/2008/03/first-steps-php-booting-script-part-1&quot;&gt;Part 1&lt;/a&gt;
  of this topic. Part 2 of my discussion on booting begins with a digression.
&lt;/p&gt;

&lt;h2&gt;Frameworks and libraries&lt;/h2&gt;
&lt;p&gt;
  Some time ago, I read an article by
  &lt;a href=&quot;http://lerdorf.com&quot;&gt;Rasmus Lerdorf&lt;/a&gt; titled
  &lt;a href=&quot;http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html&quot;&gt;&lt;cite&gt;The no-framework PHP MVC framework&lt;/cite&gt;&lt;/a&gt;.
  It got me thinking about my framework, which at the time I was
  converting from PHP4 to PHP5.
&lt;/p&gt;
&lt;p&gt;
  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?
&lt;/p&gt;
&lt;!--break--&gt;
&lt;p&gt;
  In my mind, a library:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Is under the control of the application&lt;/li&gt;
  &lt;li&gt;
    Provides a set of functions or objects for performing a closely
    related set of tasks
  &lt;/li&gt;
  &lt;li&gt;Has few pre-requisites&lt;/li&gt;
  &lt;li&gt;Works independently of other libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  A framework:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Controls the application&lt;/li&gt;
  &lt;li&gt;Tends to enforce a methodology&lt;/li&gt;
  &lt;li&gt;Performs a wide range of tasks&lt;/li&gt;
  &lt;li&gt;
    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.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  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.
&lt;/p&gt;
&lt;p&gt;
  My framework would:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Be object-oriented&lt;/li&gt;
  &lt;li&gt;Be under the application&#039;s control&lt;/li&gt;
  &lt;li&gt;
    Provide an architecture that allowed addressing a wide range of
    tasks
  &lt;/li&gt;
  &lt;li&gt;
    Consist of &quot;libraries&quot; which worked synergistically but which
    would also allow integration of external functionality (through
    base classes and interfaces)
  &lt;/li&gt;
  &lt;li&gt;
    Minimize the amount of core classes needed to use the framework
&lt;/ul&gt;
&lt;p&gt;
  I know that calling my framework a &quot;framework&quot; 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&#039;ll stick
  with it.
&lt;/p&gt;

&lt;h2&gt;Back to booting&lt;/h2&gt;
&lt;p&gt;
  Let&#039;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.
&lt;/p&gt;
&lt;p&gt;
  Returning to where we left off last week, we know that each Web page
  begins with
&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;require &lt;span style=&quot;color: #006080&quot;&gt;&#039;include.inc&#039;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  where include.inc contains:
&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;$fileTop = ...;
require &lt;span style=&quot;color: #006080&quot;&gt;&quot;$fileTop/res/boot/boot.inc&quot;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  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.
&lt;/p&gt;

&lt;h2&gt;Directory structure&lt;/h2&gt;
&lt;p&gt;
  This is the directory structure I use:
&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&quot;/files/blogs/developer/node116/boot-dir.png&quot; width=&quot;150&quot; height=&quot;147&quot; alt=&quot;1 res 2 boot 3 boot.inc 1 site 2 php 3 conf.inc 3 setup.inc 1 th&quot; title=&quot;&quot;&gt;
&lt;/p&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    The &quot;res&quot; directory contains all resources except images. This
    includes CSS, Javascript and PHP code.
  &lt;/li&gt;
  &lt;li&gt;
    The &quot;boot&quot; directory contains just one file, boot.inc. I just the
    same boot.inc file to boot many sites.
  &lt;/li&gt;
  &lt;li&gt;
    The &quot;site&quot; directory contains all the site-specific files. The boot
    system requires two files in res/site/php: conf.inc and setup.inc.
  &lt;/li&gt;
  &lt;li&gt;
    The &quot;th&quot; directory contains the Tiger Heron framework which I will
    cover in future articles.
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The boot sequence&lt;/h2&gt;
&lt;p&gt;
  I can finally describe the boot sequence:
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;The server loads the Web page&lt;/li&gt;
  &lt;li&gt;The Web page loads include.inc&lt;/li&gt;
  &lt;li&gt;In include.inc, define $fileTop and load res/boot/boot.inc&lt;/li&gt;
  &lt;li&gt;In boot.inc, load res/site/php/conf.inc&lt;/li&gt;
  &lt;li&gt;
    Define some variables, set the include path and perform some basic
    initialization
  &lt;/li&gt;
  &lt;li&gt;Finish boot.inc by loading res/site/php/setup.inc&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  The conf.inc file gives the site a &quot;hook&quot; 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.
&lt;/p&gt;
&lt;p&gt;
  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.
&lt;/p&gt;
&lt;p&gt;
  Boot.inc will:
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    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.).
  &lt;/li&gt;
  &lt;li&gt;
    I determine whether this site is running on my PC, on a staging
    site or on a production site.
  &lt;/li&gt;
  &lt;li&gt;
    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.
  &lt;/li&gt;
  &lt;li&gt;
    I set up the include path based on the system type and values
    passed in by conf.inc.
  &lt;/li&gt;
  &lt;li&gt;I turn off user aborts, as these can wreck a database.&lt;/li&gt;
  &lt;li&gt;I remove magic quotes if they have been applied.&lt;/li&gt;
  &lt;li&gt;I allow for Macintosh line endings.&lt;/li&gt;
  &lt;li&gt;
    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.
  &lt;/li&gt;
  &lt;li&gt;I use UTC as the timezone.&lt;/li&gt;
  &lt;li&gt;
    I define some absolute and relative paths to various commonly
    accessed places.
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  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.
&lt;/p&gt;
&lt;p&gt;
  I&#039;ve left off one important step. The Web page, before including any
  code, can set define some values of its own. Let&#039;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.
&lt;/p&gt;
&lt;p&gt;
  To make this clear, the Web page would start with:
&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;$useCache = &lt;span style=&quot;color: #0000ff&quot;&gt;false&lt;/span&gt;;
require &lt;span style=&quot;color: #006080&quot;&gt;&#039;include.inc&#039;&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  And the conf.inc file would contain:
&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (!isset($useCache)) $useCache = &lt;span style=&quot;color: #0000ff&quot;&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  Finally, the setup.inc file would set up the caching based on the
  value of $useCache.
&lt;/p&gt;
&lt;p&gt;
  The caching example points out that boot.inc doesn&#039;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&#039;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.
&lt;/p&gt;

&lt;h2&gt;The .htaccess file&lt;/h2&gt;
&lt;p&gt;
  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.
&lt;/p&gt;
&lt;p&gt;
  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&#039;s Apache server with a -D DEVELOPMENT_ENV
  command-line option. This allows me to separate PC and hosting
  options using
&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;IfDefine&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;DEVELOPMENT_ENV&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
  ...
&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;IfDefine&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  and
&lt;/p&gt;
&lt;div&gt;&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;IfDefine&lt;/span&gt; !&lt;span style=&quot;color: #ff0000&quot;&gt;DEVELOPMENT_ENV&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
  ...
&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;IfDefine&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Mission accomplished&lt;/h2&gt;
&lt;p&gt;
  If you go back to &lt;a
  href=&quot;/article/2008/03/first-steps-php-booting-script-part-1&quot;&gt;Part
  1&lt;/a&gt; of this topic, you&#039;ll see I have met all the goals I set for
  myself without violating any of the restrictions I listed.
&lt;/p&gt;
&lt;p&gt;
  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&#039;t count on being able to set php.ini or
  using php_flag and php_value in my .htaccess file.
&lt;/p&gt;
&lt;p&gt;
  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.
&lt;/p&gt;
&lt;p&gt;
  If you want a closer look at this, I have packaged up the &lt;a
  href=&quot;/files/blogs/developer/node116/boot-sample.zip&quot;&gt;boot code&lt;/a&gt; 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.
&lt;/p&gt;
</description>
 <comments>http://www.tigerheron.com/article/2008/04/first-steps-php-booting-script-part-2#comments</comments>
 <category domain="http://www.tigerheron.com/category/boot">boot</category>
 <category domain="http://www.tigerheron.com/category/php">PHP</category>
 <pubDate>Fri, 25 Apr 2008 22:22:13 +0000</pubDate>
 <dc:creator>developer</dc:creator>
 <guid isPermaLink="false">116 at http://www.tigerheron.com</guid>
</item>
<item>
 <title>First steps with PHP - booting a script, Part 1</title>
 <link>http://www.tigerheron.com/article/2008/03/first-steps-php-booting-script-part-1</link>
 <description>&lt;p&gt;
  Having covered &lt;a
  href=&quot;/article/2007/11/tale-two-patterns&quot;&gt;downloading and
  installing PHP&lt;/a&gt; and &lt;a
  href=&quot;/article/2008/01/eclipse-and-php&quot;&gt;setting up a development
  environment&lt;/a&gt;, I&#039;m now actually going to talk about
  &lt;em&gt;writing&lt;/em&gt; PHP code! Specifically, I will describe how I boot
  my PHP scripts and why I boot them the way I do. Part 1 shows how my
  requirements for code portability and maintainability influence the
  boot process. Part 2 will go into more detail about the specific
  steps executed by the boot code.
&lt;/p&gt;
&lt;!--break--&gt;
  &lt;h2&gt;My environment&lt;/h2&gt;
  &lt;p&gt;
    Here&#039;s some background: I develop sites for multiple clients.
    Initial coding occurs on my Windows XP system. When the code is
    running well, I upload it to the client&#039;s hosting system, which is
    typically Linux based.
  &lt;/p&gt;
  &lt;p&gt;
    I start by creating a new directory for my client&#039;s Web files (on
    my PC) and then creating an alias in my Apache configuration file
    to point to this location. For this article, let&#039;s assume I reach
    the Web site using http://localhost/sample.
  &lt;/p&gt;

  &lt;h2&gt;A sample task&lt;/h2&gt;
  &lt;p&gt;
    For our first PHP class, let&#039;s tackle something easy&amp;mdash;let&#039;s
    use PHP code to generate our sample site&#039;s navigation menu. Here&#039;s
    a quick sketch of the navigation class:
  &lt;/p&gt;
&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;&amp;lt;?php
&lt;span style=&quot;color: #0000ff&quot;&gt;class&lt;/span&gt; Navigation
{
    &lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; function printMainNav()
    {
        echo &lt;span style=&quot;color: #006080&quot;&gt;&#039;&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&quot;index.php&quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;....&#039;&lt;/span&gt;;
    }
}
?&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;
    and here is the index.php page using the class:
  &lt;/p&gt;
&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;
&amp;lt;?php &lt;span style=&quot;color: #0000ff&quot;&gt;require&lt;/span&gt; &lt;span style=&quot;color: #006080&quot;&gt;&#039;Navigation.inc&#039;&lt;/span&gt;; ?&amp;gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
    ...
  &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;?php $navigation = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; Navigation(); $navigation-&amp;gt;printMainNav(); ?&amp;gt;
      ...
  &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
  &lt;p&gt;
    At this point, the directory we created contains two files:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;index.php&lt;/li&gt;
    &lt;li&gt;Navigation.inc&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    The code works, but we&#039;re already seeing some potential pitfalls.
    First, we don&#039;t want to place the PHP classes in the same directory as
    the Web pages. Secondly, our sample system will eventually grow to
    where we will use sub-directories to organize our Web pages. The
    problems we see are:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;
      Each Web page will need to include the Navigation.inc file based
      on the Web file&#039;s location. If we ever change our mind about
      where to place Navigation.inc, a lot of files will need changes.
    &lt;/li&gt;
    &lt;li&gt;
      The link to the home page (in the navigation), as written, only
      works for Web pages at the top of the directory tree.
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    It may seem that there are some easy work-arounds for these two
    problems. For instance, setting the path to the Navigation.inc file in
    the php.ini file solves the first problem. And linking to
    &quot;/sample/index.php&quot;, solves the second. The reason these solutions
    aren&#039;t ideal lies with the environment in which I work.
  &lt;/p&gt;

  &lt;h2&gt;Goals and requirements&lt;/h2&gt;
  &lt;p&gt;
    These are my goals:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;I want to use a consistent approach for all my clients.&lt;/li&gt;
    &lt;li&gt;I want to allow for sub-directories in the Web site.&lt;/li&gt;
    &lt;li&gt;
      I want all Web files to have a consistent way of including PHP
      code, regardless of their location on the site. This lets me use
      the same template for all files and to move a file from one
      place to another without having to edit it.
    &lt;/li&gt;
    &lt;li&gt;
      I don&#039;t want the Web pages to use any complicated calculations
      in order to include PHP code. Complicated code should be stored
      in one place, not scattered in every Web page.
    &lt;/li&gt;
    &lt;li&gt;
      I want to be able to upload the code from my Windows system to
      the hosting system without &lt;em&gt;any&lt;/em&gt; changes and have it work
      in both environments.
    &lt;/li&gt;
    &lt;li&gt;
      Occasionally, I also want the code to work without change on a
      testing site on the hosting system. This lets the client preview
      site changes without affecting the site the customers sees.
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    These are the restrictions I have:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;
      I can&#039;t alter the php.ini file since shared hosting services
      usually don&#039;t provide access to this file.
    &lt;/li&gt;
    &lt;li&gt;
      I can&#039;t place php_flag or php_value statements in the .htaccess
      file. These only work if PHP is run as an Apache module and some
      hosting companies use Fast CGI. &lt;em&gt;(Note: apparently, this
      limitation will disappear in PHP 5.3.)&lt;/em&gt;
    &lt;/li&gt;
    &lt;li&gt;
      I can&#039;t assume I can reference a Web page at the top of the site
      by starting the path with &quot;/&quot;. This might work for the final
      site, but not for the site on the PC, where the top is at
      /sample.
    &lt;/li&gt;
  &lt;/ul&gt;

  &lt;h2&gt;My current solution&lt;/h2&gt;
  &lt;p&gt;
    I have not found the perfect solution. What I use is pretty close:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt; Each Web page begins with &amp;lt;?php require &#039;include.inc&#039;; ?&amp;gt;.&lt;/li&gt;
    &lt;li&gt;
      Each Web site directory contains an include.inc file with the
      following contents:
&lt;pre style=&quot;padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#039;Courier New&#039;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none&quot;&gt;
&amp;lt;?php
  $fileTop = &lt;span style=&quot;color: #006080&quot;&gt;&#039;.&#039;&lt;/span&gt;;
  &lt;span style=&quot;color: #0000ff&quot;&gt;require&lt;/span&gt; &lt;span style=&quot;color: #006080&quot;&gt;&quot;$fileTop/res/boot/boot.inc&quot;&lt;/span&gt;;
?&amp;gt;
&lt;/pre&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    The advantages are:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;
      We can move Web files from one directory to any other without
      editing.
    &lt;/li&gt;
    &lt;li&gt;
      The variable $fileTop identifies the file path to the top of the
      root of the Web site.
    &lt;/li&gt;
    &lt;li&gt;
      $fileTop is a relative path, so the Web site tree can be located
      anywhere in the site&#039;s document root.
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    It&#039;s not a perfect solution because I still have to create one
    include.inc file per directory. Of course, that&#039;s not very many
    files and the contents are not complicated. Any heavy lifting can
    be relegated to the boot.inc file.
  &lt;/p&gt;
  &lt;p&gt;
    It&#039;s also not perfect because it requires an extra file load for
    the include.inc file.
  &lt;/p&gt;
  &lt;p&gt;
    It assumes that &#039;.&#039; is in the php.ini search path. So far, this has
    proven to be a safe assumption.
  &lt;/p&gt;

  &lt;h2&gt;Alternatives&lt;/h2&gt;
  &lt;p&gt;
    Drupal and a number of other systems use a common dispatcher page
    for all Web site accesses. Every page loads index.php, which then
    includes the desired content. $fileTop is always &#039;.&#039;.
  &lt;/p&gt;
  &lt;p&gt;
    Using Apache&#039;s mod_rewrite module, the process could work like this:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;The user enters http://www.sample.com/somepage.&lt;/li&gt;
    &lt;li&gt;Mod_rewrite converts this to http://www.sample.com/index.php?q=somepage.&lt;/li&gt;
    &lt;li&gt;The index.php file is loaded.&lt;/li&gt;
    &lt;li&gt;
      The index.php can directly contain the boot.inc code. This saves
      one include/require.
    &lt;/li&gt;
    &lt;li&gt;It uses the &#039;q&#039; parameter to determine which page the user really wanted.&lt;/li&gt;
    &lt;li&gt;That Web page somepage.inc is included.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    This eliminates two file includes. There is some hidden cost in
    that the mod_rewrite script probably has to do a file check to see
    if the requested Web file actually exists&amp;mdash;this allows access
    to CSS, Javascript and image files that you may not want handled
    by PHP.
  &lt;/p&gt;
  &lt;p&gt;
    One problem with this approach is that my Web pages can set some
    options &lt;em&gt;before&lt;/em&gt; loading the include.inc file and these
    options control aspects of the boot process (e.g. whether to use
    caching, whether to use sessions, etc.). I will discuss this more
    in Part 2 of this article; we might lose this flexibility in the
    single dispatcher approach or we might have to work around it in a
    way that voids the performance gain. Not having tried this
    alternative, I&#039;m not sure of the answer.
  &lt;/p&gt;
  &lt;p&gt;
    Do you have an even better approach? Please let me know.
  &lt;/p&gt;

  &lt;h2&gt;More to come&lt;/h2&gt;
  &lt;p&gt;
    In Part 2, I will discuss what happens when the boot.inc file is
    executed. Stay tuned!
  &lt;/p&gt;
</description>
 <comments>http://www.tigerheron.com/article/2008/03/first-steps-php-booting-script-part-1#comments</comments>
 <category domain="http://www.tigerheron.com/category/boot">boot</category>
 <category domain="http://www.tigerheron.com/category/php">PHP</category>
 <pubDate>Tue, 18 Mar 2008 23:57:56 +0000</pubDate>
 <dc:creator>developer</dc:creator>
 <guid isPermaLink="false">114 at http://www.tigerheron.com</guid>
</item>
<item>
 <title>Eclipse and PHP</title>
 <link>http://www.tigerheron.com/article/2008/01/eclipse-and-php</link>
 <description>&lt;p&gt;
  In my last &lt;a
  href=&quot;/article/2007/11/tale-two-patterns&quot;&gt;article&lt;/a&gt;, I talked
  about installing PHP. With PHP installed, you will want to start
  writing code, so today&#039;s article is about developing PHP using the
  open source Eclipse integrated development environment (IDE).
&lt;/p&gt;
&lt;p&gt;
  Eclipse started as a Java IDE and evolved into a generic IDE with a
  strong Java bias. If you start out with a standard Eclipse
  installation and without any Eclipse experience, it may take you a
  while to figure out the best way to set it up for use with PHP. This
  article will make the PHP setup fast and easy.
&lt;/p&gt;
&lt;!--break--&gt;

&lt;h2&gt;Why use Eclipse?&lt;/h2&gt;
&lt;p&gt;
  The reasons for using Eclipse are the same as those for using most IDEs:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Syntax highlighting&lt;/li&gt;
  &lt;li&gt;Syntax validation as you type&lt;/li&gt;
  &lt;li&gt;Editing assistance (indentation, auto-completion, etc.)&lt;/li&gt;
  &lt;li&gt;Access to documentation as you type&lt;/li&gt;
  &lt;li&gt;Refactoring assistance&lt;/li&gt;
  &lt;li&gt;Debugging assistance&lt;/li&gt;
  &lt;li&gt;Integration with other tools (documentation creation, source
      control, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  Currently, the PHP version of a feature is often more limited than
  the Java version. For example, refactoring is limited to moving
  files; if you want to rename a class, method or function, you will
  need to use the Find/Replace tool (which, luckily, can be applied to
  all files in a project). I expect that the PHP tools will improve
  with time.
&lt;/p&gt;

&lt;h2&gt;PDT&lt;/h2&gt;
&lt;p&gt;
  Eclipse consists of a core set of functions and a flexible plugin
  system. The plugins provide many of the features that we usually
  think of as standard parts of an IDE. This is what makes it possible
  to adapt Eclipse to many computer languages.
&lt;/p&gt;
&lt;p&gt;
  &lt;a href=&quot;http://www.eclipse.org/pdt/&quot;&gt;PDT&lt;/a&gt; is the PHP Development
  Tools plugin, which is essential for working with PHP inside
  Eclipse. Over time, you may choose to enhance your Eclipse
  installation with other plugins, but for PHP development, you only
  need PDT (and its few dependencies).
&lt;/p&gt;

&lt;h2&gt;Getting started: Download&lt;/h2&gt;
&lt;p&gt;
  Begin by downloading the all-in-one &lt;a
  href=&quot;http://download.eclipse.org/tools/pdt/downloads/&quot;&gt;Eclipse/PDT
  ZIP file&lt;/a&gt;. This contains all you need to start using Eclipse with
  PDT.
&lt;/p&gt;
&lt;p&gt;
  If you don&#039;t have Java Runtime Environment (JRE) 5 (or greater)
  installed, then you&#039;ll also need to download the latest &lt;a
  href=&quot;http://www.java.com/en/download/manual.jsp&quot;&gt;JRE&lt;/a&gt;.
&lt;/p&gt;

&lt;h2&gt;Getting started: Install&lt;/h2&gt;
&lt;p&gt;
  Start by installing the JRE, if you need it.
&lt;/p&gt;
&lt;p&gt;
  The Eclipse all-in-one package comes as a ZIP file. On Windows, you
  can extract the contents to C:&amp;#92;Program Files. This will create a
  folder called &quot;eclipse&quot;. For easy access, copy the eclipse.exe file
  in the folder and paste it as a shortcut on the desktop.
&lt;/p&gt;

&lt;h2&gt;Getting started: Configure&lt;/h2&gt;
&lt;p&gt;
  Start Eclipse by running the eclipse.exe file. This will ask you to
  select a &quot;workspace&quot;, a folder that will store a collection of your
  projects. You can have more than one workspace.
&lt;/p&gt;
&lt;p&gt;
  Eclipse will suggest a location for the workspace. If you&#039;re happy
  with it, click OK. On Windows, I would suggest using
  something like My Documents&amp;#92;Eclipse. If you don&#039;t intend to create
  multiple workspaces, select &quot;Use this as the default and do not ask
  again&quot; before clicking on OK (you can change your mind later).
&lt;/p&gt;
&lt;p&gt;
  Eclipse should appear and display the Welcome screen (you can return
  to the Welcome screen through the Help menu). Now I will introduce
  you to Eclipse&#039;s rather intimidating preferences system: select &lt;span
  class=&quot;navPath&quot;&gt;Window &amp;gt; Preferences&lt;/span&gt;. Under &lt;span
  class=&quot;navPath&quot;&gt;PHP &amp;gt; PHP Interpreter&lt;/span&gt;, select PHP 4 or 5.
&lt;/p&gt;
&lt;p&gt;
  There are many other options you will want to customize, but this is
  sufficient to get started. You&#039;ll return to this menu many times to
  tweak how Eclipse works.
&lt;/p&gt;

&lt;h2&gt;Getting started: Update&lt;/h2&gt;
&lt;p&gt;
  You should also become familiar with Eclipse&#039;s update system. Select
  &lt;span class=&quot;navPath&quot;&gt;Help &amp;gt; Software Updates &amp;gt; Find and
  Install &amp;gt; Search for updates of the currently installed features
  &amp;gt; Finish&lt;/span&gt;. Select a mirror or let Eclipse select one for you.
  Eclipse will now begin a rather slow search for updates. You can
  place the update dialog into the background and continue to work
  while the search takes place.
&lt;/p&gt;
&lt;p&gt;
  When Eclipse locates all the updates, a window will appear, showing
  you your update options. Select everything and begin the update.
  Once you have installed all updates, you may need to restart
  Eclipse. Your installation is now up-to-date.
&lt;/p&gt;
&lt;p&gt;
  The update method is also the way you add new features to Eclipse.
  Use &lt;span class=&quot;navPath&quot;&gt;Help &amp;gt; Software Updates &amp;gt; Find and
  Install&lt;/span&gt;, but this time select &quot;Search for new features to
  install&quot;. You&#039;ll be able to search for features on a collection of
  sites.
&lt;/p&gt;
&lt;p&gt;
  For example, let&#039;s say you use doxygen to generate your PHP
  documentation. You would click on &quot;New Remote Site&quot;, enter &quot;Eclox&quot; for
  the name and http://download.gna.org/eclox/update/ for the URL. This
  creates a new entry in the sites list.
&lt;/p&gt;
&lt;p&gt;
  You can visit &lt;a href=&quot;http://www.eclipseplugincentral.com/&quot;&gt;Eclipse
  Plugin Central&lt;/a&gt; to find additional plugins to install. But let&#039;s
  leave that for later.
&lt;/p&gt;

&lt;h2&gt;Creating a project for existing PHP code&lt;/h2&gt;
&lt;p&gt;
  Your Eclipse installation may coincide with the creation of a new
  PHP project, but it is more likely that you already have existing
  code you want to use within Eclipse. This is where most people get a
  little stuck&amp;mdash;if you know the magic incantation, the process is
  easy.
&lt;/p&gt;
&lt;p&gt;
  Let&#039;s say you have a PHP Web site at My Documents&amp;#92;Sample&amp;#92;Web Site and
  that you test the Web site using the local server address
  http://localhost/sample.
&lt;/p&gt;
&lt;p&gt;
  Fire up Eclipse and select &lt;span class=&quot;navPath&quot;&gt;File &amp;gt; New &amp;gt;
  PHP Project&lt;/span&gt;. Enter a project name. Disable the &lt;span
  class=&quot;navPath&quot;&gt;Project contents &amp;gt; Use default&lt;/span&gt; toggle and
  browse to the My Documents&amp;#92;Sample&amp;#92;Web Site folder. Click &lt;span
  class=&quot;navPath&quot;&gt;Next&lt;/span&gt;. The files in the My
  Documetns&amp;#92;Sample&amp;#92;Web Site folder are now part of an Eclipse project.
&lt;/p&gt;
&lt;p&gt;
  You probably also reference code through a PHP include path. Select
  &lt;span class=&quot;navPath&quot;&gt;Libraries &amp;gt; Add External Folder&lt;/span&gt; to
  include folders in your Web site&#039;s include path. Click &lt;span
  class=&quot;navPath&quot;&gt;Finish&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
  Our project now appears in Eclipse&#039;s PHP Explorer pane. Eclipse will
  place a .project file in the My Documents&amp;#92;Sample&amp;#92;Web Site folder,
  but your content is otherwise undisturbed. You are ready to use
  Eclipse. You can also continue to work on your code using your
  existing development tools.
&lt;/p&gt;

&lt;h2&gt;Editing with Eclipse&lt;/h2&gt;
&lt;p&gt;
  Using the PHP Explorer pane, you can double-click on a file and have
  it appear in Eclipse&#039;s editor pane. The features here are pretty
  standard, so I won&#039;t talk about them too much. You may want to
  return to the preferences dialog to customize the editing features.
&lt;/p&gt;
&lt;p&gt;
  One nice editor feature is called &quot;code assist&quot;. Eclipse will pop up
  various displays that offer documentation or auto-completion help.
  If the code assist popup doesn&#039;t appear automatically, you can call
  it with Ctrl + Space. One caveat: if you have enabled the Emacs key
  bindings, the magic sequence is Alt + /.
&lt;/p&gt;

&lt;h2&gt;Executing PHP&lt;/h2&gt;
&lt;p&gt;
  You can still run your Web pages by typing
  http://localhost/sample/some_page.php into your Web browser. But
  let&#039;s try running the page from eclipse.
&lt;/p&gt;
&lt;p&gt;
  First, some setup: Using &lt;span class=&quot;navPath&quot;&gt;Window &amp;gt;
  Preferences &amp;gt; PHP &amp;gt; PHP servers&lt;/span&gt;, we create a new
  server, Sample, with a URL of http://localhost/sample. If you would
  like to use your default browser, go to &lt;span
  class=&quot;navPath&quot;&gt;General &amp;gt; Web Browser&lt;/span&gt;, select &lt;span
  class=&quot;navPath&quot;&gt;Use external browser&lt;/span&gt; and enable &lt;span
  class=&quot;navPath&quot;&gt;Default system Web browser&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
  Open up your Web page in the editor. Select &lt;span
  class=&quot;navPath&quot;&gt;Run &amp;gt; Run As &amp;gt; PHP Web Page&lt;/span&gt;. In the
  dialog that appears, verify that the &lt;span class=&quot;navPath&quot;&gt;Launch
  URL&lt;/span&gt; is correct. The page will appear in your Web browser.
&lt;/p&gt;
&lt;p&gt;
  You may notice that the URL has many parameters attached to it.
  These are for coordinating with the debugger. This may be a bug in
  Eclipse since debug parameters should only be added when debugging a
  script.
&lt;/p&gt;
&lt;p&gt;
  Go to &lt;span class=&quot;navPath&quot;&gt;Run &amp;gt; Open Run Dialog&lt;/span&gt;. You&#039;ll
  see that you can create a &quot;run configuration&quot; that controls what
  happens when you select &lt;span class=&quot;navPath&quot;&gt;Run&lt;/span&gt;. For my
  &quot;sample&quot; project, I right-clicked on &lt;span class=&quot;navPath&quot;&gt;PHP Web
  Page&lt;/span&gt; and selected &lt;span class=&quot;navPath&quot;&gt;New&lt;/span&gt;. I set the
  debugger to XDebug, the PHP Server to Sample and the file to
  /Sample/index.php. On the &lt;span class=&quot;navPath&quot;&gt;Common&lt;/span&gt; tab, I
  toggled Run under &lt;span class=&quot;navPath&quot;&gt;Display in favorites
  menu&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
  Now I can run the index.php page by selecting the Run icon on the tool
  bar and then selecting the run configuration I created from the tool
  bar drop down. Using this method, the page appears without the
  debugging parameters attached.
&lt;/p&gt;
&lt;p&gt;
  As far as I can tell, you would have to create one run configuration
  per page. Or, as I pointed out earlier, you could just enter the
  page address directly in your browser and bypass Eclipse.
&lt;/p&gt;

&lt;h2&gt;Debugging PHP&lt;/h2&gt;
&lt;p&gt;
  If you have your system set up to use either the Zend debugger or
  XDebug, it&#039;s easy to debug with Eclipse.
&lt;/p&gt;
&lt;p&gt;
  Configuring PHP for debugging is beyond the scope of this article.
  The Eclipse portion of the setup involves using &lt;span
  class=&quot;navPath&quot;&gt;Run &amp;gt; Open Debug Dialog&lt;/span&gt; to get to a dialog
  very similar to the Run Dialog. Create a configuration for debugging
  index.php and enabled the Debug toggle on the Common tab.
&lt;/p&gt;
&lt;p&gt;
  On the tool bar, you can use the debug button drop-down to select your
  debug configuration. Normally, the debugger will break on the first
  line.
&lt;/p&gt;
&lt;p&gt;
  When you start debugging, Eclipse will offer to switch to the PHP
  Debug perspective, which will give you the right panes and controls
  to run the debugger.
&lt;/p&gt;

&lt;h2&gt;Additional resources&lt;/h2&gt;
&lt;p&gt;
  I hope these instructions give you a head start at using Eclipse for
  PHP. Here are some other places you may get assistance.
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Visit &lt;a
  href=&quot;http://www.eclipse.org/&quot;&gt;http://www.eclipse.org/&lt;/a&gt;, the home
  page of the Eclipse project.&lt;/li&gt;
  &lt;li&gt;Visit &lt;a
  href=&quot;http://wiki.eclipse.org/PDT/&quot;&gt;http://wiki.eclipse.org/PDT&lt;/a&gt;, the home
  page for PDT.&lt;/li&gt;
  &lt;li&gt;Visit &lt;a
  href=&quot;http://wiki.eclipse.org/PDT/FAQ&quot;&gt;http://wiki.eclipse.org/PDT/FAQ&lt;/a&gt; for a list of frequently asked questions about PDT.&lt;/li&gt;
  &lt;li&gt;Use &lt;span class=&quot;navPath&quot;&gt;Help &amp;gt; Help Contents&lt;/span&gt; and
  open up the &lt;span class=&quot;navPath&quot;&gt;PDT User Guide&lt;/span&gt; for the
  online manual.&lt;/li&gt;
&lt;/ul&gt;
</description>
 <comments>http://www.tigerheron.com/article/2008/01/eclipse-and-php#comments</comments>
 <category domain="http://www.tigerheron.com/category/eclipse">Eclipse</category>
 <category domain="http://www.tigerheron.com/category/ide">IDE</category>
 <category domain="http://www.tigerheron.com/category/php">PHP</category>
 <category domain="http://www.tigerheron.com/category/software-developers">software developers</category>
 <category domain="http://www.tigerheron.com/category/xdebug">XDebug</category>
 <pubDate>Wed, 09 Jan 2008 16:29:44 +0000</pubDate>
 <dc:creator>developer</dc:creator>
 <guid isPermaLink="false">92 at http://www.tigerheron.com</guid>
</item>
<item>
 <title>A Tale of Two Patterns</title>
 <link>http://www.tigerheron.com/article/2007/11/tale-two-patterns</link>
 <description>&lt;p&gt;
  Originally, I planned to write about how to configure the Apache
  server to run both PHP4 and PHP5. With the push toward PHP5 (see &lt;a
  href=&quot;http://gophp5.org/&quot;&gt;Go PHP5&lt;/a&gt;), there are now hundreds of
  articles covering that topic. Instead, I will talk about two IT
  patterns I use for PHP development on Windows. The patterns are
  ancient and familiar to most Unix developers, but little used in the
  Windows world.
&lt;/p&gt;
&lt;!--break--&gt;
&lt;p&gt;
  Since the patterns existed long before the term &amp;quot;design
  patterns&amp;quot; came into vogue, they don&amp;#39;t have any names that I am aware
  of. In this article, I will call them the &lt;em&gt;Bait-and Switch &lt;/em&gt;
  and the &lt;em&gt;Shell Game&lt;/em&gt; patterns.
&lt;/p&gt;
&lt;h2&gt;Junction points&lt;/h2&gt;
&lt;p&gt;
  On Unix, the Bait-and-Switch pattern is implemented using soft
  links. On Windows, the equivalent feature (at least for folders) is a
  junction point. Since this is an obscure feature for many Windows users, let me
  start by describing what junction points do and how to manage them.
&lt;/p&gt;
&lt;p&gt;
  Junction points can be used to assign the address of one directory to another.
  Once created, file operations performed on the junction point
  are actually forwarded to the linked directory. Essentially, you are
  reaching the same files through alternate file paths.
&lt;/p&gt;
&lt;p&gt;
  The concept is similar to a Windows &amp;quot;shortcut&amp;quot;, but
  shortcuts are limited in the number of file operations they support.
  Junction points are much better at &amp;quot;fooling&amp;quot; the operating
  system.
&lt;/p&gt;
&lt;p&gt;
  How do you create a junction point? Microsoft must feel that this
  feature is too confusing for most users as they omitted creating a
  user interface for it. I&amp;#39;ve been using a great open source tool: &lt;a
  href=&quot;http://sourceforge.net/projects/ntfslinkext&quot;&gt;NTFS Link&lt;/a&gt;,
  written originally by &lt;a href=&quot;http://www.elsdoerfer.info/&quot;&gt;Michael
  Elsdoerfer&lt;/a&gt; and now maintained on &lt;a
  href=&quot;http://sourceforge.net/&quot;&gt;SourceForge&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  I won&amp;#39;t go into the details of installing and configuring NTFS Link
  since there is plenty of information on Michael&amp;#39;s site. The only tip
  I&amp;#39;ll give is to take advantage of the icon overlays feature in the
  configuration dialog so that junction points are easy to see in an
  Explorer window. You won&amp;#39;t have any trouble spotting the junction points in my
  screen capture below.
&lt;/p&gt;
&lt;p&gt;
  I don&amp;#39;t believe NTFS Link will work on Vista, since Microsoft has
  introduced a replacement for junction points called &lt;a
  href=&quot;http://en.wikipedia.org/wiki/NTFS_symbolic_link&quot;&gt;NTFS symbolic
  links&lt;/a&gt;. These can point to files as well as folders, which is
  somewhat closer to the Unix soft link command. You can use the
  &amp;quot;mklink&amp;quot;  to create these links, but that&amp;#39;s quite a step
  down from the beautiful interface that NTFS Link provides.
&lt;/p&gt;
&lt;p&gt;
  One caveat, specially for Unix users on Windows: if you delete a
  junction point, you will also delete the files in the folder pointed
  to by the junction point. On Unix, deleting a soft link only removes
  the link. This is one reason why it&amp;#39;s important to ensure that
  junction points are easy to spot. The good news is that the NTFS
  Link package  intercepts folder deletions and implements the Unix
  behavior. This works only for the junction points it creates.
&lt;/p&gt;
&lt;p&gt;
  Folder copies can also pose problems, but NTFS Link helps us there
  as well. When you attempt to copy a junction point, it will ask
  whether you want to copy just the junction point or to copy it as
  they it were a real directory.
&lt;/p&gt;
&lt;h2&gt;The Bait-and-Switch pattern&lt;/h2&gt;
&lt;p&gt;
  To use the  Bait-and-Switch pattern, start by installing multiple versions
  of a software package. Each version is usually placed in a directory
  with the package and version as part of the name; for example,
  php-5.2.5-Win32. Then create a junction point to the
  version you want to use. Finally, have the rest of the system access the
  package through the junction point. Now, changing the package version is as
  easy as redirecting the junction point.
&lt;/p&gt;
&lt;p&gt;
  Junction points can be cascaded. For example, you could use
  &amp;quot;php&amp;quot; to point to the latest version of PHP. Then use
  &amp;quot;php4&amp;quot; and &amp;quot;php5&amp;quot; to point to the latest version
  of PHP 4 or 5. So &amp;quot;php&amp;quot; would point to &amp;quot;php5&amp;quot;
  which would point to the latest version of php5. When PHP 6 is
  released, &amp;quot;php&amp;quot; would change to point to &amp;quot;php6&amp;quot;,
  but &amp;quot;php5&amp;quot; would continue to point to the latest PHP 5
  version.
&lt;/p&gt;
&lt;h2&gt;The Shell Game pattern&lt;/h2&gt;
&lt;p&gt;
  The Shell Game pattern uses a different way of fooling the operating
  system. The idea is to run a program by first running a script that
  configures the program environment and then starts the program. If
  set up properly, the command you type to start the script can be the same
  as what you would normally type to start the program (e.g. typing &quot;php&quot; to
  start the CLI PHP program). On Unix, the script is usually a &lt;em&gt;sh&lt;/em&gt;
  (shell) script and thus my name for this pattern.
&lt;/p&gt;
&lt;p&gt;
  This pattern is not as useful on Windows as Bait-and-Switch because
  so many programs store their environment in the registry. Unix
  programs rely more on environment variables and command-line
  options. The registry is global and any change affects all versions
  of the running program. Environment variables and command-line
  options, however, can be set per-application, so that we can
  simultaneously run multiple copies of a program, each tailored to
  behave different from the others.
&lt;/p&gt;
&lt;p&gt;
  PHP uses environment variables and command-line options for its
  behavior, so the Shell Game pattern works well for it.
&lt;/p&gt;
&lt;p&gt;
  On Windows, you can write the script using any of a number of tools.
  A batch file should be sufficient, but I use &lt;a
  href=&quot;http://www.perl.org/&quot;&gt;Perl&lt;/a&gt;. Perl is fast and also provides
  a solution for properly starting a windowed application based on &lt;a
  href=&quot;http://gtk.php.net/&quot;&gt;PHP-GTK&lt;/a&gt;. You can get a version of
  Perl for Windows from &lt;a
  href=&quot;http://www.activestate.com/Products/activeperl/features.plex&quot;&gt;ActiveState&lt;/a&gt;.
  I use &lt;a
  href=&quot;http://www.indigostar.com/indigoperl.htm&quot;&gt;IndigoPerl&lt;/a&gt;, but
  it hasn&amp;#39;t been updated since early 2005.
&lt;/p&gt;
&lt;p&gt;
  Some Windows scripting tools are very slow, so be careful with your
  choice.
&lt;/p&gt;
&lt;h2&gt;Applying Bait-and-Switch to a PHP installation&lt;/h2&gt;
&lt;p&gt;
  Here&amp;#39;s a screen shot of my PHP installation.
&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;/files/blogs/developer/node91/tale-two-patterns-1.png&quot; alt=&quot;Explorer window screen shot showing my PHP installation&quot; width=&quot;234&quot; height=&quot;325&quot;&gt;&lt;/p&gt;
&lt;p&gt;
  I&amp;#39;ve installed PHP in C:&amp;#92;Program Files&amp;#92;php instead of C:&amp;#92;php. A few
  things to note:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The files with the large green arrows are junction points.&lt;/li&gt;
  &lt;li&gt;There are multiple PHP 4 and 5 installations as well as PHP-GTK. &lt;/li&gt;
  &lt;li&gt;The junction points point to one of the PHP 4, PHP 5 or PHP-GTK installations (typically, the latest, but it can be any version). &lt;/li&gt;
  &lt;li&gt;The &amp;quot;bin&amp;quot; directory is the only directory in the execution path.&lt;/li&gt;
  &lt;li&gt;There is one &amp;quot;pear&amp;quot; directory shared by all PHP versions. When I add a new PEAR package, all PHP versions have access to it. &lt;/li&gt;
  &lt;li&gt;There is one &amp;quot;php5-ext&amp;quot; directory where I place extensions that are independent of the PHP 5 version (currently, I have XCache and XDebug).&lt;/li&gt;
  &lt;li&gt;All the files needed to run PHP are stored in C:&amp;#92;Program Files&amp;#92;php. This includes the php.ini file. Each PHP version has one php.ini file, although I could also have had  one copy shared by all versions. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  Why did I configure PHP this way?
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;I was able to place PHP where I wanted it.&lt;/li&gt;
  &lt;li&gt;I was able to keep the php.ini file with the rest of the PHP installation. &lt;/li&gt;
  &lt;li&gt;I can easily switch from one version of PHP to another.&lt;/li&gt;
  &lt;li&gt;I can quickly install a new version of PHP without deleting my current version.&lt;/li&gt;
  &lt;li&gt;I need to maintain only one version of PEAR.&lt;/li&gt;
  &lt;li&gt;I can simultaneously run CLI versions of PHP 4, PHP 5 and PHP-GTK without any conflicts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  There may be other and better ways to achieve these goals, but this
  approach works well for me.
&lt;/p&gt;
&lt;h2&gt;Playing the  PHP Shell Game&lt;/h2&gt;
&lt;p&gt;
  My Bait-and-Switch configuration wouldn&amp;#39;t work without the support
  of the Shell Game pattern.
&lt;/p&gt;
&lt;p&gt;
  The first step is to place C:&amp;#92;Program Files&amp;#92;php&amp;#92;bin in the execution
  path (Control Panel &amp;gt; System &amp;gt; Advanced &amp;gt; Environment
  Variables). None of the PHP installations should be placed on the
  path.
&lt;/p&gt;
&lt;p&gt;
  Next, create a set of Shell Game scripts that will take the place of
  the php.exe, php-cgi.exe and php-win.exe. Since I use perl, I make
  the process easier by adding PL to the PATHEXT environment variable
  and then running a batch file that contains these two lines:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
assoc .pl=pl_auto_file
ftype pl_auto_file=&amp;quot;C:&amp;#92;indigoperlperl&amp;#92;bin&amp;#92;perl.exe&amp;quot; &amp;quot;%%1&amp;quot; %%*
&lt;/pre&gt;
&lt;p&gt;
  If you use ActivePerl, you will need to adjust the path to perl.
  Having done all the steps listed so far, you could now write a perl
  script called sample.pl, place it in the bin directory and execute
  it from any directory by typing &amp;quot;sample&amp;quot;. Because we need
  to ensure that the PATH and PATHEXT variables are properly inherited
  by all processes, you may want to log out and back in again.
&lt;/p&gt;
&lt;p&gt;
  Here&amp;#39;s the Perl script I use for the CLI version of PHP5:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
#!/usr/bin/perl
# Command line (CLI) PHP 5

our $phpMainDir = &quot;C:&amp;#92;&amp;#92;Program Files&amp;#92;&amp;#92;php&quot;;
our $phpDir = &quot;$phpMainDir&amp;#92;&amp;#92;php5&quot;;
our $phpBinDir = &quot;$phpDir&quot;;
our $phpExtDir  = &quot;$phpDir&amp;#92;&amp;#92;ext&quot;;
our $phpBin = &quot;$phpBinDir&amp;#92;&amp;#92;php.exe&quot;;
our $phpMibsDir = &quot;$phpDir&amp;#92;&amp;#92;extras&amp;#92;&amp;#92;mibs&quot;;
our $pearDir = &quot;$phpMainDir&amp;#92;&amp;#92;pear&quot;;
our $pearBin = &quot;$phpMainDir&amp;#92;&amp;#92;bin&amp;#92;&amp;#92;php5.pl&quot;;

$ENV{&amp;#39;PATH&amp;#39;} = $phpDir . &amp;#39;;&amp;#39; . $ENV{&amp;#39;PATH&amp;#39;};
$ENV{&amp;#39;MIBDIRS&amp;#39;} = $phpMibsDir;
$ENV{&amp;#39;PHP_PEAR_BIN_DIR&amp;#39;} = $pearDir;
$ENV{&amp;#39;PHP_PEAR_DATA_DIR&amp;#39;} = &quot;$pearDir&amp;#92;&amp;#92;pear&amp;#92;&amp;#92;data&quot;;
$ENV{&amp;#39;PHP_PEAR_DOC_DIR&amp;#39;} = &quot;$pearDir&amp;#92;&amp;#92;pear&amp;#92;&amp;#92;docs&quot;;
$ENV{&amp;#39;PHP_PEAR_INSTALL_DIR&amp;#39;} = &quot;$pearDir&amp;#92;&amp;#92;pear&quot;;
$ENV{&amp;#39;PHP_PEAR_PHP_BIN&amp;#39;} = $pearBin;
$ENV{&amp;#39;PHP_PEAR_SYSCONF_DIR&amp;#39;} = $pearDir;
$ENV{&amp;#39;PHP_PEAR_TEST_DIR&amp;#39;} = &quot;$pearDir&amp;#92;&amp;#92;pear&amp;#92;&amp;#92;tests&quot;;

system &quot;&amp;#92;&quot;$phpBin&amp;#92;&quot;&quot;, &quot;-c&quot;, $phpDir, @ARGV;
&lt;/pre&gt;
&lt;p&gt;
  The initial set of variable definitions set up a number of
  locations. The code is structured so that this is the only section
  that needs to be altered when creating CGI and CLI versions of PHP
  4, 5 or GTK. GTK has no CGI version, so there are five scripts
  total. If you&amp;#39;d like to see all five versions, you can get them from
  this &lt;a href=&quot;/files/downloads/PHP scripts.zip&quot;&gt;ZIP file&lt;/a&gt;
  (3KB).
&lt;/p&gt;
&lt;p&gt;
  We&amp;#39;re not done yet! If you want to run a CGI version of PHP in
  Apache, you can just point Apache at the appropriate script. If you
  want to run PHP as an Apache module, however, you will also need to use the
  Shell Game pattern for the Apache executable. Start with the same script as
  for the CGI version of PHP you want use, delete the last line and append these
  instead:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;
our $apache = 
  &amp;quot;C:&amp;#92;&amp;#92;Program Files&amp;#92;&amp;#92;Apache Software Foundation&amp;#92;&amp;#92;Apache2.2&amp;#92;&amp;#92;bin&amp;#92;&amp;#92;httpd.exe&amp;quot;;
system &amp;quot;&amp;quot;$apache&amp;quot;&amp;quot;, @ARGV;
&lt;/pre&gt;
&lt;p&gt;
  Save the result in a file called httpd.pl, place it in the Apache bin directory and
  change the Apache service to
  use &amp;quot;C:&amp;#92;indigoperlperl&amp;#92;bin&amp;#92;perl.exe&amp;quot; &amp;quot;C:&amp;#92;Program
  Files&amp;#92;Apache Software Foundation&amp;#92;Apache2.2&amp;#92;bin&amp;#92;httpd.pl&amp;quot; -k
  runservice. (I edited the entry by using a registry editor&amp;mdash;does anyone
  know a better way?).
&lt;/p&gt;
&lt;p&gt;
  Finally, if you want to run  some of the scripts in the pear
  directory (pear.bat, pecl.bat, phing.bat), you will need to modify
  the scripts to use the Perl scripts rather than directly calling the PHP
  executables. I&amp;#39;ll leave this as an exercise for the reader.
&lt;/p&gt;
&lt;p&gt;
  One caveat: there are some programs (such as IDEs) that will ask you
  for the location of your installed PHP. Then they get very clever
  and try to determine if you have a valid installation. Well, the
  installation is valid, but the program won&amp;#39;t be able to figure that
  out and will refuse to accept your choice. The solutions vary with
  the programs. Sometimes you can tell the program to set up an
  environment for the PHP subprocess. Sometimes you will need to write
  a Shell Game script for that tool. I haven&amp;#39;t encountered many of these types
  of problems and  haven&amp;#39;t found any that I couldn&amp;#39;t work around.
&lt;/p&gt;
</description>
 <comments>http://www.tigerheron.com/article/2007/11/tale-two-patterns#comments</comments>
 <category domain="http://www.tigerheron.com/category/design-patterns">design patterns</category>
 <category domain="http://www.tigerheron.com/category/perl">Perl</category>
 <category domain="http://www.tigerheron.com/category/php">PHP</category>
 <category domain="http://www.tigerheron.com/category/php-gtk">PHP-GTK</category>
 <category domain="http://www.tigerheron.com/category/unix">Unix</category>
 <pubDate>Wed, 28 Nov 2007 23:24:16 +0000</pubDate>
 <dc:creator>developer</dc:creator>
 <guid isPermaLink="false">91 at http://www.tigerheron.com</guid>
</item>
<item>
 <title>High-performance debugging</title>
 <link>http://www.tigerheron.com/article/2007/09/high-performance-debugging</link>
 <description>&lt;p&gt;
  In this article, I will show you how to use PHP 5 input filters to support
  debug, trace and assert statements so that a one-line change
  disables these statements and restores your script to full production
  performance.
&lt;/p&gt;
&lt;!--break--&gt;

&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;
  The typical debug statement looks like this:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;echo &lt;span class=&quot;str&quot;&gt;&quot;&amp;lt;p&amp;gt;Hello, I am a debug statement&amp;lt;/p&amp;gt;&quot;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  This is the workhorse of PHP debugging—at least, when we aren&#039;t
  using a debugger. We insert it as needed and remove it when done.&lt;/p&gt;
&lt;p&gt;
  Sometimes the debug code takes some work to produce or has some
  permanent benefits. The easiest way to preserve it is by placing it
  in a comment:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;// echo &lt;span class=&quot;str&quot;&gt;&quot;&amp;lt;p&amp;gt;Hello, I am a complicated debug statement&amp;lt;/p&amp;gt;&quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  This can be inconvenient if we  frequently need to enable
  debugging or if we need to enable multiple debug statements. So the
  next variation is to enable debug statements based on a flag:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; ($debugEnabled) echo &lt;span class=&quot;str&quot;&gt;&quot;&amp;lt;p&amp;gt;Hello, I am a debug statement&amp;lt;/p&amp;gt;&quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  Now, we can turn a number of debug statements on or off with a single
  setting. But we&#039;ve also added some overhead that occurs even when
  the debug statements are disabled. We have also added some extra
  typing that will make us less inclined to use this tool.&lt;/p&gt;
&lt;p&gt;
  You can gain some flexibility by using:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;debug(&lt;span class=&quot;str&quot;&gt;&quot;Hello, I am a debug statement&quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  This opens the door to creating an elaborate debug system, but adds a performance penalty. Not only do we have the overhead of the function call, but the function argument is evaluated each time
  the statement is executed, whether debugging is enabled or not.
  We&#039;re back to:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; ($debugEnabled) debug(&lt;span class=&quot;str&quot;&gt;&quot;Hello, I am a debug statement&quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  PHP provides an&lt;span class=&quot;code&quot;&gt; &lt;a
  href=&quot;http://php.net/manual/en/function.assert.php&quot;&gt;assert()&lt;/a&gt;&lt;/span&gt;
  function which helps check program logic and can be disabled in
  php.ini. This function could be subverted to serve as the base for a
  debug system, but it appears to function much like the &lt;span
  class=&quot;code&quot;&gt;debug&lt;/span&gt; function above, at least in PHP 5.2.4. &lt;/p&gt;
&lt;p&gt;
  For code that services thousands of requests per hour, the small
  overhead of these debug statements is significant and they are
  rarely left in place.&lt;/p&gt;

&lt;h2&gt;Why use debug statements?&lt;/h2&gt;
&lt;p&gt;Before going further, I need to answer the obvious question: why not use debuggers, profilers or other tools instead of debug statements? &lt;/p&gt;
&lt;p&gt;The answer is that it&#039;s not an either-or; each tool has its place. Debug statements are sometimes faster to use or provide information that is easier to understand. For example, the ability to easily  trace all  database queries and send the output to a log file might be more effective in resolving some problems than stepping through the code with a debugger. &lt;/p&gt;
&lt;p&gt;
  The debug system I will present to you has these goals:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It should support debug, trace and assert statements.&lt;/li&gt;
  &lt;li&gt;It should be easily and completely disabled for production code.&lt;/li&gt;
  &lt;li&gt;It should be easy to enter debug statements. &lt;/li&gt;
  &lt;/ul&gt;

&lt;h2&gt;Setting the stage&lt;/h2&gt;
&lt;p&gt;
  Let me start with the three simple debugging classes I will use in
  this article. Each class name is prefixed with &quot;th&quot; for &quot;Tiger
  Heron&quot;.&lt;/p&gt;
&lt;p&gt;
  The first is the &lt;span class=&quot;code&quot;&gt;thDebug &lt;/span&gt;class, which
  allows us to format the output appropriately for Web or CLI use:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thDebug
{
    static public function debug($msg)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (php_sapi_name() == &lt;span class=&quot;str&quot;&gt;&#039;cli&#039;&lt;/span&gt;) echo $msg . &lt;span class=&quot;str&quot;&gt;&quot;n&quot;&lt;/span&gt;;
        &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; echo &lt;span class=&quot;str&quot;&gt;&#039;&amp;lt;p&amp;gt;&#039;&lt;/span&gt; . nl2br($msg) . &lt;span class=&quot;str&quot;&gt;&#039;&amp;lt;/p&amp;gt;&#039;&lt;/span&gt;;
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  The second class is thTrace. Tracing can be enabled or disabled, and
  you can set a threshold for the level of messages that are
  displayed.&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thTrace
{
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $isEnabled = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $level = 0;

    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function enable($isEnabled) { self::$isEnabled = $isEnabled; }
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function isEnabled() { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; self::$isEnabled; }
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function setLevel($level) { self::$level = $level; }

    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function trace($msg, $level = 0)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (self::$isEnabled &amp;amp;&amp;amp; $level &amp;lt;= self::$level) {
            thDebug::debug($msg);
        }
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  The  final debug class is thAssert, which generates an message only
  if an assertion fails. The &quot;precondition&quot; and &quot;postcondition&quot;
  methods are aliases for assert. Assertions, like tracing, can be enabled or disabled at run-time. &lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thAssert
{
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $isEnabled = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;

    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function enable($isEnabled) { self::$isEnabled = $isEnabled; }
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function isEnabled() { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; self::$isEnabled; }
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function assert($cond, $file, $line, $title=&lt;span class=&quot;str&quot;&gt;&#039;Assertion&#039;&lt;/span&gt;)
        { &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!$cond) thDebug::debug(&lt;span class=&quot;str&quot;&gt;&quot;$title failed! $file:$line&quot;&lt;/span&gt;);  }
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function precondition($cond, $file, $line)
       { self::assert($cond, $file, $line, &lt;span class=&quot;str&quot;&gt;&#039;Precondition&#039;&lt;/span&gt;); }
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function postcondition($cond, $file, $line)
      { self::assert($cond, $file, $line, &lt;span class=&quot;str&quot;&gt;&#039;Postcondition&#039;&lt;/span&gt;); }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To enable the entire debug system, we use: &lt;/p&gt;
&lt;div&gt;
 &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thDebugManager
{
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $isEnabled = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $isFilterRegistered = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;

    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function enable($isEnabled)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!$isFilterRegistered &amp;amp;&amp;amp; $isEnabled) {
            require &lt;span class=&quot;str&quot;&gt;&#039;thDebugFilter.inc&#039;&lt;/span&gt;;
            $isFilterRegistered = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
        }
        self::$isEnabled = $isEnabled;
    }

    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function isEnabled() { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; self::$isEnabled; }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The references to the filter are explained in the next section. It might seem to make more sense to place this code in the thDebug class, but we want to avoid loading any debug-related classes when they are not used. The &lt;span class=&quot;code&quot;&gt;thDebugManager&lt;/span&gt; contains the minimum amount of code that we must load all the time.&lt;/p&gt;
&lt;h2&gt;PHP input filters&lt;/h2&gt;
&lt;p&gt;
  We&#039;ll now introduce the key PHP 5 feature we&#039;ll use for our
  solution: the input filter. We will create a filter that will
  transform PHP code as it is loaded, essentially acting as a
  dynamic pre-processor.&lt;/p&gt;
&lt;p&gt;
  I started with some code from Adam Trachtenberg&#039;s book, &lt;em&gt;&lt;a
  href=&quot;http://www.amazon.com/gp/product/0596006365?ie=UTF8&amp;amp;tag=tigerheron-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596006365&quot;&gt;Upgrading
  to PHP 5&lt;/a&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; alt=&quot;&quot;
  src=&quot;http://www.assoc-amazon.com/e/ir?t=tigerheron-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0596006365&quot;
  border=&quot;0&quot;&gt;&lt;/em&gt;, and tweaked it a bit to create a reusable abstract
  class. To create a new filter, simply subclass this class and
  implement the missing function.&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thAbstractStreamFilter
    extends php_user_filter
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $data;
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; $bucket;

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function onCreate()
    {
        $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data = &lt;span class=&quot;str&quot;&gt;&#039;&#039;&lt;/span&gt;;
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function filter($&lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt;, $&lt;span class=&quot;kwrd&quot;&gt;out&lt;/span&gt;, &amp;amp;$consumed, $closing)
    {
        &lt;span class=&quot;kwrd&quot;&gt;while&lt;/span&gt; ($bucket = stream_bucket_make_writeable($&lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt;)) {
            $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data .= $bucket-&amp;gt;data;
            $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;bucket = $bucket;
            $consumed = 0;
        }

        $consumed += strlen($&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data);
        $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data = $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;filterData($&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data);
        $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;bucket-&amp;gt;data = $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data;
        $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;bucket-&amp;gt;datalen = strlen($&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data);
        stream_bucket_append($&lt;span class=&quot;kwrd&quot;&gt;out&lt;/span&gt;, $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;bucket);
        $&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;-&amp;gt;data = &lt;span class=&quot;str&quot;&gt;&#039;&#039;&lt;/span&gt;;
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; PSFS_PASS_ON;
    }

    &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function filterData($data);
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  I&#039;ll refer you to Adam&#039;s book for the details on input filters.&lt;/p&gt;

&lt;h2&gt;The Debug filter&lt;/h2&gt;
&lt;p&gt;
  Using the &lt;span class=&quot;code&quot;&gt;thAbstractStreamFilter &lt;/span&gt;class, I
  can finally create the core of my debug solution, the &lt;span
  class=&quot;code&quot;&gt;thDebugFilter&lt;/span&gt;:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thDebugFilter
    extends thAbstractStreamFilter
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function filterData($data)
    {
        $data =
            preg_replace(
                &lt;span class=&quot;str&quot;&gt;&#039;!//CODEs*([^nr]*)!m&#039;&lt;/span&gt;,
                &lt;span class=&quot;str&quot;&gt;&#039;$1&#039;&lt;/span&gt;, $data);
        $data =
            preg_replace(
                &lt;span class=&quot;str&quot;&gt;&#039;!//DBGs*([^nr]*)!m&#039;&lt;/span&gt;,
                &lt;span class=&quot;str&quot;&gt;&#039;thDebug::debug($1);&#039;&lt;/span&gt;, $data);
        $data =
            preg_replace(
                &lt;span class=&quot;str&quot;&gt;&#039;!//TRACEs*([^nr]*)!m&#039;&lt;/span&gt;,
                &lt;span class=&quot;str&quot;&gt;&#039;if (thTrace::isEnabled()) thTrace::trace($1);&#039;&lt;/span&gt;, $data);
        $data =
            preg_replace(
                &lt;span class=&quot;str&quot;&gt;&#039;!//ASSERTs*([^nr]*)!m&#039;&lt;/span&gt;,
                &lt;span class=&quot;str&quot;&gt;&#039;if (thAssert::isEnabled()) &#039;&lt;/span&gt; .
                &lt;span class=&quot;str&quot;&gt;&#039;thAssert::assert($1, __FILE__, __LINE__);&#039;&lt;/span&gt;, $data);
        $data =
            preg_replace(
                &lt;span class=&quot;str&quot;&gt;&#039;!//PRECONDs*([^nr]*)!m&#039;&lt;/span&gt;,
                &lt;span class=&quot;str&quot;&gt;&#039;if (thAssert::isEnabled()) &#039;&lt;/span&gt; .
                &lt;span class=&quot;str&quot;&gt;&#039;thAssert::precondition($1, __FILE__, __LINE__);&#039;&lt;/span&gt;, $data);
        $data =
            preg_replace(
                &lt;span class=&quot;str&quot;&gt;&#039;!//POSTCONDs*([^nr]*)!m&#039;&lt;/span&gt;,
                &lt;span class=&quot;str&quot;&gt;&#039;if (thAssert::isEnabled()) &#039;&lt;/span&gt; .
                &lt;span class=&quot;str&quot;&gt;&#039;thAssert::postcondition($1, __FILE__, __LINE__);&#039;&lt;/span&gt;, $data);

        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; $data;
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  I&#039;ve introduced some special &amp;quot;keywords&amp;quot; to PHP: &lt;span
  class=&quot;code&quot;&gt;//CODE&lt;/span&gt;, &lt;span class=&quot;code&quot;&gt;//DBG&lt;/span&gt;, &lt;span
  class=&quot;code&quot;&gt;//TRACE&lt;/span&gt;, &lt;span class=&quot;code&quot;&gt;//ASSERT&lt;/span&gt;,
  &lt;span class=&quot;code&quot;&gt;//PRECOND&lt;/span&gt; and &lt;span
  class=&quot;code&quot;&gt;//POSTCOND&lt;/span&gt;. When the filter is not used, these
  all look like PHP comments. When the filter is enabled, each of
  these statements is transformed into live code.&lt;/p&gt;
&lt;p&gt;
  You could do everything  with //&lt;span class=&quot;code&quot;&gt;CODE&lt;/span&gt;. This
  is used to hide or expose any arbitrary line of code. The other
  statements reduce the typing needed to use the debug classes.&lt;/p&gt;
&lt;p&gt;Here are some examples and their translations &lt;/p&gt;
&lt;div&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;rem&quot;&gt;//CODE $x = $x + 10; 
  -&amp;gt; $x = $x + 10;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;//DBG &quot;This is a debug statement.&quot;&lt;/span&gt;
  -&amp;gt; thDebug::debug(&amp;quot;This is a statement.&amp;quot;);
&lt;span class=&quot;rem&quot;&gt;//TRACE &quot;Level 4 message&quot;, 4&lt;/span&gt;
  -&amp;gt; if (thTrace::isEnabled()) thTrace::trace(&amp;quot;Level 4 message&amp;quot;, 4, __FILE__, _LINE__);
&lt;span class=&quot;rem&quot;&gt;//ASSERT $x == 10&lt;/span&gt;
  -&amp;gt; if (thAssert::isEnabled()) thAssert::assert($x == 10, __FILE__, __LINE__);
&lt;span class=&quot;rem&quot;&gt;//PRECOND $data == null&lt;/span&gt;
  -&amp;gt; if (thAssert::isEnabled()) thAssert::precondition($x == 10, __FILE__, __LINE__);
//POSTCOND $data != null
  -&amp;gt; if (thAssert::isEnabled()) thAssert::postcondition($x == 10, __FILE__, __LINE__);
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  Before using an input filter, we have to register it. The following
  line does the job:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;stream_filter_register(&lt;span class=&quot;str&quot;&gt;&#039;phpCode.thDebug&#039;&lt;/span&gt;,&lt;span class=&quot;str&quot;&gt;&#039;thDebugFilter&#039;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;

&lt;h2&gt;Tying it all together with __autoload&lt;/h2&gt;
&lt;p&gt;Now that we have the filter, how do we use it? Here is one way: &lt;/p&gt;
&lt;div&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;function thRequire($file)
{
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (thDebugManager::isEnabled()) {
        require &lt;span class=&quot;str&quot;&gt;&#039;php://filter/read=phpCode.thDebug/resource=&#039;&lt;/span&gt; . $file;
    }
    &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; {
        require $file;
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You would call &lt;span class=&quot;code&quot;&gt;thRequire()&lt;/span&gt; in place of any require statement. You would need similar methods for &lt;span class=&quot;code&quot;&gt;require_once&lt;/span&gt;, &lt;span class=&quot;code&quot;&gt;include&lt;/span&gt; and &lt;span class=&quot;code&quot;&gt;include_once&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I prefer using anothe PHP 5 feature, the &lt;span class=&quot;code&quot;&gt;__autoload()&lt;/span&gt; method. It  allows us to
  dispense with most &lt;span class=&quot;code&quot;&gt;include&lt;/span&gt; and &lt;span class=&quot;code&quot;&gt;require&lt;/span&gt; statements, at least for
  classes. When a class is needed but not defined, the  function
  registered with &lt;span class=&quot;code&quot;&gt;__autoload &lt;/span&gt;will be given a
  chance to load the class. Most of my code is objected-oriented, so this works well for me.&lt;/p&gt;
&lt;p&gt;
  Here is the &lt;span class=&quot;code&quot;&gt; &lt;/span&gt;class that that handles class
  loading. For this article, I have deliberately created a very basic autoloader: it assumes that the class name maps to a file with an &amp;quot;inc&amp;quot; extension and exists in the include path. &lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; thAutoload
{
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; function load($className)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (thDebugManager::isEnabled()) {
            require
                &lt;span class=&quot;str&quot;&gt;&#039;php://filter/read=phpCode.thDebug/resource=&#039;&lt;/span&gt; .
                $className . &lt;span class=&quot;str&quot;&gt;&#039;.inc&#039;&lt;/span&gt;;
        }
        &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; {
            require $className . &lt;span class=&quot;str&quot;&gt;&#039;.inc&#039;&lt;/span&gt;;
        }
        return true;
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
  I still need to register my autoload handler with  &lt;span
  class=&quot;code&quot;&gt;__autoload()&lt;/span&gt;, but that would be bad
  style. There&#039;s only room for one &lt;span
  class=&quot;code&quot;&gt;__autoload()&lt;/span&gt; method, so to allow sharing with other packages, I use
  &lt;span class=&quot;code&quot;&gt;spl_autoload_register()&lt;/span&gt; instead:&lt;/p&gt;
&lt;div&gt;
  &lt;pre class=&quot;csharpcode&quot;&gt;spl_autoload_register(array(&lt;span class=&quot;str&quot;&gt;&#039;thAutoload&#039;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&#039;load&#039;&lt;/span&gt;));&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If we were really using other autoloaders, we should also check if the file exists and return false if it doesn&#039;t, so as to give other autoloaders a chance to try loading the class. &lt;/p&gt;
&lt;p&gt;In any case, all the pieces are present and the solution is complete:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;span class=&quot;code&quot;&gt;thAutoload&lt;/span&gt; and &lt;span class=&quot;code&quot;&gt;thDebugManager&lt;/span&gt; must be loaded with a normal &lt;span class=&quot;code&quot;&gt;require&lt;/span&gt; or &lt;span class=&quot;code&quot;&gt;include&lt;/span&gt;. &lt;/li&gt;
  &lt;li&gt;To enable debugging, call &lt;span class=&quot;code&quot;&gt;thDebugManager::enable(true)&lt;/span&gt; before loading any  classes containing debug statements. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;So how well does it perform?&lt;/h2&gt;
&lt;p&gt;
  One way to see if I achieved my goals is to itemize all the overhead
  imposed by the debugging system &lt;em&gt;when it is disabled&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The compiler will have to compile the &lt;span
  class=&quot;code&quot;&gt;thDebugManager &lt;/span&gt;class.&lt;/li&gt;
  &lt;li&gt;The &lt;span class=&quot;code&quot;&gt;thAutoload &lt;/span&gt;class also a small bit of code that is compiled but not used. &lt;/li&gt;
  &lt;li&gt;One &lt;span class=&quot;code&quot;&gt;if&lt;/span&gt; statement and a function call is executed per loaded
  class.&lt;/li&gt;
  &lt;li&gt;The compiler has to discard some extra comment lines.&lt;/li&gt;
  &lt;/ul&gt;
&lt;p&gt;To me, the overhead appears acceptably low. However, for the highest performing scripts, where you count nanoseconds, this is still not good enough. Here are options for increasing performance:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Using &lt;span class=&quot;code&quot;&gt;__autoload()&lt;/span&gt; is slightly slower than direct loads, so the scripts could use &lt;span class=&quot;code&quot;&gt;thRequire()&lt;/span&gt;. &lt;/li&gt;
  &lt;li&gt;The &lt;span class=&quot;code&quot;&gt;thDebugManager&lt;/span&gt; can make the &lt;span class=&quot;code&quot;&gt;$isEnabled&lt;/span&gt; variable public—bad OO style, but it eliminates a function call. &lt;/li&gt;
  &lt;li&gt;Need more speed? Comment out the unused parts of thRequire(). This involves changing a few lines, but it is far easier than commenting out all the debug statements, which is what you would be doing if you used debug statement in the typical fashion.&lt;/li&gt;
  &lt;li&gt;Need even more? Edit all thRequires into straight requires. If we&#039;re talking high-performance scripts, you shouldn&#039;t have very many of these anyway. While this is not very convenient, you can enable a lot of debugging capability with a few edits.&lt;/li&gt;
  &lt;li&gt;Finally, use an opcode cache. This eliminates all compiler overhead. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Getting the code&lt;/h2&gt;
&lt;p&gt;
  I&#039;ve put all the code together in a ZIP file, along with a sample
  sorting class that uses the debugging features and a main program
  that can be run using the command-line version of PHP.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/files/downloads/high-performance-debugging.zip&quot;&gt;Download high-performance-debugging.zip&lt;/a&gt; ( 7KB) &lt;/p&gt;
&lt;h2&gt;Where to go from here&lt;/h2&gt;
&lt;p&gt;
  The ability to trasnform code dynamically opens up a lot of pre-processing
  possibilities: how about running the code through the C pre-processor? Or a macro processor like m4? Or even adding new syntax to the PHP language? I&#039;ll explore some options in later articles.&lt;/p&gt;
&lt;h2&gt;A special request for opcode cache developers &lt;/h2&gt;
&lt;p&gt;The extra filter processing creates  undesirable overhead that could be easily eliminated with an opcode cache, but it is unclear how many opcode caches support input filters. The dynamic nature of input filters make it almost impossible to determine when the cached code needs to be updated (after all, I could create a filter where the generated code would vary depending on the time of day) and this could discourage developers from adding suport.&lt;/p&gt;
&lt;p&gt;I hope instead that the developers will provide some way of enabling this capability with the caveat that the user must manage the cache, either manually or programmatically. Without some caching support, there is a limited future for using this technique in production code. &lt;/p&gt;
</description>
 <comments>http://www.tigerheron.com/article/2007/09/high-performance-debugging#comments</comments>
 <category domain="http://www.tigerheron.com/category/assert">assert</category>
 <category domain="http://www.tigerheron.com/category/autoload">autoload</category>
 <category domain="http://www.tigerheron.com/category/debugging">debugging</category>
 <category domain="http://www.tigerheron.com/category/input-filters">input filters</category>
 <category domain="http://www.tigerheron.com/category/opcode-caches">opcode caches</category>
 <category domain="http://www.tigerheron.com/category/performance">performance</category>
 <category domain="http://www.tigerheron.com/category/php">PHP</category>
 <category domain="http://www.tigerheron.com/category/software-developers">software developers</category>
 <category domain="http://www.tigerheron.com/category/trace">trace</category>
 <pubDate>Mon, 17 Sep 2007 03:14:32 +0000</pubDate>
 <dc:creator>developer</dc:creator>
 <guid isPermaLink="false">88 at http://www.tigerheron.com</guid>
</item>
<item>
 <title>In the beginning...</title>
 <link>http://www.tigerheron.com/article/2007/09/beginning</link>
 <description>&lt;p&gt;
  Welcome to the first of a series of PHP articles. I hope to present
  you with useful tips, novel ideas, and code you can use or adapt. My
  reward will be learning more about PHP, both from researching the
  articles and from the suggestions and criticism you offer.
&lt;/p&gt;
&lt;!--break--&gt;
&lt;p&gt;
  All my PHP articles will use PHP 5 as a base. Many will focus on OO
  programming and PHP performance, two topics I hope will generate
  lively discussions.
&lt;/p&gt;
&lt;p&gt;
  Many of the articles will include some working code. The code is
  provided under a Creative Commons license, and may be used in
  commercial and non-commercial works with attribution. I ask that you
  not sell the code except when embedded as part of a larger system.
&lt;/p&gt;
&lt;p&gt;
  Here&#039;s a list of the articles I plan to write. I will update it as I
  go. If any of these topics sounds interesting, subscribe to my
  developers&#039; feed now to ensure you receive the article when it comes
  out.
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/article/2007/09/high-performance-debugging&quot;&gt;High-performance debugging&lt;/a&gt;*&lt;br&gt;

    &lt;em&gt;In support of the goPHP5 movement (and to start this series
    with a bang), I&#039;ll show you how to include debug statements in 
    production code with no overhead. The  technique can be extended to 
    support dynamic pre-processing.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;/article/2007/11/tale-two-patterns&quot;&gt;A Tale of Two Patterns&lt;/a&gt;&lt;br&gt;

    &lt;em&gt;Using junction points and Perl, I&#039;ll show you how to easily
    manage multiple PHP installations on Windows, including multiple
    versions of PHP 4, PHP 5 and PHP GTK.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/article/2008/01/eclipse-and-php&quot;&gt;
    Eclipse and PHP&lt;/a&gt;&lt;br&gt;
    &lt;em&gt;Create, edit and test PHP with the Eclipse 3.3 IDE.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;/article/2008/03/first-steps-php-booting-script-part-1&quot;&gt;First steps with PHP&amp;mdash;booting a script, Part 1&lt;/a&gt;&lt;br&gt;
    &lt;a href=&quot;/article/2008/04/first-steps-php-booting-script-part-2&quot;&gt;First steps with PHP&amp;mdash;booting a script, Part 2&lt;/a&gt;&lt;br&gt;
    &lt;em&gt;Learn how to get PHP scripts going in a flexible and efficient way.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Autoload: the good, the bad and the ugly&lt;br&gt;
    &lt;em&gt;The first in a set of articles introducing PHP 5&#039;s
    __autoload() method.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Autoload: Using class loaders*&lt;br&gt;

    &lt;em&gt;Following up on the previous article, I&#039;ll discuss the
    contentious topic&amp;nbsp; of class loaders.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Autoload: Overcoming session problems&lt;br&gt;

    &lt;em&gt;Mixing __autoload() and sessions spells &quot;trouble&quot;. I&#039;ll cover
    one possible solution.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Extending PHP syntax by using streams*&lt;br&gt;

    &lt;em&gt;This article returns to territory covered by my first article
    and suggests ways in which the PHP language can be easily extended
    by using streams.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    How much performance do you really need?*&lt;br&gt;

    &lt;em&gt;To achieve maximum PHP performance you may have to sacrifice
    some coding flexibility. Should you?&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Short and sweet: compression&lt;br&gt;

    &lt;em&gt;How to compress for bandwidth savings.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Increase performance through caching&lt;br&gt;

    &lt;em&gt;How to benefit from server and browser caching.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    PHP and CSS*&lt;br&gt;

    &lt;em&gt;Does it make sense to use PHP code in your CSS? Can you do it
    without sacrificing performance?&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Database classes that make your life easier&lt;br&gt;

    &lt;em&gt;This topic could easily become a set of articles. Can we
    improve on the mysqli library? How well do high-level database
    classes perform?&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Iterators you can use&lt;br&gt;

    &lt;em&gt;PHP 5 comes with a basic set of iterator classes. Here are
    some extensions.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Components*&lt;br&gt;

    &lt;em&gt;I&#039;ll present my Component classes and ask: fantastic building
    blocks or huge performance drain?&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    An OO approach to forms and wizards&lt;br&gt;

    &lt;em&gt;I lose tons of time developing forms and wizards. Here&#039;s my
    OO-approach to making their creation easier.&lt;/em&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Opcode caching: the manual&lt;br&gt;

    &lt;em&gt;I don&#039;t know what I&#039;ll write, but I know this is an article I&#039;d like to read!&lt;/em&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  I hope you&#039;ll visit and contribute your ideas. Subscribe now!
&lt;/p&gt;
&lt;p style=&quot;font-size: smaller&quot;&gt;
* Unusual topics that should lead to some great debates.
&lt;/p&gt;
</description>
 <comments>http://www.tigerheron.com/article/2007/09/beginning#comments</comments>
 <category domain="http://www.tigerheron.com/category/php">PHP</category>
 <category domain="http://www.tigerheron.com/category/software-developers">software developers</category>
 <pubDate>Sun, 16 Sep 2007 02:11:02 +0000</pubDate>
 <dc:creator>developer</dc:creator>
 <guid isPermaLink="false">87 at http://www.tigerheron.com</guid>
</item>
</channel>
</rss>
