Mach-II for PHP: A Preview

Mach-II is a framework for organizing applications using standard OO techniques. This article will cover how to install, set up and configure a Mach-II application, and explore basic coding techniques.

Background

The Mach-II website proclaims: “Mach-II is a web-application framework focused on easing software development and maintenance.” This introductory description points out a risk common among complex web-based applications built with other frameworks: as requirements expand, they grow too large and complex to maintain without considerable effort.

Mach-II arrived on the scene with this in mind. It’s a framework for organizing applications using standard OO techniques. This means reuse and scalability, two direct benefits of an OO approach, combined with a XML configuration file to control everything.
 
But let’s not get ahead of ourselves. The brainchild of Hal Helms and Ben Edwards, Mach-II first took shape as an advanced version of Fusebox. It took advantage of the then newly-introduced ColdFusion CFCs, or components (classes, in PHP-ese), to provide a framework that allowed developers to code their apps using a combination of events, listeners, filters and plugins. These elements are configured by loading up any Mach-II application’s mach-ii.xml file and mapping out the relationships as XML nodes and attributes.

You may be wondering what this has to do with PHP.  Well, thanks to the hard work of Alan Richmond, the Mach-II framework will soon be available to the developer community.  Continue reading this article for a preview of Mach-II development.

Basic Concepts

This article will introduce you to Mach-II. It features a basic example intended to demonstrate the framework’s appeal for simple to complex web applications. For a more comprehensive breakdown of the concepts behind the framework, see the following documents on Mach-II.com:

{mospagebreak title=Installation}

Let’s walk through a basic setup. This is often the most intimidating part of learning a new framework, but with Mach-II it’s surprisingly painless.

There are two ways to install Mach-II for PHP. The first and preferred method is using the PEAR installer. The second is a manual installation.

PEAR Installer

For anyone unfamiliar with using the PEAR installer with PHP, visit this link. It’s a snap to get running and will allow you to install Mach-II from the command line by issuing a command to PHP. Once the PEAR installer is set up, simply install the Mach-II package like any other PEAR package. Then at the command prompt enter the following:

pear install MachII-x.x.x.tgz

Manual Installation

First, open php.ini and make sure the path to your web root is listed (it should be).

include_path = “.; c:inetpubwwwroot;”

One feature of Mach-II is its core files only need to be installed once for multiple apps. In the case of the demo app, Mach-II was manually installed in the web root. Obviously you can install the framework anywhere, as long as the core files (and your application) can use the include path ./MachII.

Next, unarchive the Mach-II core files into a temp directory. You’ll see the following directory structure:

Getting Started with Mach-II for PHP

Figure 1  Core files in their directories

For the purpose of this demonstration, our application’s directory will reside at the same level as the core files. Create a directory in your web root called ./MachII and copy the contents of ./MachII-x.x.x into it. Create a new directory ./simpleApp inside your web root, as well. This is where we’ll put the demonstration application’s files.

Now unarchive the project files for this article into ./simpleApp. You should see the following directory structure:

Getting Started with Mach-II for PHP

Figure 2  Our demo’s directory structure

{mospagebreak title=Configuration}

Programs that use implicit invocation are frequently referred to as event-driven or event-based. Events are announced, and listeners respond if they are subscribed to them. This is how Mach-II works.

In order to understand what is meant by this, we should begin with mach-ii.xml. This is the configuration file used to define event relationships in a Mach-II application.

<!–
    phpMachII
        config
            mach-ii.xml
   
    I define the basic control flow for this demo application.
–>
<mach-ii>

    <!– PROPERTIES –>
    <properties>
        <!– MACH II REQUIRED –>
        <property name=”defaultEvent” value=”showMain” />
        <property name=”exceptionEvent” value=”exception” />
        <property name=”applicationRoot” value=”/phpMachII” />
        <property name=”eventParameter” value=”event” />
        <property name=”parameterPrecedence” value=”form” />
        <property name=”maxEvents” value=”10″ /> 
    </properties>

    <!– LISTENERS –>
 <listeners>
  <listener name=”processForm” type=”phpMachII.model.processForm”>
   <invoker type=”MachII.framework.invokers.ObjectEvent” />
  </listener>  
 </listeners>
   
    <!– EVENT FILTERS –>
    <event-filters>
  <event-filter name=”GlobalsToEvent” type=”phpMachII.filters.GlobalsToEvent” />
    </event-filters>

    <!– EVENTS –>
 <event-handlers>
 
  <!– Main (landing page) –>
  <event-handler event=”showMain” access=”public”>
   <event-arg name=”page” value=”Main” />  
   <view-page name=”main” />
  </event-handler>
 
  <!– Process a few form variables for demonstration purposes –>
  <event-handler event=”processForm” access=”public”>
   <event-mapping event=”success” mapping=”showResults” />
   <event-mapping event=”noSuccess” mapping=”showMain” />
   <notify listener=”processForm” method=”validateForm” resultKey=”GLOBALS['results']” />
  </event-handler> 
 
  <!– Display results of form processing –>
  <event-handler event=”showResults” access=”public”>
   <event-arg name=”pageName” value=”Success” />
   <view-page name=”results” /> 
  </event-handler>
   
  <event-handler event=”exception”>
   <event-arg name=”page” value=”Failure” />
   <view-page name=”exception” />
  </event-handler>
 
 </event-handlers>

    <!– VIEWS –>
    <page-views>
 <page-view name=”main” page=”/views/main.php” />
 <page-view name=”results” page=”/views/results.php” />
        <!– Exception –>
        <page-view name=”exception” page=”/views/exception.php” /> 
    </page-views>
   
    <!– PLUGINS –>
    <plugins>
    </plugins>

