3.23.2006

Stupid Zend Humor

Here's a quick IM with another programmer at work

Tom (3/23/2006 1:49:54 PM): WHat did you do to my Zend?
Rich (3/23/2006 1:50:18 PM): nothin
Rich (3/23/2006 1:50:20 PM): why?

Tom (3/23/2006 1:50:37 PM): Froze for a minute
Rich (3/23/2006 1:53:12 PM): mine's been fine
Tom (3/23/2006 1:53:29 PM): seems better now
Rich (3/23/2006 1:53:55 PM): that's because I stopped running slow_toms_zend();
Tom (3/23/2006 1:54:05 PM):
Tom (3/23/2006 1:55:08 PM): You forgot the parameter: slow_toms_zend(xtra_slow_today);
Rich (3/23/2006 1:55:51 PM): there's a default set up in the function declaration:
Rich (3/23/2006 1:56:02 PM): function slow_toms_zend(xtra_slow_today = true)
Tom (3/23/2006 1:55:56 PM): and then there's the 'break his balls' parameter
Rich (3/23/2006 1:56:26 PM): no, that's a separate function
Rich (3/23/2006 1:56:47 PM): it's a public method in the PissTomOff class
Tom (3/23/2006 1:56:55 PM): ;-)
Rich (3/23/2006 1:57:00 PM): is it still slow?
Tom (3/23/2006 1:57:03 PM): No, but outlook crashed
Rich (3/23/2006 1:57:11 PM): Dude, you need a new computer. Or feed that hamster inside yours.

11.19.2005

Still fleshing out the syntax highlighting

I'm not 100% happy with the way the syntax highlighting is working out so far with the code examples. I may have to hack up the plug-in. My apologies if it's annoying you as well.

UPDATE 12/2/2005: It would help if I actually included the css file, eh? Code examples now contain outlines and scrolling.

11.18.2005

Configuration variables via Singleton object in PHP4

There is probably no design pattern handier and easier to set up than a Singleton pattern. One of the best uses in PHP apps is for configuration variables. You can use define all over the place or you can use $GLOBAL but things work a lot better when you have nice neat place to set and get global configuration variables. Enter the Singleton Configuration object. Here's some simple code for the object itself, simply named Config.php:

/** 
* Web Config object using Singleton pattern 
* 
* @author Rich Zygler, Jr. 
* @datecreated 03/08/2005 
* @access public 
* @usage $config =& Config::getInstance(); 
* @usage $config->setConfig('admin_email', 'test@test.com'); 
* @usage $email = $config->getConfig('admin_email'); 
* @TODO 
*/ 

class Config 
{ 
  var $configVars = array(); 

/* 
* Create a new config object 
*/ 
  function &getInstance() 
  { 
    static $instance; 
    if (!$instance) 
    { 
      $instance = array(new Config); 
    } 
    return $instance[0]; 
  } 

/* 
* Get config data 
* 
* @param     $key string - array key of variable whose data we are retrieving 
* @return    $this->configVars string 
*/ 
  function getConfig($key) 
  { 
    return $this->configVars[$key]; 
  } 

/* 
* Set config data 
* 
* @param     $key string -variable to retrieve data stored 
* @param     $value string -variable that contains data to store 
* @return    true 
* Can use arrays as well as in  $config->setConfig('email_list', array(//... )); 
* retrieve array by foreach($config->getConfig('email_list') as $email) { //... } 
* 
*/ 

  function setConfig($key, $val) 
  { 
    $this->configVars[$key] = $val; 
    return true; 
  } 

} 


If you think the getInstance method looks a little borked, you're right. What we're doing there is attempting to return the first and only the first implementation of this object. So everytime you make a call to this config object, you should be getting the same one. That's why we return the [0]th item in the array. This is a little easier in PHP5 but for PHP4, this is what we're stuck with.

And here's how to use this bad boy:

/** 
* config include 
* 
* @author Rich Zygler, Jr. 
* @datecreated 03/08/2005 
* @TODO 
*/ 

// Bring in the Config class file 
require_once ('Config.php'); 

// Instantiate our config object 
// Remember in PHP4, we use the  =& 
// to pass by reference 

$config =& Config::getInstance(); 

// Set up some config vars 
// will change per application 
// The usage here is:     setConfig(varName, varValue) 

$config->setConfig('appVersion', '1.o'); 
$config->setConfig('appName','Tester'); 
$config->setConfig('debug', true); 

// Maybe set the DB connection vars 
$config->setConfig('dbconn', array( 
  'username' => 'bunsen', 
  'password' => '!honeydew%', 
  'host'     => 'localhost', 
  'db'       => 'test', 
  'type'     => 'mysql' 
  ) 
); 

// Now to get those values back from the $config object 

// first let's initialize our vars 
$appVersion = ''; 
$appName = ''; 
$debug = false; 
$dbConnArray = array(); // used for getting back db values 
$dbUser = ''; 
$dbPass = ''; 
$dbHost = ''; 
$dbType = ''; 
$dbName = ''; 

