Jump to content
zbeng

Creating XUL applications with PHP

Recommended Posts

This article introduces some of the technical aspects of getting XUL clients hooked up with PHP.

What is XUL?

XUL, or the XML User Interface language, is the common thread running through all Mozilla-powered applications – both desktop and web-based. XUL is a way to describe an application's user interface using XML. XUL is similar in many ways to HTML, while borrowing from, yet not exactly imitating its syntax. (It is possible to mix HTML tags into a XUL application.)

Getting Started

To start off with, we need a simple XUL file that contains a form. This form could consist of anything, but for this example, I will be using a simple Login form that you might be familiar with while building web applications.

In the form listed below, notice that the Sign in button references the loginCmd listed in the <commandset></commandset> section above. Keeping your javascript commands out of the main XUL body helps promote readability and reusability.

The XUL file

<?xml version="1.0"?>

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window

id="phpServer-Communication-test"

title="PHP Server Communication Test"

orient="horizontal"

xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<script src="js/main.js" type="application/x-javascript"></script>

<commandset>

<command id="loginCmd" oncommand="doLogin()"/>

</commandset>

<keyset>

<key id="login-button" keycode="VK_RETURN" command="loginCmd"/>

<key id="login-button" keycode="VK_ENTER" command="loginCmd"/>

</keyset>

<vbox flex="1" align="center" pack="center" style="background-color:#444">

<label value="XUL Login Authentication Example" style="font-size: 16px"/>

<label value="Click the login button to see the response from the server" style="font-size: 14px"/>

<grid style="background-color:#999;padding:40px;border-top: 2px solid #bbb; border-left: 2px solid #bbb; border-bottom: 2px solid #555;border-right: 2px solid #555">

<columns>

<column/>

<column/>

</columns>

<rows>

<row>

<label value="Username"/>

<textbox id="loginUser" style="width:10em"/>

</row>

<row>

<label value="Password"/>

<textbox id="loginPass" style="width:10em" type="password"/>

</row>

<row>

<spacer/>

<button label="Sign in" command="loginCmd"/>

</row>

</rows>

</grid>

</vbox>

</window>

The PHP Server simply echoes the value’s passed to it to the screen as well as some text to prove it’s the real thing (a call to the date function).

The PHP file

<?php

session_name('XULSession'); // Set session name

session_start();

echo "Server Time is: ".date("m/d/Y H:i:s")."n";

echo "$_POST = n";

print_r($_POST);

echo "$_GET = n";

print_r($_GET);

// Watch these...

echo "$_COOKIE = n";

print_r($_COOKIE);

echo "$_SESSION = n";

print_r($_SESSION);

if ( $_GET['username'] == 'root' && $_GET['password'] == 'topsecret' ) {

$_SESSION['username'] = $_GET['username'];

$_SESSION['password'] = $_GET['password'];

}

?>

Note the <pre> tags aren’t needed around the print_r’s because javasript does not squish white space like browsers do.

The session name (XULSession) turns up in the $_COOKIE array. In other words, the XUL client is doing the same as a browser does between requests (via the XMLHttpRequest).

Also if you enter the username as “root” and the password as “topsecret”, it will show up in the $_SESSION array on the next request (you need to “login” two times to see this).

In other words you can use PHP‘s sessions to lock the remote XUL client out of your PHP application until a valid username and password is provided. Users will still have the remote client running (unlike normal browser clients where you send an HTTP redirect to an HTML login form) but as long as you keep the real Business Logic in PHP, requiring a valid session to execute it, there should be no real issues here. The XUL client would be unable to do any harm.

The real action takes place in the main.js file. Here’s an excerpt containing the doLogin function.

The Javascript File

/* main.js */

function doLogin() {

var username = document.getElementById('loginUser').value;

var password = document.getElementById('loginPass').value;

req = new phpRequest();

req.add('action','doLogin');

req.add('username',username);

req.add('password',password);

var response = req.execute();

alert(response);

}

Now that all the files are in place, we are going to run the script. Starting with the blank form, simply enter in a sample username and password. Press the ‘Sign in’ button and witness the response from the server. Next, press the ‘Sign in’ button and witness the response from the server.

How does it work?

After the “Sign in” button is clicked, the doLogin method in main.js is called. In it, the username and password have been pulled from the XUL form via the Javascript DOM.

After we have pulled in the username and password into scope, a new ‘phpRequest’ object is instantiated. The phpRequest is a javascript object that takes care of the details of connecting and talking to a PHP server. We will talk on phpRequest later in this article. The add() function simply takes a key/value pair that contains data that will be sent to the php script.

