PHP Archive

The Singleton Chapter

Posted 5/26/2005 By Jason

I was reviewing the editing of the Singleton chapter last night. It was kind of interesting to look it over again, as I originally wrote, and had the tech review performed, on this chapter back in December of 2004! Looking it over again I am pretty proud of the decisions I made in writing it. One important decision was to not make the Singleton pattern the first design pattern explained in the book. The actual sequence of chapters up to this point is:

  1. Preface
  2. Programming Practices
  3. The ValueObject Pattern
  4. The Factory Pattern
  5. The Singleton Pattern

So the Singleton pattern is the third pattern covered in the book. The Programming Practices chapter gave me a chance to introduce Unit Testing and Refactoring, which is very important considering the heavy use of SimpleTest throughout the rest of the book for unit tests of the code. As I mentioned in an earlier blog entry, the unit tests are not just included in the code download, but integrated directly into the prose and flow of each chapter. The ValueObject pattern discussion gave me a chance to review references in PHP4 and object handles in PHP5 in much greater detail, and doing FactoryMethod next lets me allude to the fact that the Singleton is essentially a specialized Factory which only returns a single instance of a class.

In the book I try to give equal coverage to PHP4 and PHP5, but this particular chapter I spend much more time with PHP4 examples, as having private constructors in PHP5 make implementing the pattern relatively easy. I cover several possible implementations, and highlight the fact that the Zend 1 engine does not store references in static variables (as noted in the manual).

I briefly cover the MonoState pattern here as well, since they end up exhibiting similar behaviors, and you can do some neat code with reference —non-object related references!—to implement the MonoState pattern.

Book Update

Posted 5/24/2005 By Jason

This post is just a quick update on the status of my book, PHP Architect’s Guide to PHP Design Patterns. Marco fired himself as editor…because he found a more suitable replacement. We are still kicking through the editing review and are about 20% of the way through the book, and are trying to process around one chapter a day. This is the final pass before layout.

As I understand it, the book will be available in PDF on the php|architect site very quickly after it has been through l lay out. The turnaround time for the print runs is minimal as well. To the best of my knowledge, we are still targeting June for having it available.

Marco has been hot on my tail with regards to some ideas to market the book. Keep tuned here for further information on this subject :)

Just the Facts Ma’m

Posted 5/18/2005 By Jason

What does a PHP geek do when confronted with the task of generating practice math problems for his eight year old daughter? Script it, of course. Madeline wanted to practice addition, so she gave me a crayon and told me to write down 100 math problems consisting of adding two single digit numbers.

A “better” solution lept to mind immediatly:

A class to store and render a “fact”:

<?php

class Fact {
    protected $top;
    protected $bottom;
    
    public function __construct($t, $b) {
        $this->top = $t;
        $this->bottom = $b;
    }
    
    public function render() {
        return '&nbsp;'.$this->top."\n<u>+".$this->bottom.'</u>&nbsp;';
    }
}

?>

Generate some facts and store them in an array:

<?php

$facts = array();

foreach(range(0,9) as $top) {
    foreach(range(0,9) as $bottom) {
        $facts[] = new Fact($top, $bottom);
    }
}

?>

Make sure they are in random order:

<?php

shuffle($facts);

?>

and render them into a table for easy layout (what can I say, it was a two minute hack):

<?php

echo '<table border="0" cellpadding="9">';

foreach(range(0,9) as $tens) {
    echo '<tr>';
        foreach(range(0,9) as $ones) {
            echo '<td>', $facts[$tens*10+$ones]->render(), '</td>';
        }
    echo '</tr>';
}
echo '</tr></table>';

?>

fresh, randomly ordered fact sheet ready for printing.

Here is the Test Driven Development in PHP presentation from php|tropics. You can download either the zip or tarball flavors. In each is the PowerPoint presentation and the code files with unit tests I used when writing the presentation.

This presentation also went well. I went out on a bit of a limb and did some TDD live for about 45 minutes near the end of the session. We all decided to work on a MySQL driven Guestbook. Since there were about 30 or so people who were willing to hang around for 20 extra minutes while we finished the example up, I think that is a pretty good testament to the presentation, particularly considering the beautiful Cancun sun which was minutes away from all the dedicated attendees.

