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.
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.
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
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.
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.
| Description | Name | Size | Download method |
|---|---|---|---|
| Part 1 sample code | code_part1.zip | 3KB | HTTP |
Information about download methods
Learn
-
To learn more about integrating XForms and graphics using SVG see the article: Creating an XForms-based logo generator (developerWorks, ).
-
Get a basic introduction to XForms in Introduction to XForms, Part 1: The new Web standard for forms (Chris Herborth, developerWorks, September 2006).
-
Get the The PHP Manual.
-
Visit PHP.NET for PHP documentation.
-
For tutorials on learning to program with PHP, check out the developerWorks Learning PHP series.
-
Visit IBM developerWorks' PHP project resources to learn more about PHP.
-
Learn more about XForms submission events in the XForms tip: Using form submission events (Nicholas Chase, developerWorks, November 2006).
-
Find out how to accept XForms data in Java (Nicholas Chase, developerWorks, October 2006), Perl (Tyler Anderson, developerWorks, October 2006), and PHP (Nicholas Chase, developerWorks, October 2006).
-
IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
-
XML technical library: See the developerWorks XML Zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
-
developerWorks technical events and webcasts: Stay current with technology in these sessions.
-
Learn more about XForms in the IBM developerWorks XML zone.
Get products and technologies
-
Get PHP V 5.2.3.
-
Get the Firefox XForms plugin.
-
The XForms Recommendation is maintained by the W3C.
Discuss
Comments (Undergoing maintenance)