</mach-ii>

Figure 3  The demo app’s mach-ii.xml structure

This file is the control center of a Mach-II application. As you can see by looking at our example’s mach-ii.xml file, the application is composed of properties, listeners, event-handlers, plugins and filters. mach-ii.xml is where you define the properties and relationships that make up your application. It can be found in an application’s /configure/ directory.

{mospagebreak title=Properties}

Let’s examine <properties> first.

<!– PROPERTIES –>
    <properties>
        <!– MACH II REQUIRED –>
        <property name=”defaultEvent” value=”showMain” />
        <property name=”exceptionEvent” value=”exception” />
        <property name=”applicationRoot” value=”/phpMachII” />
        <property name=”eventParameter” value=”event” />
        <property name=”parameterPrecedence” value=”form” />
        <property name=”maxEvents” value=”10″ /> 
    </properties>

Figure 4  mach-ii.xml <properties>

applicationRoot is an absolute or relative path responsible for directing the application to the display files in our app’s views directory. For our purposes it will be set to the current directory, “.”.

defaultEvent is the event you want called when the application first loads.

exceptionEvent is the event triggered for an unhandled exception. Built-in exception handling like this is good because it allows you to consider error handling from the very start. As you define events (we’ll get to that soon), you can build corresponding exception events seamlessly into your system.

eventParameter is the name of the Mach-II event we’ll be referencing in our code. Make it descriptive but easy to type.

parameterPrecedence is used to determine which request parameter to favor when there are simultaneous form and url ($_POST and $_GET) parameters. In our application we’ll want form as the default.

MaxEvents determines how many events are allowed per request.

For more on these Mach-II properties, see Mach-II Application Configuration.

{mospagebreak title=Event Handlers}

Let’s examine <event-handlers> in mach-ii.xml. As you already know, event-handlers are where you define the events triggered during a request. They describe the event names, and which views to associate with them.

<!– EVENT-HANDLERS –>
<event-handlers>
 
 <!– Main (landing page) –>
 <event-handler event=”showMain” access=”public”>
  <event-arg name=”page” value=”Main” />  
  <view-page name=”main” />
 </event-handler>
 
 <!– Process a few form variables for demonstration purposes –>
 <event-handler event=”processForm” access=”public”>
  <event-mapping event=”success” mapping=”showResults” />
  <event-mapping event=”noSuccess” mapping=”showMain” />
  <notify listener=”processForm” method=”validateForm” resultKey=”GLOBALS['results']” />
 </event-handler> 

 <!– Display results of form processing –>
 <event-handler event=”showResults” access=”public”>
  <event-arg name=”page” value=”Success” />
  <view-page name=”results” /> 
 </event-handler>
  
 <event-handler event=”exception”>
  <event-arg name=”page” value=”Failure” />
  <view-page name=”exception” />
 </event-handler>

</event-handlers>

Figure 5  mach-ii.xml <event-handlers>

Obviously our application needs to have a landing page. Since we named our default event showMain, we’ve defined a showMain event handler to receive that default event:

<!– Landing Page –>
<event-handler event=”showMain” access=”public”>
 <event-arg name=”page” value=”Main” />
<view-page name=”main” />
</event-handler>

Figure 6  Our landing page’s event-handler

Events can also be announced in <event-handler>, allowing very complex interactions between objects.

Inside <event-handler> is a node named <view-page>. This calls views defined in <page-views>. This is where display files are organized.

<!– PAGE-VIEWS –>
<page-views>
 <page-view name=”main” page=”/views/main.php” />
 <page-view name=”showResults” page=”/views/showResults.php” />
 <page-view name=”exceptionEvent” page=”/views/exception.php” />
</page-views>

