The Resource Model for Web Design

Notification Object

Most of the applications I develop make heavy use of a program called a "Notification Object." I usually call the object "msg." The purpose of the object is to bring messages from one program to another.

In a true client server application (where the web server and database live on different computers) I use the notification object to move data between the two computers. The web server will send a command to the database server which will hand back a result set or the message object.

The msg object keeps track of the state of the program. As the object tracks the execution of the program, it needs to be accessible at any point in the program. It is possible to have multiple notifcation objects in one program; however, since the object tracks the state of the program, there really should be only one notification object.

For the sake of clarity. The message object in this project is lean. All it does is print an HTML block about the success or failure of the program. In a mission critical application, one would add logging and have it email or text the administrator in case of an important problem. You can also add features to help recover from errors.

The messaging object can get complex. When it becomes complex the flow control structure that I use in this example becomes a bit confusing. I really prefer the object syntax.

The problem I face is that scoped of objects in PHP is too limited; so I have to write the code for this resource as a procedure. Here is the procedure I am using:

I prefer to use the object syntax for the program. Unfortunately, since PHP does not have an easy mechanism for making objects global, I will encapsulate the object in a procedure using flow control variables.

The procedure/object I use looks as follows:

const MSG_OK = 0;     // sets a happy message
const MSG_ERROR = 1;  // notes an error
const MSG_COMMENT = 2;// add a hidden message as an HTML comment
const MSG_DEBUG = 3;  // display HTML Comment (usually for the programmer).
const MSG_ECHO = 4;   // echoes the errors in the error buffer.
const MSG_ISOK = 5;   // check to see if all is well.
const MSG_ISDEBUG =6; // telles us if we are in debug mode.


function msgNote($fc, $txt='') {
  static $arr = array();
  static $isOkay = true;  // We start out okay, but things can go bad.
  static $hasAccess = false;  // Default is no. You must grant access.
  static $debugMode = false;  // display additional comments for programmer
  $rv = 0;

  if ($fc == MSG_OK) {
    $arr[] = ['type'=>MSG_OK, 'txt' => $txt];
  } elseif ($fc == MSG_ERROR) {
    $arr[] = ['type'=>MSG_ERROR, 'txt' => $txt];
    $isOkay = false;
  } elseif ($fc == MSG_COMMENT) {
    $arr[] = ['type'=>MSG_COMMENT, 'txt' => $txt];
  } elseif ($fc == MSG_ISOK) {
    return $isOkay;
  } elseif ($fc == MSG_ISDEBUG) {
    return $debugMode;
  } elseif ($fc == MSG_ECHO) {
    // This control loops through and prints the messages.
    $pos = 0;
    $ulClass = ($isOkay)?  'ulOkay' : 'ulErrors';
    foreach ($arr as &$row) {
      if ($pos++ == 0) echo PHP_EOL.'<ul class="'.$ulClass.'">';
      switch ($row['type']) {
         case MSG_OK:
            echo PHP_EOL.'	<li class="msgHappy">'.$row['txt'].'</li>';
            break;
         case MSG_ERROR:
            echo PHP_EOL.'	<li class="msgSad">'.$row['txt'].'</li>';
            break;
         case MSG_COMMENT:
            if ($debugMode) {
              // this is a message for the administrator.
              echo PHP_EOL.'	<li>[COMMENT]'.$row['txt'].'[/COMMENT]</li>';
            } else {
              echo PHP_EOL.'<!--'.$row['txt'].'-->';
            }
            break;
         default: // should not happen.
      }
    }
    if ($pos > 0) echo PHP_EOL.'</ul>';
    $arr = []; // empty the array.
  }
  return $rv;
}

msgNote() has a static array that holds messages, a boolean variabe that notes the condition of the program, and a debug mode that allows you to add comments. In "debug mode" the program prints the comments as part of the message block, otherwise it prints it as an HTML comment.

The flow control variables lets you set a happy message or a sad message. The sad message sets $isOkay to false. The MSG_ECHO command outputs the whole message to the screen.

A program that uses the procedure might look as follows:

  msgNote(MSG_OK,'Everything is looking good.');
  msgNote(MSG_OK,'Trust me, everything is looking great.');
  msgNote(MSG_COMMENT,'No, they are\'t.');
  msgNote(MSG_ERROR,'Everything is broken.');
  if (msgNote(MSG_OK)) {
    // do something important
  } else {
    // clean up pieces of broken program.
  }
  if (user is a programmer) msgNote(MSG_DEBUG);
  msgNote(MSG_ECHO);
  

One can drop a message at any point in a program.

The wonderful little message object prints the flow of the program.

It is possible to enhance the procedure by writing error messages to a log file. You can have it report the line number of a program, and so forth.

I am keeping the program simple to show that this little program can be a real work horse.

Exception Handling System

Version 5 of PHP introduced an exception handling object and the try/catch block based on similar constructs in c, java and PL/SQL.

A try/catch block is really just a stylized form of an if/then statement. A try/catch block says: "If this stuff works; then continue; else run exception handler."

The try/catch block became popular in low level languages where any line of code could fail for a variety of bizarre reasons such as a bad sector on a disk or improperly allocated memory for the program.

Cosider the following pseudo code:

a = 1;
b = 2;
c = 3;

If there is insufficient memory; any one of those basic assignment operations could fail. Rather than checking available memory for each assignment, a try catch block lets you execute a whole block of code that would skip to the execption handler if any one of the lines failed. A try/catch block might look like:

try {
  a = 1;
  b = 2;
  c = 3;
} catch {
  // handle a memory allocation error.
}

The try/catch style is great for desktop programs, but I do not believe that it is the best method for web programming.

In web design, a web browser sends a discrete request to a server and expexts to get a web page back in return. When errors happen, you have to shut down the operation and get some HTML back to the browser.

Now, yes, It is still possible for your web server to run out of memory. But when that happens, the whole server is likely to crash; So, even if your PHP program included the best execption handler in the history of exception handlers, it is unlikely to execute because your server crashed.

Getting your server back on line will be a matter of calling tech support or frantically accessing your server through an online terminal and not through your PHP pages.

While it is possible for any line of code to fail, the common errors in PHP involve accessing io devices. These errors are actually easiet to handle with inline if/then statements.

Some programming schools seem to be teaching that since the try/catch syntax is common in java that the try/catch block must somehow be a higher form or thought than the if/then statement. The truth of the matter is that programmers who get overly excited with the ability to throw exceptions end up creating speghetti code which is every bit as complex as the code written with the GOTO statement.

While there is rarely cause for a web programmer to throw an exception, It is necessary to catch errors from programs that are likely to throw an error and to include a general try/catch block for the main program. I usually jsut catch the exception and record it in my message object as follows:

try {
  // something that might cause an error
} catch (Exception $e) {
  msgNote(MSG_ERROR,'A bad thing happened.');
  msgNote(MSG_COMMENT,'Error '.$e->getCode.' '.$e->getMessage.' line '.$e->getLine());
  // set any variabless needing set to finish creating the page.
}

Some programmers advocate using the exception handler for the primary messaging object. For that matter, I've actually worked on projects the exception handlers were more detailed than the main program and handled much of the day to day program flow.

I dislike that style as I find it creates a confused program flow. I prefer to use the message object and its known program state to control the flow of the program.

Resource Model - - writings