php|works has arrived!

Posted 9/22/2004 By Jason

The php|works conference in Toronto is officially underway. They have WIFI access from the atrium (and from my room, since if faces into the hotel :) ). Tested it out from the conference rooms as well, so all is good with internet connectivity.

Looks like a very good line up of speakers. Went out to dinner with a few of the other speakers last night and had a number of engaging conversations ranging from trends in rich client-side applications to baby care techniques (seems like there are quite a few new PHP fathers, and I abandon my wife at home with a two year old with 103 degree temp :( ).

My presentations are tomorrow at 2:00—Documenting Source Code—and Friday at 9:45—PHP and Oracle. Both of them are of course biased towards my perspective of using PHP in an enterprise development environment.

Hope to see you there. Drop by and see me if you are here.

   

Teach yourself x in n time units

Posted 9/10/2004 By Jason

Ran across this and thought I would share:
http://www.norvig.com/21-days.html.

Happy Reading :)

   

Marcus Blogs!

Posted 9/1/2004 By Jason

Marcus Baker (author of SimpleTest php unit testing software) now has a blog at http://www.lastcraft.com/blog. Right out of the gate he has several thoughtful and insightful essays reminiscent of his many similar posts in the Advanced PHP Programming forum on SitePoint.

His post Design Drool brings up some of what I have only been vaguely hinting at in some of my posts, the mindset of a good programmer. Marcus does a great job of summarizing our own internal hidden agenda…and he was spot on with that old sprite based spaces invaders game :) . Even brought up the memories of the first program I was paid to write: a scheduling program for a machine shop. Boy was that ever a nightmare to try to cram both the BASIC source code and the data into 64k 😯 !

   

Scientific Method Man

Posted 9/1/2004 By Jason

Wired published an article titled “Scientific Method Man” regarding Gordon Rugg’s solution to the problem of the Voynich manuscript (a manuscript written in a code that has not been broken for 400 years). His solution was to prove that the manuscript was a hoax. To do so required some creative, out-of-the-box thinking, and a challenge to the dogmatic thinking of the experts in that domain.

I was attracted to this article because I see this kind of creative thinking being required to solve many of the issues I see at work, but it seems a rare trait indeed to see people with this skill set :(

   

js does xmlrpc

Posted 8/29/2004 By Jason

Today I explored some new (to me) technologies to support a feature I was playing with. On a complex form representing a row being edited in a database, I had several 1-to-many relationships that I wanted to edit (i.e. make additions to) without submitting the main form. It is an intranet application, so I have the ability to rely on the fact that users will be using IE, and js will be enabled.

From the usual bag of tricks, my initial thought was you could have javascript submit a hidden form in a non-visible frame, and have the results come back with some onLoad() js that would update the main form (even did a little flow diagram, will attach at the end of the post). But I remembered Harry mentioning using js and php to communicate by serializing data in mutually compatible formats. This is the scriptserver project which he blogged about a while back. Harry also sent me a link to this js library to implement xmlrpc.

I have to admit that I have not played around with xmlrpc to date (at least in terms of actually doing anything with the technology, I have read enough to have the gist of xmlrpc and SOAP). This is mainly because I kept asking my Unix admin at work to compile php with the xmlrpc extension, and he always complained that he could not get the extension to compiled on HP-UX. I have finally started to push for some Linux web servers at work, so that will not persist as an issue in the future. Anyway, I decided to play around with this javascript xmlrpc library and see what I could come up with.
Read the remainder of this entry »

   

Creative use of Data:Table

Posted 8/22/2004 By Jason

Harry recently blogged about the Data:Table component I wrote for WACT. His post talked about the common method of using the data:table tag, i.e. feed it a data set and have it generate a table, perhaps using some declarative markup in the template to modify the results. Used in this context, you can output nicely formatted HTML tables with minimal amounts of code.

I had an interesting problem recently that challenged the way I used the data:table component. I needed to display 18 months of data in a table. Each row represented a different item, and the months were to be laid out in the columns of the table.

When I started to work with the table, I initially started with the traditional style of putting all of the tags specifying the layout in the template. With just two months of data, it might have looked something like this:

<data:table from="tableData" autogen="n">
  <data:column name="itemdesc">
    <data:header>Description</data:header>
  </data:column>
  <data:group>
    <data:header>{$m1label}</data:header>
    <data:column name="m1val">
      <data:header>Value</data:header>
      <data:cell>{$m1val|number}</data:cell>
    </data:column>
    <data:column name="m1val2">
      <data:header>Input</data:header>
      <data:cell><input type="text" name="{$m1key}" value="{$m1val2|number}"></data:cell>
    </data:column>
  </data:group>
  <data:group>
    <data:header>{$m2label}</data:header>
    <data:column name="m2val">
      <data:header>Value</data:header>
      <data:cell>{$m2val|number}</data:cell>
    </data:column>
    <data:column name="m2val2">
      <data:header>Input</data:header>
      <data:cell><input type="text" name="{$m2key}" value="{$m2val2|number}"></data:cell>
    </data:column>
  </data:group>
</data:table>

You can see where the group of columns for month two is just a cut and paste with minor tweaks to the variables. While this worked fine, I knew this was not what I wanted to maintain for the long run. Ideally I could use a loop to specify the templates for a single month once and have it increment through the values, but the data:table component does not support other WACT looping structures inside of it (a list component), and WACT templates do not support variable variables that would be required to iterate over the months.
Read the remainder of this entry »

   

Stealth PHP Singletons

Posted 8/18/2004 By Jason

I explained a bit of my code in a post up on SitePoint that reminded me of one of my favorite bag of php tricks: associating a superglobal key reference with a class variable.

<?php
$this->_stack =& $_SESSION[NOTIFY_SESSION_KEY];
?>

This has the effect of making a “stealth” static member, as well as effectively making the class a singleton (i.e. every instance of the class will access and manipulate the same data, and is therefore equivalent).

The context of my post was explaining a session based user notification queue. I have been using WACT recently, so I included a helper method to return the queue as an ArrayDataSet.

So without further ado, here is the test case and code.

Read the remainder of this entry »

   

Math Tricks

Posted 8/14/2004 By Jason

Inspired by a wired article I googled for a Vedic Math tutorial.

I have always found these little math tricks interesting, mainly from the perspective of trying to figure out how they work. I think it is a kind of a mental excersize similar to figuring out a clever optimization algorithm in programming.

Anyway, this Vedic math reminded me of one of my favorite stories about a young Gauss (eminent 19th century contributor to mathematics and statistics) whose math teacher instructed them to add up the numbers from 1 to 100 on their slate to keep them quite and occupied for a while. The story continues that, much to the teacher

   

Not the last lastcraft

Posted 7/31/2004 By Jason

Marcus Baker, author of SimpleTest and oop/pattern guru extraordinaire at the SitePoint Advanced PHP forum has just had release 1.0 of Bryn Reuben Baker, a strapping young man of 8 lbs. 4 oz. born at 1:48AM July 30th, 2004.

Congratulations Marcus! May Bryn’s tests of you always result in a green bar :)

   

Testing MVC Actions classes

Posted 7/29/2004 By Jason

In developing web applications with a Model-View-Controller “flavor”, I find that in the Controller portion of the architecture I invariably end up with “Action” classes. These are implemented as a Strategy pattern (i.e. a family of algorithms, encapsulated as classes with the same method signature, making them interchangeable). In my code, I end up with something like:

<?php
class Action {
  function Action() {}
  function Perform() {}
}
?>

And there might be some kind of an application controller, e.g.:

<?php
switch (strtolower($_REQUEST['action'])) {
case 'dosomething':
  $action = 'DoSomething';  break;
default:
  $action = 'DefaultAction'; 
}
if (!class_exists($action)) {
  require_once ACTION_INCLUDE_DIR.$action.'.php';
}
$action_instance =& new $action;
$action_instance->perform();
?>

Now inside these classes they usually need to access various model classes which in the past I had done by simply creating an instance of the desired model as a local variable in the Perform() method. This however, makes the code very hard to unit test.
Read the remainder of this entry »

   

New Data Mining Article Published

Posted 7/21/2004 By Jason

Magazine Cover php|architect’s July issue contains my latest article on the topic of Data Mining with PHP.

The article shows examples of several graph styles (including the rarely seen radar chart!), and uses the PHP bug database as a data set to mine.

Because php|a chose to make this the sample article for the month, it is available for download as a pdf file here.

<soapbox>
The data set is a little old (December 2002 timeframe) because this was actually written as part of the PHP Graphics Handbook, a book I co-wrote for Wrox, approximately one month before they went bankrupt :evil:. But, as a bonus, it is available for you to peruse now :)! Wrox decided I wrote too much and edited out 1/3 of my original content before publication, and this case study represents about half of what was cut.
</soapbox>

 

   