// Now let's get the values from the config object and populate our variables 
// of course, for a fully functioning app, you may want to check that these values are set 
$appVersion = $config->getConfig('appVersion'); 
$appName = $config->getConfig('appName'); 
$debug = $config->getConfig('debug'); 

// Here, we slurp the whole array from the config into a new array 
$dbConnArray = $config->getConfig('dbconn'); 
$dbUser  = $dbConnArray['username']; 
$dbPass  = $dbConnArray['password']; 
$dbHost     = $dbConnArray['host']; 
$dbType     = $dbConnArray['type']; 
$dbName    = $dbConnArray['db']; 

// Now let's echo everything out to make sure the values are 
// coming back correctly 
echo "The version is: $appVersion"; 
echo "The name is: $appName"; 
echo "The debugger is on: $debug (1 = true) "; 
echo "The db username is: $dbUser "; 
echo "The db password is: $dbPass "; 


What's great about this method of doing things is that you virtually eliminate the need for global variables in functions and objects. This is a very good thing. If you need some configuration variables available to a function or object, you can pass it this config object like this:

// call the function this way 
doSomethingWithConfig($config); 

// define the function this way 
// Remember to accept the object by reference (add the &) 
// otherwise a copy of the config data is created -- not good 

function doSomethingWithConfig(&$config) 
{ 
  // get app version 
  $appVersion = ''; 
  $appVersion = $config->getConfig('appVersion'); 
  return $appVersion; 
}


If you like this way of doing things, wait until you try to recreate this in PHP5, it's even easier.

11.11.2005

Form data validation in PHP and JavaScript

I'm mentoring a few folks at work in web app development, specifically PHP. Today, the subject of form data validation came up when I pointed out to them that their app had none. No matter what data I entered for name, email address, etc., that data went right into the database (or at least the insert was tried). It was hack city.

There are 3 different types of data validation checks one can do:
  • Syntactic validation
  • Semantic validation
  • Domain or model validation

Syntactic validation is when you need to make sure that the syntax of incoming data is correct. For instance, if it's a "first name" field, you wouldn't expect numbers, ampersands or other strange characters in there. You'll have to strip out the garbage before you can put that name into the database, so you'd better make the user fix their data before you have to. Another common one I find is when trying to get telephone numbers, social security numbers, etc. You don't want any chars in there.

Syntactic validation also takes care of checking minimum and maximum lengths for fields. If a new user must have a username that's 5 or more characters, you would check that thru syntactic validation. Same thing for maxlengths. Syntactic validation is what's going on too with checking for required fields (ie, is the username field blank).

Another common use of syntactic validation on the web is for checking valid email addresses and urls. You need to make sure those email addresses folks are giving you are at least of the proper form so you can email them good marketing stuff later. You could also check to make sure that email address actually exists (this would fall under domain validation though).

Syntactic validation is the simplest form of validation. The beauty part of it is that you can do most syntactic checks in both JavaScript on the client-side and then again in PHP on the server side. This aspect of "double-checking" stumped my associates too until I mocked up a quick form on my own machine that posted junk values to their test app, causing all kinds of mysql errors. I've seen programmers that don't do validation on both the client-side and server-side, but those programmers are no longer working steadily.

Another form of data validation is Semantic validation. In semantic validation checks, you are checking to make sure that one piece of information makes sense in regards to other incoming information.

For example, when registering a new user, most web apps will place the password box twice to make sure the user enters their desired password correctly. Checking these two passwords to make sure they are the same would be an example of semantic validation. Another example of semantic validation is checking to make sure that a required field based off another field is actually filled in. So, if the user specifies the country as US, then they also have to specify a state in the US... otherwise, they don't have to specify a state.

Semantic validation rules can get very complex, very quickly. While it's easy to build up a library of reusable code of syntax validation rules, semantic validation rules often require some custom work on every form. Again, semantic validation rules are most effective when used on both the client-side and server-side.

The third kind of form data validation is Domain or model validation. Domain validation requires checking the incoming info against another source of acceptable values. This could be existing database records, a config file, or simply PHP code. This kind of validation is checking the "domain" or "model" to make sure this incoming info makes sense.

A great example of domain validation is when registering as a new user on a site. After passing all the syntactic and semantic checks for registering a new username and password on the site, the app has to check to make sure the username you are requesting isn't already taken. So, it queries the users table in the db to see if your requested username is there. If it is, then the app needs to alert you to what went wrong and give you another chance to suggest a username. So, our web app is checking your requested username against the domain of existing usernames in our system.

Other examples of domain validation include checking to make sure an article_id in a CMS exists before we edit/delete it. Domain validation is also used in many permission schemes in web apps (ie, you can perform this action if your user level is > 5 or something).

Domain validation will almost always need to be done on the server-side as that's where the domain or model usually resides. So, you can't do any domain validation in JavaScript (well, you could, but it would be the most insecure app in the world).

Now the trick with form data validation is that most of the checks you're doing on the data will be done over and over again in every web app created. So, you're best bet is to create some type of class to take care of all this for you. (more on this in future article).