Skip to main content

Use PHP to create XForms, Part 1: Creating a PHP XForms library

Tyler Anderson (tyleranderson5@yahoo.com), Freelance writer, Backstop Media
Tyler Anderson has graduated with a degree in computer science in 2004 and a Master of Science degree in computer engineering in December, 2005, both from Brigham Young University. Tyler is currently a freelance writer and developer for Backstop Media.

Summary:  This two-part article series is designed to get PHP developers up to speed in leveraging Web 2.0 XForms forms for their PHP forms development so that they can finally put their outdated Web 1.0 HTML forms away. This will be accomplished by creating a library of functions that generate XForms elements when called upon. In this article, Part 1 of a two-part series, developers will create the XForms library using PHP, allowing each function to take in parameters and output XForm elements.

View more content in this series

Date:  28 Aug 2007
Level:  Intermediate
Activity:  1841 views
Comments:  

Introducing a PHP XForms library

XForms is a great Web 2.0 language with exciting features that allow developers to create cutting-edge forms. And why not use it with PHP? PHP developers traditionally output HTML, which generally limits the capabilities of their forms. The problem with XForms, however, is that the file type is strictly XHTML, which is a more refined version of HTML in that the XML format is strict, and doesn't allow mistakes, mismatched tags being one of them. On top of that, there is regular syntax for XForms, which can make the learning curve of XForms a bit steep for some PHP developers who are possibly just learning the PHP language itself.

This series illustrates the creation of an XForms PHP library that PHP developers can call on to create the XForms elements for them. This will help remove the learning curve associated with learning XForms, and also help seasoned XForms developers leverage PHP in their Web application designs. It also avoids having to continually output explicit XHTML code, but instead simple calls are made to the XForms library to output the XHTML code for you. This ultimately speeds up development time by decreasing the possibility of mistakes in the resulting XHTML.

For this article you'll need PHP 5 and the Firefox XForms plugin (see the Resources section for download links). This article series was tested using PHP5 on WAMP5 Server Version 1.7.1 running Apache 2.

Now it's time to create the library.


Creating the library

In creating the PHP XForms library, you're going to use a class so that memory and local variables will be held within the class, eliminating extra variables and the associated mess in your code. First, you're going to start off with the class declaration and local variables, as shown in Listing 1.


Listing 1. Class declaration and local variables
                
<?php

class xforms_lib{
    var $namespace;
    var $namespaceXforms;
    var $namespaceEvents;

...

}

?>

Note here the name of the class, you'll need it for when you begin using it. The three variables shown above in Listing 1 are the three main namespaces you'll be using: The general XHTML namespace, the XForms namespace and the Events namespace.

Please note that the contructor (shown in Listing 2) and all subsequent methods are within the class declaration as shown in Listing 1.

As you begin to create the above file, save its name as xforms_lib.php, and place it in a subdirectory to your PHP code; call it lib, for example.

These class variables (shown in Listing 1) get set in the class's constructor, as shown in Listing 2.


Listing 2. The xforms_lib constructor
                    
    function xforms_lib($ns, $nsxforms, $nsevents){
        $this->namespace = $ns;
        $this->namespaceXforms = $nsxforms;
        $this->namespaceEvents = $nsevents;
    }

The above constructor takes in the values of these namespaces and saves them within the class. This eliminates having to keep entering them if you were planning on writing multiple XHTML files using your PHP XForms library, for example.

Next, you'll write the htmlTag method that returns the declaration for the opening HTML tag. This function simply outputs the HTML tag for you: <html xmlns="..." , ...>. See Listing 3.


Listing 3. Opening up the HTML tag
                
    function htmlTag($customNS='', $customNSnamespace=''){
        $xml = '<html';
        if($this->namespace != '')
            $xml .= ' xmlns="'.$this->namespace.'"';
        if($this->namespaceXforms != '')
            $xml .= ' xmlns:xforms="'.$this->namespaceXforms.'"';
        if($this->namespaceEvents != '')
            $xml .= ' xmlns:ev="'.$this->namespaceEvents.'"';
        if($this->customNS != '' && $this->customNSnamespace != '')
            $xml .= ' xmlns:'.$this->customNS.
                '="'.$this->customNSnamespace.'"';
        $xml .= ' >';
        return $xml;
    }

This function, shown in Listing 3, creates the opening HTML tag while placing the namespace values in the proper location within the HTML tag. The htmlTag method returns the following XHTML, as shown in Listing 4.


Listing 4. XHTML returned from htmlTag
                
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:xforms="http://www.w3.org/2002/xforms" 
      xmlns:ev="http://www.w3.org/2001/xml-events" >

You may now begin writing more functions that specify the contents of other XForms XHTML tags. Check out the submissionTag function in Listing 5. You'll use this function to have a submission XForms XHTML tag created for you.


Listing 5. The submissionTag function
                
    function submissionTag($id, $action, $method = 'post', $ref='',
                           $instance = '', $replace = ''){
        $xml = '<xforms:submission id="'.$id.'" action="'.$action.
            '" method="'.$method.'"';
        if($ref != '')
            $xml .= ' ref="'.$ref.'"';
        if($instance != '')
            $xml .= ' instance="'.$instance.'"';
        if($replace != '')
            $xml .= ' replace="'.$replace.'"';
        $xml .= " />";
        return $xml;
    }

See how this function takes in two required variables, $id and $action. The request method is defaulted to post. Thus, the first three variables, $id, $action and $method are returned in the resultant XHTML regardless of the values of the other variables. If ref, instance and replace are defined, then they also will be returned in the resultant XHTML. Passing a minimum of two variables, submissionTag('xformsTest', 'receive.php'), to this function returns the following XHTML: <xforms:submission id="xformsTest" action="receive.php" method="post" />.

Next you'll create the bindTag function, as shown in Listing 6. With this function you can create variable bind tags by changing the parameters to the function.


Listing 6: Creating the bindTag function
                
    function bindTag($nodeset, $relevant = '', $calculate = '',
                     $required = ''){
        $xml = '<xforms:bind nodeset="'.$nodeset.'"';
        if($relevant != '')
            $xml .= ' relevant="'.$relevant.'"';
        if($calculate != '')
            $xml .= ' calculate="'.$calculate.'"';
        $xml .= " />";
        return $xml;
    }

Here there is one absolutely required field, nodeset, and one of the other three, relevant, calculate, or required would need to be set to make the bind element functional.

Next, the dispatch tag, can be output with the following PHP, as shown in Listing 7. You'll use this function to have a dispatch tag created for you based on the inputs you send to the function.


Listing 7. The dispatch tag
                

    function dispatchTag($name, $target){
        $xml = '<xforms:dispatch';
        if($name != '')
            $xml .= ' name="'.$name.'"';
        if($target != '')
            $xml .= ' target="'.$target.'"';
        $xml .= " />";
        return $xml;
    }

This element has two required parameters, a name and a target, allowing you to dispatch XForms events like xforms-submit (example name) to submission (example target) elements.

The loadTag can be used to redirect to a different page, or display "pop-up"-type pages (pass 'new' as the $show variable). Take a look at the code in Listing 8. With this function you'll be able to create load tags on the fly in your PHP code.


Listing 8. The loadTag function
                
    function loadTag($resource = '', $ref = '', $show='replace'){
        $xml = '<xforms:load show="'.$show.'"';
        if($ref != '')
            $xml .= ' ref="'.$ref.'"';
        else if($resource != '')
            $xml .= ' resource="'.$resource.'"';
        $xml .= " />";
        return $xml;
    }

Note that $resource and $ref cannot both be defined. In Part 2 you'll add some error checking to make sure that both the $resource and $ref inputs aren't defined.

Next, create the insertTag function, as shown in Listing 9. This function allows you to automatically create insert tags within your PHP code, based on the data you send into the function.


Listing 9. The insertTag function
                
    function insertTag($nodeset, $at, $position = 'after'){
        $xml = '<xforms:insert nodeset="'.$nodeset.'" at="'.$at.
            '" position="'.$position.'" />';
        return $xml;
    }

This function takes in two required parameters with the optional and default $position parameter as a third one.

The next function, setvalueTag, takes in two required parameters, as shown in Listing 10. Using this function, you'll be able to create a wide variety of setvalue tags consistently.


Listing 10. The setvalueTag function
                
    function setvalueTag($ref, $value){
        $xml = '<xforms:setvalue ref="'.$ref.'" value="'.$value.'" />';
        return $xml;
    }

The inputTag function has a slightly different layout in that it has a nested XHTML label tag, as shown in Listing 11. The input function will allow you to create input boxes easily in your PHP code.


Listing 11. The inputTag function.
                
    function inputTag($ref, $label = ''){
        $xml = '<xforms:input ref="'.$ref.'">';
        if($label != '')
            $xml .= '<xforms:label>'.$label.'</xforms:label>';
        $xml .= "</xforms:input>";
        return $xml;
    }

Notice that a single required variable is input, $ref, and if $label is defined, then a nested label tag is placed within the input tag, which will be displayed beside the input to specify what should be entered there, 'Phone number: ', for example. You'll see this function in action in the testing section of this article.

Next up is the outputTag function, shown in Listing 12. Like, the input function, the output function allows you to easily create output tags in your PHP code.


Listing 12. The outputTag function
                
    function outputTag($value){
        $xml = '<xforms:output value="'.$value.'">';
        $xml .= '</xforms:output>';
        return $xml;
    }

This is a simple function to display the output of a variable to the screen, much like outputting HTML directly onto a regular Web page, except this one can change dynamically depending on the actual contents of the XML it references in its value attribute.

This next one, select1Tag, is slighly more complicated. Take a look at it in Listing 13. With the select1Tag function, you'll be able to much more easily create select1 elements, without having to bother if you have the syntax right.


Listing 13. The select1Tag function
                
    function select1Tag($ref, $label, $itemArray, $itemset,
                        $appearance = 'minimal'){
        $xml = '<xforms:select1 ref="'.$ref.'" appearance="'.
            $appearance.'">';
        $xml .= '<xforms:label>'.$label.'</xforms:label>';
        if(is_array($itemset)){
            $xml .= '<xforms:itemset nodeset="'.$itemset['nodeset'].'">';
            $xml .= '<xforms:label ref="'.$itemset['label'].'" />';
            $xml .= '<xforms:value ref="'.$itemset['value'].'" />';
            $xml .= '</xforms:itemset>';
        }
        else if(is_array($itemArray))
            foreach($itemArray as $item){
                $xml .= '<xforms:item>';
                $xml .= '<xforms:label>'.$item['label'].'</xforms:label>';
                $xml .= '<xforms:value>'.$item['value'].'</xforms:value>';
                $xml .= '</xforms:item>';
            }
        $xml .= '</xforms:select1>';
        return $xml;
    }

This function displays a complete select1 tag. If an array of labels and values are entered in the $itemArray element, then they will be iterated on and displayed in the menu. If an itemset is entered then that will instead be used to populate the contents of the menu.

This next function is a quick way to output XHTML comments in resultant XHTML code, as shown in Listing 14.


Listing 14. The comment function
                
    function comment($comment){
        $xml = '<!-- '.$comment.' -->';
        return $xml;
    }

Here the input, $comment, is placed in between a valid XHTML comment tag and returned.

This next method, instanceTag, returns a complete instance, as shown in Listing 15. This function allows you to easily create instance declarations from within your PHP code.


Listing 15. The instanceTag function
                
    function instanceTag($id = '', $instanceXML = '', $src = ''){
        $xml = '<xforms:instance';
        if($id != '')
            $xml .= ' id="'.$id.'"';
        if($src != '')
            $xml .= ' src="'.$src.'"';
        else if($instanceXML != ''){
            $xml .= '>'."\r\n";
            $xml .= $instanceXML;
            $xml .= "\r\n".'</xforms:instance>';
        }
        else
            $xml .= " />";
        return $xml;
    }

Either instance XML can be entered through the $instanceXML parameter, or a source URL in the $src parameter. The instance can be referenced later in other XHTML elements by its $id.

The submitTag function outputs a button that submits the specified instance data to a given URL. See Listing 16. With the aid of this function you'll be able to easily link submit buttons to submission tags within your PHP code.


Listing 16. The submitTag function
                
    function submitTag($submission, $label='Submit', $ref = ''){
        $xml = '<xforms:submit submission="'.$submission.'"';
        if($ref != '')
            $xml .= ' ref="'.$ref.'"';
        $xml .= ' >';
        $xml .= '<xforms:label>'.$label.'</xforms:label>';
        $xml .= '</xforms:submit>';
        return $xml;
    }

When you create a submission tag using the submissionTag function in Listing 5, you can enter the $id you used in Listing 5 here in the $submission parameter. This will link the submit element to the submission element.

The last eight functions open and close various tags: action, repeat, model, and trigger.


Listing 17. Opening and closing of the action, repeat, model and trigger tags
                
    function actionTagOpen($event){
        $xml = '<xforms:action ev:event="'.$event.'">';
        return $xml;
    }

    function actionTagClose(){
        $xml = '</xforms:action>';
        return $xml;
    }

    function repeatTagOpen($nodeset, $id = ''){
        $xml = '<xforms:repeat nodeset="'.$nodeset.'"';
        if($id != '')
            $xml .= ' id="'.$id.'"';
        $xml .= ' >';
        return $xml;
    }

    function repeatTagClose(){
        $xml = '</xforms:repeat>';
        return $xml;
    }

    function modelTagOpen($id = ''){
        $xml = '<xforms:model';
        if($id != '')
            $xml .= ' id="'.$id.'"';
        $xml .= ' >';
        return $xml;
    }

    function modelTagClose(){
        $xml = '</xforms:model>';
        return $xml;
    }

    function triggerTagOpen($ref, $submission = '', $label = 'default'){
        $xml = '<xforms:trigger ref="'.$ref.'"';
        if($submission != '')
            $xml .= ' submission="'.$submission.'"';
        $xml .= ' >';
        return $xml;
    }

    function triggerTagClose(){
        $xml = '</xforms:trigger>';
        return $xml;
    }