After all key/value pairs have been added to the request, the execute method is called and the request is actually made to the server. The entire HTTP response body is returned by the execute method. The response is then echoed to the screen to provide feedback that our method actually worked.

A word about security: The javascript security model limits what can be connected. It means that if you upload this XUL file and javascript file to a php server, your server MUST also be on the same server and the path to the server must be relative.

In other words: XUL URL: http://some.server/xul/xulform.xul Server URL: /xul/server/server.php (must be relative)

The second way to connect to a remote server would be to install your XUL package into your local chrome directory. When you install the package locally, you can connect to any server via an absolute URL.

More information about the javascript security model can be found on the web.

The phpRequest object

The phpRequest object is where all the magic happens. It provides a programmer friendly interface to the implementation details of the XMLHttpRequest object that actually makes the call to the php page.

The Javascript:

const SERVER_URL = "/xul/server.php";

//Start phpRequest Object

function phpRequest() {

//Set some default variables

this.parms = new Array();

this.parmsIndex = 0;

//Set the server url

this.server = SERVER_URL;

//Add two methods

this.execute = phpRequestExecute;

this.add = phpRequestAdd;

}

function phpRequestAdd(name,value) {

//Add a new pair object to the params

this.parms[this.parmsIndex] = new Pair(name,value);

this.parmsIndex++;

}

function phpRequestExecute() {

//Set the server to a local variable

var targetURL = this.server;

//Try to create our XMLHttpRequest Object

try {

var httpRequest = new XMLHttpRequest();

}catch (e){

alert('Error creating the connection!');

return;

}

//Make the connection and send our data

try {

var txt = "?1";

for(var i in this.parms) {

txt = txt+'&'+this.parms.name+'='+this.parms.value;

}

//Two options here, only uncomment one of these

//GET REQUEST

httpRequest.open("GET", targetURL+txt, false, null, null);

//POST REQUEST EXAMPLE

/*

httpRequest.open("POST", targetURL+txt, false, null, null);

httpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

*/

httpRequest.send('');

}catch (e){

alert('An error has occured calling the external site: '+e);

return false;

}

//Make sure we received a valid response

switch(httpRequest.readyState) {

case 1,2,3:

alert('Bad Ready State: '+httpRequest.status);

return false;

break;

case 4:

if(httpRequest.status !=200) {

alert('The server respond with a bad status code: '+httpRequest.status);

return false;

} else {

var response = httpRequest.responseText;

}

break;

}

return response;

}

//Utility Pair class

function Pair(name,value) {

this.name = name;

this.value = value;

}

Javascript’s object model is a little different. Instead of defining a ‘class’ in php, you create functions and then link them together. That is what is happening in the phpRequest function. Several variables are set including the server URL that is defined by a constant variable on the first line of the program. After the variables are defined, the literal function names are assigned to local variables. When that is done, they become callable methods inside the object. There are several other ways to do this within javascript, please refer to the javascript core specification for details.

The phpRequest maintains an internal array of Pair objects. Because javascript does not have the same array support that php does, a workaround is needed to create a key/value array. The Pair object performs this task very well.

The method where the action really happens is the phpRequestExecute method. It contains the code that helps us to connect to a php server from our javascript. The javascript object that allows us to connect to another script via HTTP is the XMLHttpRequest object. It is an internal javascript object that can be used to return XML (or HTML) documents from an external source. More information about the XMLHttpRequest object can be found on the XULPlanet website (http://www.xulplanet.com/references/elemref/ref_XMLHttpRequest.html).

After the XMLHttpRequest object has successfully been instantiated, the url is simply created by looping over the internal array of key/value pairs. Now, you can use either GET or POST to send data to the server. I have included code for both methods. The same URL is passed, but there is one difference. When you send a POST request, you have to set the content type to be ‘application/x-www-form-urlencoded’ so the web server you are sending it to will know that you are sending a POST request. There are more tricks if you need to send larger amounts of data, but they are beyond the scope of this article.

After you set the url, you must call the XMLHttpRequests send method. This is what actually sends the request to the server. After a response from the server is received, it is stored in the XMLHttpRequest’s responseText variable and available for use.

Conclusion

I have attempted to provide an overview of the advantage of combining XUL with PHP to create a rich web application, and the specific code involved with doing so. Hope you have a great time creating high end applications using these technologies.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...