zbeng Posted November 22, 2006 Report Share Posted November 22, 2006 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 StartedTo 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<?phpsession_name('XULSession'); // Set session namesession_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 objectThe 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 Objectfunction 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 classfunction 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.ConclusionI 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. Quote Link to comment Share on other sites More sharing options...