Figure 7  page-views node

You’ll find yourself coding very specific event-handlers for each specific type of request. Similar to coding a method in a PHP class, event-handlers should be as concise and reusable as possible. It’s important to factor in the needs of your application when determining the granularity of your event-handlers.

The event handler we just defined will communicate with a <listener> we’ve created (below).

<!– LISTENERS –>
<listeners>
 <listener name=”processForm” type=”phpMachII.model.processForm”>
  <invoker type=”MachII.framework.invokers.ObjectEvent” />
 </listener>  
</listeners>

Figure 8  Listeners node

{mospagebreak title=Basic Coding Techniques}

Creating Listeners

Key to understanding Mach-II is discovering how to access variables passed in an event. For Fusebox developers the technique will feel similar to referencing form variables in the attributes scope: the framework does the conversion of form and url variables to properties of a Mach-II event (Event).

In our demo we post a form and process the variables with a Mach-II listener class. This class is a regular PHP class that extends MachII.framework.Listener:

class phpMachII_model_processForm extends MachII_framework_Listener
{
 function configure() {} // Called automatically by framework
}

Figure 9  ./model/processForm.php ~ A listener class

These variables are accessed by the listener class by calling Event like this:

$event->getArg(‘username’);

Figure 10  Accessing a value in Event

Listener classes are called by the framework using the mappings defined in the type attribute of a <listener> node (fig. 8). A method is defined in the event handler and then passed to the listener. Mach-II locates the listener class in its directory and calls the desired method. Finally, the listener receives the Event object and processes the request.

class phpMachII_model_processForm extends MachII_framework_Listener
{
 // Called automatically
 function configure() {}
 
 function validateForm($event) {
 
  // Retrieves values posted in form
  $thisUN = $event->getArg(‘username’);
  $thisPW = $event->getArg(‘password’);
 
  if (isset($thisUN) && isset($thisPW) && $thisUN == “admin” && $thisPW == “machii”) {
   $message = “Success”;
   $this->announceEvent(‘success’, $message);
  } else {   
   $message = “Failure”;
   $this->announceEvent(‘noSuccess’, $message);
  }
 
  return $message;
 }
 
}


Figure 11  ./model/processForm.php ~ accessing form variables from a listener by executing Event’s getArg method.

{mospagebreak title=Creating Views}

Views are added to an application by documenting their location in mach-ii.xml, then placing the files in their designated directories (in the demo app’s case the single directory is views).

Views are called in mach-ii.xml from their respective event handlers. In the demo application, when the form is posted and the processForm listener is called, a successful result calls the showResults event handler. showResults then calls a view.

<event-handler event=”showResults” access=”public”>
<event-arg name=”pageName” value=”Success” />
 <view-page name=”results” /> 
</event-handler>

Figure 12  ./config/mach-ii.xml ~ calling a view

It’s a good idea to create views that are as generic as possible so a single view can be used in many different event handlers. One obvious approach is to think of each view as a ‘component’ rather than a ‘page’. Mach-II is great for component-based layouts because <view-page> can specify its content be copied to a variable rather than display a view outright. In this way, multiple views can be generated in an event handler using the optional contentKey attribute:

<view-page name=”menu” contentKey=”GLOBALS['menu']” />
<view-page name=”subMenu” contentKey=”GLOBALS['subMenu']” />

Figure 13  ./config/mach-ii.xml ~ mapping views to global variables

The demo application’s results.php displays the result from the processForm listener’s validate method:

<? echo $GLOBALS['results']; ?>

Figure 14  ./views/results.php ~ Displaying the results from listener processForm

results.php also displays an <event-arg> defined in mach-ii.xml for the event showResults:

<? echo $event->getArg(‘pageName’); ?>

Figure 15  ./views/results.php ~ Displaying an <event-arg> defined in mach-ii.xml

The display file results.php:

<? $page = $event->getArg(‘pageName’); ?>

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
http://www.w3.org/TR/html4/loose.dtd“>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″>
<title><? echo $page; ?></title>
</head>

<body>
<table cellpadding=”0″ cellspacing=”0″>
 <tr>
  <td align=”left” valign=”middle”>
  <? echo $GLOBALS['results']; ?>
  </td>
 </tr>
</table>
</body>
</html>

Conclusion

There are many more topics to cover that are not within the scope of this article. Among them are plugins and filters that make it possible to manipulate Event data (you’ll see them in mach-ii.xml).

Mach-II offers developers a fast, efficient and easy-to-maintain framework for object-oriented applications in PHP.  At the time of the writing, Mach-II for PHP5 is in testing and will be available soon. For developers searching for a standardized design methodology for PHP web apps, Mach-II is a superior choice.

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort