PHP and WDDX Sessions

I l @ ve RuBoard

Using sessions is a powerful way to share data between PHP scripts. However, if you want to communicate with PHP scripts on another web server or with other web scripting languages (such as ASP) or web-aware applications, you quickly run out of options with sessions. Facilitating such communication requires other methods . This has been long addressed using special wire protocols such as RMI (Java), DCOM, and IIOP (CORBA).

Using such protocols can, however, be a problem. More often than not, such protocols are used within components of the web scripting language. For example, ASP uses COM components that communicate via DCOM. The wire protocols support a wide range of functions that for simple information exchange between web scripting languages are really just too complicated. Also, such wire protocols require their own network ports. This can cause security concerns at locations in your network, such as your firewall.

Several different companies have been aware of such shortcomings for a long time and have created several protocols to address these problems. It began with Dave Winer of UserLand software, who proposed a way of using XML to exchange data between applications (including web scripting languages) over HTTP. This solved all the problems faced by the wire protocols. HTTP was a standard wire protocol and didn't need a special port on the firewall. It was simple, and using XML meant it was text-based (thus small in size and easy to communicate). XML as a standard in its own right was widely understood by most applications.

Winer joined forces with Microsoft and eventually other companies to create what became known as the Simple Object Access Protocol (SOAP). (SOAP and PHP are discussed in Chapter 9, "PHP and Web Services.") A protocol also forked off from Winer's original idea to create XML-RPC (XML Remote Procedure Call). However, although both protocols were XML over HTTP protocols, they allowed for not only data exchange between applications, but also the capability to call functions on those applications. For just passing data between applications, SOAP and XML-RPC could be overkill.

Aside from the emergence of SOAP and XML-RPC, a third project was in development. Simeon Simeonov of the Allaire Corporation (now Macromedia) proposed a way of passing data between applications using XML over HTTP. Unlike the RPC capabilities of SOAP and XML-RPC, Simeonov proposed that his idea would only facilitate the passing of data between applications and nothing more. His idea became known as Web-Distributed Data eXchange (WDDX). WDDX development was sponsored by Allaire, which worked with third-party developer Nate Weiss to create an SDK to allow the exchange of WDDX data using Java, JavaScript, and COM.

Third parties added WDDX support to PHP, Perl, and Python. PHP support for WDDX was added to PHP and is maintained by Andrei Zmievski.

With WDDX, an application's variable types are converted (often referred to as serialized ) into a WDDX variable type. WDDX packets are the resulting XML file that WDDX creates to pass WDDX variable types between applications.

WDDX can convert most variable types that applications use, such as strings, integers, and arrays. After a variable has been converted to a WDDX variable type, it is ready for another application to pick up. In this case, the process works in reverse ”the application can convert a WDDX packet into a variable type that is native to it. This lets you share data types between applications without needing to worry about data type incompatibilities. WDDX handles it for you. You can see this by looking at a sample WDDX packet:

 <wddxPacket version='1.0'>  <header></header>  <data>  <string>Andrew</string>  </data>  </wddxPacket> 

Here you can see that WDDX has converted a string variable type containing the value Andrew into the following WDDX variable type:

 <string>Andrew</string> 

PHP's WDDX Functions

As mentioned earlier in this chapter, PHP has WDDX support built in, so you don't need to modify your PHP.ini file to start using WDDX.

PHP to ASP

Let's first look at how you can pass data from PHP to ASP using WDDX.

You create a WDDX packet by first serializing data into a WDDX packet and then presenting it.

A PHP Script to Serialize WDDX
 <?php  //define PHP data to send  $ValueToSend = "Andrew";  //convert PHP data to WDDX data  $wddxvar = wddx_serialize_value("$ValueToSend");  //output WDDX data  print("$wddxvar");  ?> 

You first set the data you want to serialize into a WDDX packet:

 $ValueToSend = "Andrew"; 

You then serialize that data:

 $wddxvar = wddx_serialize_value("$ValueToSend"); 

Finally, you present that data (see Figure 5.3):

Figure 5.3. A WDDX packet created by PHP displayed in Internet Explorer.

graphics/05fig03.gif

 print("$wddxvar"); 

Internet Explorer just shows the data within the WDDX packet. It doesn't show the surrounding XML structures. However, if you choose the view source option, you can see the WDDX packet's XML structures, as shown in Figure 5.4.