Here is the Design Patterns in PHP5 presentation from php|tropics. You can download either the zip or tarball flavors. In each is the PowerPoint presentation and the code files with unit tests I used when writing the presentation.

I felt this talk went fairly well, particularly considering it was in the same time slot as part two fo Chris Shiflett’s Security presentation (which we all know how that one drew a crowd at php|works in Toronto last fall).

Breaking the Silence

Posted 5/2/2005 By Jason

Long time, no posts. I have been very busy writing my PHP Design Patterns book, and have left little time for (self|family|blogging|other activities).

First of all, every chapter of the book is done!! Every chapter had to be written, sent to tech review, edited, and then sent to the editors. The final chapter came back from tech review a week ago Sunday, and on Friday night I sent it off to the editors. As I understand the rest of the process, I have to do one more approval of the final layout, then after a short turn around, it goes up as a PDF on the php|architect website. Only a week or two after that, it will be available in hardcopy. Down to the wire, but I am hoping to see the dead tree edition by php|t.

I am really proud of the work which went into the book. The book is basically a pattern catalog. For each pattern, I tried to select an example which exemplifies the pattern in a web development context. Each example was then developed with complete unit tests in SimpleTest. After each example was working to my satisfaction, I would then decide how to show the code in the prose of the chapter. There were a couple of chapters which I basically rewrote from scratch after getting back comments from the tech review, and the results were much stronger chapters. I think the emphasis on testing; the use of both PHP4 and PHP5, and solid examples with UML customized to the examples and the patterns is going to position this book in a strong niche.

Speaking of php|t, all spare minutes are now devoted to polishing of my two presentations on “PHP5 Design Patterns” and “Test Driven Development in PHP”. If you are headed down to Cancun, look me up.

There was another request for code related to my previous book “PHP Graphics Handbook“. I have the code for the second half of the book in this zip file. As I mentioned in this previous post, if you still have access to the last code download, shoot me an email. If you know how to contact either of the other authors, I would be happy to know that as well.

SimpleTest 1.0!

Posted 2/26/2005 By Jason

Marcus Baker has released SimpleTest version 1.0! Download the files here and view the API documentation here. Congratulations Marcus, this is a fine work and an outstanding contribution to the PHP community.

For anyone who has not caught testing fever, try it out. There has been no other programming practice which has positively affected my programming practices the way unit testing and test driven development have.

I alluded to my in progress book in an earlier post. Each of the examples in the book was developed with unit testing coverage using SimpleTest, and all of these tests will be available in the source code download for the book. I hope the book shows good coding practices as well as demonstrating design patterns in PHP.

Added My Del.icio.us Bookmarks

Posted 2/12/2005 By Jason

I added my recent del.icio.us bookmarks to this blog under the calendar in the side bar. I googled for the basic plugin, and tweaked it a bit to suit how I wanted to use it.

The plugin looks like:

<?php

/*
Plugin Name: del.icio.us
Plugin URI: http://del.icio.us/
Description: Fetches your <a href="http://del.icio.us/">del.icio.us</a> bookmarks list using the standard HTML method.
Provides one function, delicious().
Author: Phil Ulrich
Author URI: http://interalia.org/
*/
function delicious($username='sweatje', $count=10, $extended="Bookmarks",
 $divclass="link", $aclass="storytitle", $tags="yes", $tagclass="meta", 
 $tagsep="/", $tagsepclass="delTagSep", $bullet="raquo",
 $rssbutton="yes", $extendeddiv="no", $extendedclass="")
{
    $cache = 'cache/del.icio.us';
    if (file_exists($cache)
        && false !== ($mtime = filemtime($cache) )
        && (mktime() - $mtime) < 3600) {
        echo file_get_contents($cache);
        return;
    }
    $queryString = "http://del.icio.us/html/";
    $queryString .= "$username/";
    $queryString .= "?count=$count";
    $queryString .= "&extended=$extended";
    $queryString .= "&divclass=$divclass";
    $queryString .= "&aclass=$aclass";
    $queryString .= "&tags=$tags";
    $queryString .= "&tagclass=$tagclass";
    $queryString .= "&tagsep=$tagsep";
    $queryString .= "&tagsepclass=$tagsepclass";
    $queryString .= "&bullet=$bullet";
    $queryString .= "&rssbutton=$rssbutton";
    $queryString .= "&extendeddiv=$extendeddiv";
    $queryString .= "&extendedclass=$extendedclass";

    $html = implode(' ', file($queryString));
    $data = str_replace(array('<div class="link">',''),array('<li>','</li>'),$html);
    // php5 only file_put_contents($cache, $data);
    $fh = fopen($cache, 'w');
    fwrite($fh, $data);
    fclose($fh);
    echo $data;
}
</>
?>

Update: Per the comment from Darren, I added caching. I was on me “TODO” list, but you know how those go 😉

Spotted in the Wild

Posted 1/23/2005 By Jason

Here is a little teaser of something I spotted in the wild!!!

Google Vs. Blog Comment SPAM

Posted 1/19/2005 By Jason

Via the Ruby general list I stumbled on Preventing Comment Spam from Google. This seems like an easy enough idea; I will have to see if I can scrounge up enough time to hack it into WordPress.

On a related note, I heard that sometimes spammers actually have real people entering these inane blog comments. If so, I think they need some more training. 😉 It seems they are leaving obtuse comments without a url linked, and therefore with no purpose at all?!?

Euclid’s Algorithm in one line of PHP

Posted 1/14/2005 By Jason

Sometimes I am amazed at how forums work. The way in which people come and offer help, myself include, impresses me. I do not fully understand my own personal motivations for participating in forums, but at least one one of the reasons is sometimes the opportunity to write so code just for the fun of it presents itself. One such case was here. The original poster essentially wanted to reduce a fraction (though he was kind of beating around the bush about it). The post had been up on the board for a day, and several people had answered trying to help and clarify the issue at hand.

I dredged up some grade school math memories from long ago, and recalled the way to reduce a fraction was to identify the greatest common denominator, and divide each of the parts of the fraction by the gcd. I jumped to my del.icio.us reference page and located the Dictionary of Algorithms and Data Structures to search for greatest common denominator.

This quickly lead to Euclid’s Algorithm, a heuristic methodology for identifying the greatest common denominator. About a minute of thought later, I implemented the algorithm in a one line recursive function call:

<?php
function gcd($a, $b) {
  return ($b) ? gcd($b, $a % $b) : $a;
} 
?>

With that in hand, it becomes trivial to write the function to reduce the fraction.

So why am I blathering on about this? No particular reason, sometimes I just like the elegance of a particular solution, and this one struck me as one I wanted to mention and save for posterity. It is not an OOP solution, but being object oriented is not a requirement for elegance or utility. As a side effect, it was an opportunity to throw out some links that someone may end up finding useful.

Chaining Object Calls in PHP4

Posted 12/17/2004 By Jason

I ran across a SitePoint post where a user wanted to chain calls to returned objects in PHP4, similar to what you can now do in PHP5. Of course PHP4 does not allow this syntax, but the user came up with the idea of calling a function with the base object, and the series of calls as a string argument. The function would then parse the string and apropriatly eval() the calls. I took his idea as a springboard, and re-wrote it to use recursion for arbitrary call depth.

Here are the functions:

<?php
function &chain(&$obj, $call) {
        return call_chain($obj, explode('->',$call));
}
function &call_chain(&$obj, $stack) {
        if ($stack) {
                eval('$new_obj =& $obj->'.array_shift($stack).';');
                return call_chain($new_obj, $stack);
        } else {
                return $obj;
        }
}

?>

And here is a cheesy example:
Read the remainder of this entry »

New PHP Releases

Posted 12/17/2004 By Jason

From the internals list. Downloads here. But a word of caution, I have heard grumblings of problems from people migrating to 4.3.10 on some message boards I follow.
Update: If you experience any problems with upgrading to PHP 4.3.10, make sure you have the latest Zend Optimizer if you are running it. It seems there are problems with older versions of Zend Optimizer and foreach().

PHP Development Team would like to announce the immediate release of PHP
4.3.10 and 5.0.3. These are maintenance releases that in addition to
non-critical bug fixes address several very serious security issues.

These include the following:

CAN-2004-1018 – shmop_write() out of bounds memory write access.
CAN-2004-1018 – integer overflow/underflow in pack() and unpack() functions.
CAN-2004-1019 – possible information disclosure, double free and
negative reference index array underflow in deserialization code.
CAN-2004-1020 – addslashes not escaping

Documenting External Dependancies

Posted 11/22/2004 By Jason

There is an issue which kind of bugged me with external dependencies in my source code documentation after it is parsed by phpDocumentor, the source code doc does not know much about the external libraries, and therefore leaves references to them dangling…

This particular problem is highlighted when you use the source code highlighting feature (BTW: very cool feature!!!) and have a class method which returns an external class. Where you can normally click on the return class and jump to it’s documentation in your source code, you are only told the name of the class when it is external to the project.

This is rightfully so, after all “You don’t know what you don’t know.” You can not expect phpDocumentor to know about your external dependencies in a vacuum. What I have come up with in my own experimentation is to stub in a small file in the project called external.php which documents the classes as a 50,000 ft. level, and provides a link to the source of the external library. Obviously, you do not want to include this file in you project, as it would cause class re-definitions and all sorts of problems, but as a stop gap for documentation, it seems to work well.

external.php:

<?php

< ?php
/**
 *    Identify external dependancies for library classes
 *    for purposes of phpDocumentor inclusion
 *
 *    !!!WARNING! WARNING! WARNING!!!
 *            Do not include this file in the project code.
 *            It will cause the application to break. This file
 *            is for documentation only.
 *    !!!WARNING! WARNING! WARNING!!!
 *
 *    @author        Jason E. Sweat
 *    @since        2004-11-20
 *    @version    $Id: external.php,v 1.3 2004/11/22 16:03:35 sweatje Exp $
 *    @package    YourProject
 *    @subpackage    external
 */

/**#@+
 * SimpleTest 
 * @link http://simpletest.sf.net/
 */
class UnitTestCase {}
class WebTestCase {}
/**#@-*/

/**#@+
 * WACT
 * Web Application Component Toolkit
 * @link http://wact.sf.net/
 */
class WACT {}
class FormView {}
class ArrayDataSet extends WACT {}
class DataSpace extends WACT {}
class DatasetDecorator extends WACT {}
/**#@-*/

/**#@+
 * SPL
 * Standard PHP Library
 * @link http://www.php.net/~helly/php/ext/spl/
 */
class Exception {}
/**#@-*/

?>

This "fix" seems to clean up the class tree significantly where you have extended classes from external libraries as well.

PHP5 Setters Should Return $this

Posted 11/15/2004 By Jason

I think that as a convention, I will now have all setters return $this instead of null. I arrived at this decision from messing around with the Specification design pattern (“Domain Driven Design” by Eric Evans, pg. 224). When I was creating a chain of specifications in my Policy object, I ended up making a large number of Factory methods, one for each concrete Specification type. During one refactoring, I added an attribute with a setter for if this was a “normal” specification or just a “warning” specification (one that would log a normal error message if not satisfied, but still allow the policy to take place if other specifications on the chain were sufficient). A little more info on my experiment with the Specification pattern here.

Anyway, you end up with a factory method like this:

<?php

    private function fieldEquals($field, $value, $msg, $logdesc) {
        return new FieldEqualsSpecification($field, $value, $this->log, $msg, $logdesc);
    }

?>

And if you want a small variation of this method that sets the warning, you can do:

<?php

    private function fieldEqualsWarn($field, $value, $msg, $logdesc) {
        $ret = $this->fieldEquals($field, $value, $msg, $logdesc);
        $ret->setWarning();
        return $ret;
    }

?>

But, if you have the Specification::setWarning() method return $this instead of null (void) you can eliminate the temporary variable in the second Factory method and end up with this code:

<?php

    private function fieldEqualsWarn($field, $value, $msg, $logdesc) {
        return  $this->fieldEquals($field, $value, $msg, $logdesc)->setWarning();
    }

?>

Breaking it down the way the PHP parser does, you get:
$this->fieldEquals() returns an object
which we call the setWarning() method on
which returns an object that we return from this method

I’ll have to contemplate it a bit, but “When in doubt, return $this” may become a mantra for my PHP5 development 😉

Lost Download

Posted 11/11/2004 By Jason

Ages ago (it seems anyway, Feb 2003 timeframe), I wrote a book for Wrox ( PHP Graphics Handbook (Wrox) – ISBN: 1-86100-836-8 ). Wrox published it and then immediately went bankrupt. For a brief period of time they had the source code downloads for the first four chapters available on their web site as 8368_part1.zip. When I pointed out that my chapters were missing from the download, they replaced 8368_part1.zip with 8368_part2.zip instead of adding it as an additional file. I somehow failed to ever keep a copy of 8368_part1.zip. :(

Over the years, several people have tried to contact me regarding obtaining 8368_part1.zip. If anyone managed to download a copy and hold onto it, please email me a copy (jsweat_php AT yahoo DOT com).

Thanks!

WordPress 1.2.1

Posted 10/12/2004 By Jason

See this announcement regarding the newest version of WordPress. This release patches some recently announced security holes. The upgrade was a reasonably pain free process, just had to hunt for the few tweaks I threw in on the fly.

Update: Don’t forget your plugins. Posts using the syntax highlighter plugin from Scott Yang really look ugly without it 😉

PHP Case Studies Needed

Posted 10/12/2004 By Jason

Marco is looking for PHP success stories to be used for the creation of a web site dedicated to promoting PHP as an “Enterprise Ready” solution. I think this is a very worthy cause. The fact is the numerous “Enterprise” class operation are using PHP and other open source projects, often without management in these operations even knowing (or caring :( ). Any project that seeks to stengthen the awareness of PHP strengthen gets thumbs up 😎 in my book.

So… go read his post, and send ’em in if you got ’em. 😉

How many lines?

Posted 10/8/2004 By Jason

I read Size of phpDocumentor on Joshua Eichorn’s blog and questioned the methodology of simply passing all the *.php and *.inc files through wc -l to count the lines. It does not seem reasonable to me to count whitespace and comments as lines of code.

I though perhaps I could use the whitespace/comment stripping ablity of the php cli binary (the php -w option) in the middle of a shell command to get a more accurate count. Something like:

find . -type f | grep -e 'php$\|inc$' | xargs -n 1 php -w | wc -l

But is seems that this option is somewhat more aggresive with removing new lines that I would have prefered. My next thought was to convert every instance of a ; to ;\n, which you can easily do with sed.

Here was the resulting output from running
find . -type f | grep -e 'php$\|inc$' | xargs -n 1 php -w | sed -e 's/;/;\n/g' | wc -l

This is better, but still leaves you vunerable to ; embeded in stings and counts the <?php and ?> delimiters, etc. Not perfect, but a reasonable shot for a one liner shell command.

A little googling turned up SLOCCount, which professes to count multiple languages and strips comments, etc. It also passes those line count through some interesting statisical manipulation and summarizes the results.

Here is output of sloccount on some of my favorite php projects:
Read the remainder of this entry »

ScriptServer Rocks!

Posted 9/29/2004 By Jason

Well, I finally had a chance to play around with Harry’s ScriptServer.

First of all, if you are unfamiliar with the project, the goal is to hook up client side JavaScript functions with server side PHP scripts. Seamlessly, and without requiring a new HTTP requests.

And ScriptServer is great!!! It took minimal amounts of code to hook up a button of a form to collect several fields from a form, and post them directly to a class method in PHP, and allowing javascript to get a chunk of HTML back from the function for use in replacing the .innerHTML of another division on the page. The results are fantastic, no submit and quick in place edits.

The particular project I was working on that needed this kind of functionality had a large form for the base record that takes some effort to validate and update. Meanwhile, there are several one-to-many relationships that are a part of the model, which is where I am able to put the scriptserver “in place editing” to greatest effect. Essentially I handle the “quick and easy” relationships with this javascript RPC mechanism, and handle the bulk of the base record edits when the main form is submitted.

The only minor issue I encountered was with the new PHP5 case sensitivity of method names.

Anyway, kudos to Harry, works great, check it out. 8)