I just spent an hour debugging the old “never forget to exit after sending your header redirect” error.
PEBKAC (my chair and my keyboard :( )…

SAFETY TIP:
Whenever you have code that looks like this:

<?php
header('Location: '.phpself());
?>

it must be followed by

<?php
exit;
?>

to prevent hard to track down unexpected results.

   

We Don’t Need No Stinkin’ Login

Posted 7/20/2004 By Jason

Wired recently published an article regarding users avoiding site registrations by providing fake data, or using a shared login (a technique which is apparently being facilitated by bugmenot.com).

My own users balk at having to sign on, hence the posts below regarding using NTLM authentication as the primary means of identifying the user. We have a major initiative going on at work deploying a package that is a network of software modules. They use a “Single Sign On” (that mostly works, except for these modules…oh, and since you’re a developer, you will be needing these other four ids :roll:). Since this “Single Sign On” is completely distinct from the NT User that each person must log into their PC with, I have started to refer to it as the “Second Sign On” 😀

My own personal technique has changed since I rebuilt my home server. Since I now run qmail, I simply set up an alias (usually the site’s name@my domain) to give them. If they sell it 👿 and the alias starts to attract spam, I will just delete it :).

Regarding the original articles premise, what ever happened to just dropping a cookie to track usage?

   

Introducing the RUHA Lib

Posted 7/15/2004 By Jason

By popular request—or at least by Harry’s request—the Really Ugly Hack Authentication Library.

First a little preface:
This library was designed a couple of years ago to make up for the lack of NTLM authentication for apache. We—my system administrator and myself—tried several flavors of “mod_ntlm” projects for apache. We were not able to successfully compile any of these against Linux (let alone the HP-UX 10.20 production environment :( ). We tried to contact several of the maintainers without success, and so gave up the quest. This solution probably does not have very wide applicability, but we already had both Unix/Apache and Windows/IIS servers up and running, plus our staging process required users to have IE which supports NTLM authentication out of the box (as does Mozilla and Firefox now) so it did suit my needs.

BTW, if anyone knows of a working mod_ntlm module for apache now, please comment :).

My early background in web programming (prior to PHP enlightenment) was in ASP on IIS. Under this scenario, turning on security on the directory allowed you to pull the NT user name from the server variable…very handy :). Knowing this was possible, I devised a scheme were a PHP script on Apache would redirect to an ASP script on another IIS server in a NTLM protected directory, which would return the user id encrypted for the PHP script to decrypt. This scenario worked for the most part, but occasionally the user name got garbled in decryption, so I resolved to try this trick multiple times, and if I got the same result back twice in a row, I considered it golden.

Visually, this is how it looks:

follow the bouncing ball
Read the remainder of this entry »

   

Time to learn about TrackBack

Posted 7/15/2004 By Jason

By mentioning me in his blog, Jeff Moore has officially welcomed me to the blogosphere!

This seems apropos, since Jeff was motivational in both my investigation of RSS (I finally gave up the notion that is was a fad, now I can no longer remember what it was like to randomly surf for information on the internet 😉 ) and his use of WordPress, along with comments from Harry and other reviews led to me selecting WordPress as the tool to host this blog.

Now Jeff has inadvertantly posed my next challenge: How does TrackBack work? I have found two links on the subject, here and here. I guess if you see TrackBack info on Jeff’s post, you will know I suceeded :)

   

Happy Birthday PHP5

Posted 7/14/2004 By Jason

Download your copy today.

Contratulations and thanks for all the hard work to every developer involved :)

   

I have a security mechanism that I coded up several years ago. It relies on NTLM Authentication (on a remote IIS server via redirects) and can be implemented in any php script on my Unix/Apache box using three lines of code:

<?php

require_once 'the_lib.php';
session_start();
use_scrty('Application Identifier');

?>

It checks the NTLM authorized user against a database of user id’s that are authorized to access applications, and what access levels they have. If the user is not authorized, it will show an error message and exit. This scheme has worked great for me for ages.

Recently I have been doing Test Driven Development (TDD), and my favorite PHP unit testing library—SimpleTest—does not support NTLM Authentication (nor would I want to ask Marcus to implement this mess). Plus, I am not particularly interested in hard coding my NT Domain user name and password into testing scripts.

So what is left to do? Add a back door to bypass security for the test script. In doing this, I would like it to be as secure as possible while breaking security ;). What I have done is allow an additional url parameter that if present, is tested to see if it matches a md5 hash of the current unix timestamp, salted by the mtime for the directory in which the application lives. When I find a match, I insert enough data into the session to appear to have already passed the authentication. This parameter ought to be random and unguessable by my reckoning (at least by any user who does not have access to the web servers file system, for which you have other bigger problems already). Any holes in this scheme? Are there better alternatives available?