Figure 5.4. The XML structure of a WDDX packet created by a PHP script.

graphics/05fig04.gif

ASP Script to Deserialize WDDX Data

To receive the WDDX packet from the PHP script, you must load the packet into a variable within the receiving ASP script. None of the WDDX implementations (the WDDX COM component or PHP's WDDX functions) provides native ways of doing this. You must add this functionality using separate code. After you receive the WDDX packet, you can convert it into a data type native to the receiving application. This is called deserializing.

Using ASP, you can use a third-party COM component. A free COM component that allows such functionality is ASP Tear from http://www.alphasier-rapapa.com/IisDev/Components/ (also included with the WDDX SDK). However, you can use any COM component that has similar functionality.

 <%  set aspget = Server.CreateObject("SOFTWING.AspTear")  set wddxob = Server.CreateObject("WDDX.Deserializer.1")  'get WDDX data  wddxdata = aspget.Retrieve("http://localhost/phpbook/Chapter5_Sessions/WDDX/PHP/ graphics/ccc.gif two_wddxserver.php", Request_POST, "", "", "")  'convert WDDX data to ASP data  wddxvar = wddxob.deserialize(wddxdata)  'output ASP data  response.write "Hello " & wddxvar  set wddxob = nothing  set aspget = nothing  %> 

First, you must load the WDDX and ASP Tear COM objects into memory for use by ASP. Don't worry too much if you are not familiar with using COM objects. They are discussed in Chapter 7, "PHP, COM, and .NET."

 set aspget = Server.CreateObject("SOFTWING.AspTear")  set wddxob = Server.CreateObject("WDDX.Deserializer.1") 

Next you use ASP Tear to obtain the WDDX packet produced by the PHP server and load it into a variable:

 'get WDDX data  wddxdata = aspget.Retrieve("http://localhost/phpbook/Chapter5_Sessions/WDDX/PHP/ graphics/ccc.gif two_wddxserver.php", Request_POST, "", "", "") 

You deserialize the WDDX packet into a native data type for ASP:

 'convert WDDX data to ASP data  wddxvar = wddxob.deserialize(wddxdata) 

You then output the value:

 'output ASP data  response.write "Hello " & wddxvar 

Finally, you unload the COM objects from memory:

 set wddxob = nothing  set aspget = nothing 
ASP to PHP

PHP can also receive WDDX packets. Here you will see a PHP script obtaining a WDDX packet from an ASP script.

An ASP Script to Serialize WDDX
 <%  'define ASP data to send  ValueToSend = "Andrew"  set wddxob = Server.CreateObject("WDDX.Serializer.1")  'convert ASP data to WDDX data  wddxvar = wddxob.serialize(ValueToSend)  'output WDDX data  response.write wddxvar  set wddxob = nothing  %> 

This is very much the same as the serializing PHP script. First, you define the value you want to serialize in WDDX:

 'define ASP data to send  ValueToSend = "Andrew" 

You then load the WDDX COM object into memory, ready for use by ASP:

 set wddxob = Server.CreateObject("WDDX.Serializer.1") 

You then serialize the value into a WDDX packet:

 'convert ASP data to WDDX data  wddxvar = wddxob.serialize(ValueToSend) 

You then display the WDDX packet:

 'output WDDX data  response.write wddxvar 

Finally, you unload the WDDX COM object from memory:

 set wddxob = nothing 

If you look at the WDDX packet created by the serializing ASP script, you can see that it is no different from the WDDX packet created by the serializing PHP script (see Figure 5.5).

Figure 5.5. The WDDX packet created by an ASP script.

graphics/05fig05.gif

A PHP Script to Deserialize WDDX Data

The deserialize PHP script needs to do the same as the deserialize ASP script: It must convert the WDDX packet back into a native variable type for our script (in this case, a native variable type for PHP):

 <?php  //get WDDX data  $wddxdata = join ('', file  ('http://localhost/phpbook/Chapter5_Sessions/WDDX/ASP/one_wddxserver.asp'));  //convert WDDX data to PHP data  $wddxvar = wddx_deserialize("$wddxdata");  //output PHP data  print("Hello " . $wddxvar);  ?> 

You can obtain the WDDX packet from the ASP script using the PHP join function. To use the function in this manner, you must make sure that HTTP transparency is enabled in the PHP.ini settings file (the allow_url_fopen setting is enabled). (Note that HTTP transparency is enabled by default.)

 $wddxdata = join ('', file  ('http://localhost/phpbook/Chapter5_Sessions/WDDX/ASP/one_wddxserver.asp')); 

As before, you deserialize the WDDX packet into a native variable type:

 $wddxvar = wddx_deserialize("$wddxdata"); 

You then display the WDDX packet:

 print("Hello " . $wddxvar); 

ASP Arrays to PHP

WDDX also allows more-complicated data structures to be passed between applications. Here we will pass an array from an ASP WDDX script to a PHP script.

An ASP Script to Serialize an Array into a WDDX Packet
 <%  'define data as ASP array  dim names  names = Array("Andrew", "Emma", "Terry", "Mary", "Thomas")  set wddxob = Server.CreateObject("WDDX.Serializer.1")  'convert ASP array to WDDX array  wddxvar = wddxob.serialize(names)  'output WDDX array  response.write wddxvar  set wddxob = nothing  %> 

First, you create the array that you will convert to WDDX:

 dim names  names = Array("Andrew", "Emma", "Terry", "Mary", "Thomas") 

Note that currently, the WDDX COM object accepts only this definition of an array in ASP. The other definition, shown here, won't work:

 'dim names(5)  'names(1) = "Andrew" 

Next, you load the WDDX COM object into memory:

 set wddxob = Server.CreateObject("WDDX.Serializer.1") 

Then you convert the ASP array into WDDX:

 wddxvar = wddxob.serialize(names) 

Finally, you display the WDDX and unload the WDDX COM object from memory:

 response.write wddxvar  set wddxob = nothing 

As with all WDDX data, if you display the result of the ASP script, the WDDX packet is displayed, but with no surrounding XML structures (see Figure 5.6).

Figure 5.6. The array displayed as a WDDX packet.

graphics/05fig06.gif

However, if you view the content script's output, you can see the WDDX packet's XML structures, as shown in Figure 5.7.

Figure 5.7. The array displayed as a WDDX packet with surrounding XML structures.

graphics/05fig07.gif

It is interesting to note that it changes from the packets that you created previously and adds the following elements:

 <array length="5"> 

This indicates the size of the array and that you are passing an array between applications. Within the array element, you list all the elements in the array:

 <string>Andrew</string> etc. 

Therefore, the array structure within the WDDX packet is as follows :

 <array length='5'>  <string>Andrew</string>  <string>Emma</string>  <string>Terry</string>  <string>Mary</string>  <string>Thomas</string>  </array> 
A PHP Script to Deserialize an Array from a WDDX Packet

As with the previous examples, this PHP script obtains the WDDX packet from the ASP script and converts it into a native variable type. However, this time the PHP variable type you must obtain from the WDDX packet is an array.

 <?php  //get WDDX array  $wddxdata = join ('', file  ('http://localhost/phpbook/Chapter5_Sessions/WDDX/ASP/asparrays_server.asp'))  ;  //put WDDX array into PHP array  $wddxvar = wddx_deserialize("$wddxdata");  //iterate through PHP array  for ($arraycount=0; $arraycount<5; $arraycount++) { print("$wddxvar[$arraycount]\n\r<BR>");  }  ?> 

As in the previous example, you use the PHP join function to obtain the WDDX packet from the ASP script:

 $wddxdata = join ('', file  ('http://localhost/phpbook/Chapter5_Sessions/WDDX/ASP/asparrays_server.asp'))  ; 

You then deserialize the WDDX packet into a PHP array:

 $wddxvar = wddx_deserialize("$wddxdata"); 

To display the contents of the array, you loop through and display each item in the array:

 for ($arraycount=0; $arraycount<5; $arraycount++) { print("$wddxvar[$arraycount]\n\r<BR>");  } 

If you run this script, you see the displayed array, as shown in Figure 5.8.

Figure 5.8. The contents of an array converted from a WDDX packet.

graphics/05fig08.gif

PHP Arrays to ASP

Currently, it's not possible to use the script in reverse (PHP array to ASP via WDDX). The reason for this is that PHP uses a more recent version of the WDDX specification to represent arrays in WDDX. When it is deserialized, the array becomes represented in the application as a list of variables . You can show this by creating a WDDX packet from a PHP array:

 <?php  //create PHP array  $names = array("Andrew", "Emma", "Terry", "Mary", "Thomas");  //convert PHP data to WDDX data  $wddxvar = wddx_serialize_vars("names");  //output WDDX data  print("$wddxvar");  ?> 

If you run this script, you can see the WDDX packet it creates:

 <wddxPacket version='1.0'>  <header/>  <data>  <struct>  <var name='names'>  <array length='5'>  <string>Andrew</string>  <string>Emma</string>  <string>Terry</string>  <string>Mary</string>  <string>Thomas</string>  </array>  </var>  </struct>  </data>  </wddxPacket> 

You can obtain this packet using the following PHP script. Note that the array is named "names" in the WDDX packet. PHP uses this to reference the list of data when deserialized.

 <?php  $wddxdata = join ('', file  ('http://localhost/phpbook/Chapter5_Sessions/WDDX/PHP/phparrays_server.php'))  ;  $wddxvar = wddx_deserialize("$wddxdata");  while (list($key, $val) = each($wddxvar["names"])) { print "$key = $val\n<BR>";  }  ?> 

However, the WDDX COM object fails to load the WDDX packet when presented in this way by the PHP script.

Other PHP Functions for WDDX

PHP has a few other functions that can be useful when you're working with WDDX:

 <?php  $names = array("Andrew", "Emma");  $name2 = "Terry";  $name3 = "Mary";  $name4 = "Thomas";  $wddxpack = wddx_packet_start("PHP-WDDX");  wddx_add_vars($wddxpack, "names");  wddx_add_vars($wddxpack, "name2");  wddx_add_vars($wddxpack, "name3");  wddx_add_vars($wddxpack, "name4");  $wddxvar = wddx_packet_end($wddxpack);  //output WDDX data  $wddx_out = wddx_deserialize($wddxvar);  //iterate through PHP array  while (list($key, $val) = each($wddx_out["names"])) { print "$val\n<BR>";  }  print($wddx_out["name2"] . "<br>");  print($wddx_out["name3"] . "<br>");  print($wddx_out["name4"] . "<br>");  ?> 

PHP lets you modify the contents of a WDDX packet so that you can add and delete the contents of a WDDX packet as you see fit. To show this, you first create a PHP array containing the first two items in the packet:

 $names = array("Andrew", "Emma"); 

You then create the other items that make up the WDDX packet:

 $name2 = "Terry";  $name3 = "Mary";  $name4 = "Thomas"; 

You then create the WDDX packet:

 $wddxpack = wddx_packet_start("PHP-WDDX"); 

You then add the items to the WDDX packet and close it:

 wddx_add_vars($wddxpack, "names");  wddx_add_vars($wddxpack, "name2");  wddx_add_vars($wddxpack, "name3");  wddx_add_vars($wddxpack, "name4");  $wddxvar = wddx_packet_end($wddxpack); 

If you look at the contents of the WDDX packet, you can see how PHP has built it:

 <struct>  <var name='names'>  <array length='2'>  <string>Andrew</string>  <string>Emma</string>  </array>  </var>  <var name='name2'>  <string>Terry</string>  </var>  <var name='name3'>  <string>Mary</string>  </var>  <var name='name4'>  <string>Thomas</string>  </var>  </struct> 

It's interesting to note that PHP adds each data type (the array and other elements) separately to the WDDX packet. Also note that PHP uses named references for each data element added to the WDDX packet, such as names for the array, name2 for "Terry" , and so on.

 $wddx_out = wddx_deserialize($wddxvar); 

You deserialize the WDDX packet as normal. Because there are different data types within the WDDX packet, PHP handles the deserialized data differently. For the array, you use the list function that you used in the previous example:

 while (list($key, $val) = each($wddx_out["names"])) { print "$val\n<BR>";  } 

For the other data types, you use the reference contained in the WDDX file:

 print($wddx_out["name2"] . "<br>");  print($wddx_out["name3"] . "<br>");  print($wddx_out["name4"] . "<br>"); 

In effect, what is returned to PHP from the WDDX packet is a hash array (or named array). Each element in the array takes its named value from the reference in the WDDX packet.

I l @ ve RuBoard


PHP Programming for Windows
PHP Programming for Windows (Landmark (New Riders))
ISBN: 0735711690
EAN: 2147483647
Year: 2002
Pages: 99

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net