These functions are similar in style to the rest of the functions except they open and close tags that generally can have a few to several nested elements. The model element, for example, can have several nested bind, instance, and submission elements, and more. All you need to notice here is that the xxxxTagOpen version of each function opens the element's XHTML. For example, modelTagOpen() returns <xforms:model>. The close version, xxxxTagClose, closes the XHTML. For example, modelTagClose() returns </xforms:model>. The close versions generally do not take any parameters and the open versions are much like the other functions defined in this article except the XHTML tag is not closed, but open to allow other nested elements to be added before closing the corresponding XHTML tag.

Next you'll perform a proof of concept.


Simple test

Now to test what you've got so far. First you'll need to create a simple index.php file, as shown in Listing 18.


Listing 18. Proof of concept test file
                
<?php
header("Content-Type: application/xhtml+xml; charset=UTF-8");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
include('lib/xforms_lib.php');
$xformsDoc = new xforms_lib("http://www.w3.org/1999/xhtml",
                            "http://www.w3.org/2002/xforms",
                            "http://www.w3.org/2001/xml-events");

echo $xformsDoc->htmlTag();

?>
<head><title>XForms served via PHP</title>

<?php

 // display model here

$model1 = 'first';
$instance1 = 'firstInstance';
$xformsTestSubmit = 'xformsTest';
$instance1data = '<root xmlns=""><data1/></root>';

echo $xformsDoc->modelTagOpen($model1);

echo $xformsDoc->instanceTag($instance1, $instance1data);

echo $xformsDoc->submissionTag($xformsTestSubmit,
                               "receive.php", 'post');

echo $xformsDoc->modelTagClose();

?>

</head><body>

<?php

 // display form here

echo $xformsDoc->inputTag("instance('$instance1')//data1", 'input1: ');

echo $xformsDoc->submitTag($xformsTestSubmit);

?>

</body>
</html>

As this is a PHP file, you'll need to output to the browser that the data being written is actually intended to be of type application/xhtml+xml. This will allow Firefox to render the data as XForms appropriately. You'll make this happen by using the PHP header function, header(). Next, notice how the HTML tag is opened by creating a new xforms_lib class instance by passing in the three namespaces. Then, in the four statements under "// display model here,", you'll see a few variables defined which will serve as the IDs for various XForms instances and submission elements, etc., and also instance data. This is where you'll see the real power of using PHP and XForms comes into play, in the variable names that you can use and save or grab from the database in creating an XForms document.

You can also see the use of the modelTagOpen and modelTagClose functions in how the model tag is opened up, an instance and submission tag are written, and the model tag subsequently closed with a call to the modelTagClose function.

In the HTML body an input tag and submit tag are displayed by calling inputTag and submitTag, respectively, as shown in Figure 1.


Figure 1. Proof of concept
proof of concept

Now create a page to capture the submission data; receive.php is specifed above in Listing 18. So create a new file, receive.php, as shown in Listing 19.


Listing 19. Receiving and displayed posted form data
                
<?php

if (!isset($HTTP_RAW_POST_DATA))
   $HTTP_RAW_POST_DATA = file_get_contents("php://input");

echo str_replace('>', '><br />',
                 str_replace('<', '<', $HTTP_RAW_POST_DATA));

?>

Here the data is grabbed from the input to the script and displayed back to the screen.

Now you can type anything into the text box, and hit submit. Typing "testing testing 1 2 3" returns the following, as shown in Listing 20.


Listing 20. Receiving data
                
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xforms="http://www.w3.org/2002/xforms" 
             xmlns:ev="http://www.w3.org/2001/xml-events">
<data1>
testing testing 1 2 3</data1>
</root>

Excellent! Now move onto the summary to learn more about what's coming next.


Summary

You have now successfully created a PHP XForms library that will assist you in your XForms content creation and development.

Come back for Part 2, where you'll enhance the library you've just created with error checking and convenience methods. You'll also use the library in Part 2 to create a proof of concept form.



Download

DescriptionNameSizeDownload method
Part 1 sample codecode_part1.zip3KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Tyler Anderson has graduated with a degree in computer science in 2004 and a Master of Science degree in computer engineering in December, 2005, both from Brigham Young University. Tyler is currently a freelance writer and developer for Backstop Media.

Comments



Trademarks

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML
ArticleID=251428
ArticleTitle=Use PHP to create XForms, Part 1: Creating a PHP XForms library
publish-date=08282007
author1-email=tyleranderson5@yahoo.com
author1-email-cc=dwxed@us.ibm.com