<?php

/**
 *    check for test user authentication and require security
 *    @return    void
 */
function check_auth_user() {
    //if testauth is a md5 hash of the current unix timestamp within the past 2 seconds
    $mtime = filemtime('.');
    $now = mktime();
    if (array_key_exists('testauth', $_GET)
        && ($_GET['testauth'] == md5($now.$mtime)
            || $_GET['testauth'] == md5(($now-1).$mtime)
            || $_GET['testauth'] == md5(($now-2).$mtime)
            )
        ) {
        $_SESSION['scrty_data']['scrty_appl'] = APPL;
        $_SESSION['scrty']['valid_login'] = true;
        $_SESSION['scrty']['appl_acss'] = true;
        $_SESSION['scrty']['info'] = array(
             'NAME_FIRST' => 'Anonymous'
            ,'NAME_LAST' => 'User'
            ,'ACSS_LEVEL' => 'GENERAL'
            ,'LOGIN_IDFTN' => 'TESTUSER'
            );
    }
    use_scrty(APPL);
}

?>
   

Recover from System Failure

Posted 7/8/2004 By Jason

Recently I had a hard drive blow up. This is not a figure of speech, there are actually carbon scoring marks on the inside of my computer case, and you can see a gash in one of the IDE controllers onboard IC’s (zoomed in on this photo courtesy of Paint Shop Pro)

Hard Drive Failure

What did I learn?
That my strategy of backing up db dumps and important config files to another partition of the same drive does not do you any good if the hard drive controller goes. Note to self: time to bone up on rsync. I did have some backups burned to CD and replicated to another HD on a different computer, but they were woefully out of date.

I investigated Hard Drive recovery quotes. For this 10Gb HD, they ranged from a max of $1,000 down to the best quote of $350. Ouch :(

I found an identical model HD on ebay and purchased it for $24.99 + $7.00 SH. When the drive arrived, four screws were all that held the controller board onto the drive, and a quick swap allowed me to access the old HD contents. Critical files were quickly copied across the network, and the entire drive was replicated later that night.

What was my recovery plan?
I was running RedHat 7.2 on this system. In the past, I had run earlier versions of RedHat and Suse on it as well. Since RedHat began making noises about desupporting the consumer version of it’s distribution about a year ago, , I began investigating alternatives. I have another system here running Fedora, the successor to RedHat

   

User Input Validation

Posted 7/6/2004 By Jason

I will admit that I am a bit lazy about user input validation. This stems from the fact that:

  1. Most of my development is for intranet use
  2. I generally use Oracle for a back end, and tend to pass parameters as bind variables

The intranet development means that my users are more interested in using the web page to get their job accomplished than they are in hacking the page. A PHP Fatal error message is more likly to result in a support call than in lost business. Also, it is much easier to track down who is causing problems on a corporate network than on the internet, and probably the repercusions would be stronger as well.

True database bind variables also protect you from SQL injection. The problem I have is that perhaps I rely on this feature a bit too much, as it creeps into my writing of articles, where I use MySQL or Postgres, and the ADOdb library is just emulating bind variables with string substitution.

Which leads me to the gist of this post: easy data scrubbing with type casting. Here is some example code from an article I am writing, where I am able to assume the bug_id will be an integer.

<?php

/**
 * validate a user passed parameter is an actual bug id
 * @param string $parm the index of the $_GET request array to check
 * @return mixed  the integer bug_id if found, otherwise false
 */
function check_passed_bug( $parm ) {
    global $conn;

//not indented because the end of the heredoc must be the first char
$sql = < <<EOS
SELECT COUNT( 1 ) AS cnt,
`id`
FROM `bugdb`
WHERE `id` = ?
GROUP BY `id`
EOS;

    if (array_key_exists($parm, $_GET))  {
         //here is the type cast on the input
        $bug_id = (int)$_GET[$parm];
        $rs = $conn->Execute($sql, array($bug_id));
        if ($rs && !$rs->EOF) {
            $row = $rs->fetchRow();
            if (1 == $row['cnt']) {
                //if found return the id
                return (int)$row['id']; 
            }
        }
    }
    //otherwise return false
    return false; 
}</>
?>

The type cast certainly is much less expensive than something like regex based validation. So what is the verdict–Elegant solution or cheap hack, frought with SQL injection danger?

   

php|works

Posted 7/5/2004 By Jason

I am going to be a speaker at the php|works conference in Torono this September.

The two topics I am presenting on are: Developing in PHP using Oracle, and PHP Documentor.