Posting Data To PHP Using PostBackUrl - Part 2

by Saurabh 22. January 2008 20:55

Couple of years ago I did a blog post about using PostBackUrl with PHP. Although the code sample I used as illustration was a ASP.net page in it's simplest form, real world ASP.net pages aren't as simple as that. Almost any ASP.net web app that does a little more than just input some form data and flush it out would be doing so with the help of user controls and/or Master Pages. This complicates the HTML form entity names as it prefixes the user specified IDs with a number of _ (underscores) and $ signs.

So how can your PHP script read form data when element names ain't that simple anymore? Allow me to illustrate. Say we have a very basic Master page like this:

   1: <%@ Master Language="C#" AutoEventWireup="true" CodeFile="verybasic.master.cs" Inherits="Masters_verybasic" %>
   2:  
   3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4:  
   5: <html xmlns="http://www.w3.org/1999/xhtml" >
   6: <head runat="server">
   7:     <title>Untitled Page</title>
   8: </head>
   9: <body>
  10:     <form id="form1" runat="server">
  11:     <div style="clear: both; width: 100%; text-align: center;">MASTER HEADER. <br />
  12:         <asp:CheckBox ID="CheckBox1" runat="server" Text="Master's chkBox" /></div>
  13:     <div>
  14:         <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
  15:         </asp:contentplaceholder>
  16:     </div>
  17:     </form>
  18: </body>
  19: </html>

And we have a simple webform that uses the above master:

   1: <%@ Page Language="C#" MasterPageFile="~/Masters/verybasic.master" AutoEventWireup="true" CodeFile="p2php.aspx.cs" Inherits="p2php" Title="Post To PHP" %>
   2: <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
   3:     <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
   4:     <br />
   5:     <asp:Button ID="Button1" runat="server" Text="Submit" PostBackUrl="catchpostback.php" />
   6: </asp:Content> 

To read values of controls that are part of the Master page, the form itself or user controls, we will exploit the fact that in all such cases the form elements are "prefixed" with their containers and a bunch of underscores & dollar signs to the original developer specified control IDs. We can build a function similar to the one below:

   1: function getFormVar($var,$isPostBack = false)
   2: {
   3:     $retVal = "";
   4:     if($isPostBack == true)
   5:     {
   6:         $var = $var.'$';
   7:         foreach($_POST as $key => $r)
   8:         {
   9:             if(ereg($var,$key))
  10:                 return $_POST[$key];
  11:         }
  12:         return "";
  13:     }
  14:     else
  15:     {
  16:         if(isset($_REQUEST[$var]))
  17:         {
  18:             return $_REQUEST[$var];
  19:         }
  20:         else
  21:             return $retVal;
  22:     }
  23: }

To read the value of a control say TextBox1 you do something like this: $myvar = getFormVar("TextBox1",true);

The function getFormVar can read regular form elements as if they were from a PHP or HTML page, but when the 2nd parameter is set to true it loops through the POST variables and returns the value of the element of a ASP.net control (buried inside a user control or a master page) while you only specify the control ID you used in the ASP.net itself.

Some tidbits of this function you should know:

  • Although it gets you started, this function is not a complete solution. For example if the form element you want to read is part of a user control which has more than one instances on the page, it will fail flat out. But you can easily change the regex to enable reading in those cases.
  • I used ereg() instead of preg_match()  (comparatively fast) in my function as preg_match() might not be available on many setups.

A complete working demo can be downloaded from here.

There's one more thing that's pretty interesting IMO; ASP.net posts the entire form to the target page specified in PostBackUrl and of course __EVENTTARGET is empty!

Demo in action!

Tags: ,

Programming

A PHP4 version of PHPLiveX with ExternalJS property

by Saurabh 10. January 2008 20:51

The beauty of PHPLiveX is its astute simplicity that makes it among the best AJAX libraries for PHP. The dev team has now shifted to focus to PHP5, so ver. 2.3 is the last version for PHP4. Although a bit late, it was realized that for the sae of brevity and maintaining clean & tidy code support for outputting the javascript to a file rather than inline was made. Only a minor version too late for developers working on PHP4 code. So although folks using PHPLiveX 2.4 and above get to enjoy a more readable HTML output, the ExternalJS property is not supported by any official build for PHP4. But adding it is surprisingly easy!

I have been working to AJAXify an old PHP4 app on client insistence, this app is deployed on PHP4 and hence cannot use ExternalJS property. And I like my HTML to tidy up. So this is what I did to add ExternalJS to PHPLiveX 2.3 that was used in the project.

Start by adding a new property ExternalJS to the class. And then modify the Run method to something like this:

   1: function Run(){
   2:     $html = $this->CreateJS();
   3:     for($i=0;$i<count($this->FList);$i++){
   4:         $html .= $this->CreateFunction($this->FList[$i]);
   5:     }
   6:     if(empty($this->ExternalJS)){
   7:         echo "<script type='text/javascript' language='javascript'>" . $html . "</script>";
   8:     }
   9:     else{
  10:         if(!file_exists($this->ExternalJS)){
  11:             $fp = fopen($this->ExternalJS, "w");
  12:             if($fp != false){
  13:                 fwrite($fp, $html);
  14:                 fclose($fp);
  15:             }
  16:             else
  17:                 echo "<script type='text/javascript' language='javascript'>" . $html . "</script>";
  18:  
  19:  
  20:         }
  21:         echo "<script type='text/javascript' src='{$this->ExternalJS}'></script>";
  22:         }
  23: }

That's it! You can get rid of inline embedding of the PHPLiveX javascript. Similar to ver. 2.4 and above the call to Run() must not be inside the <script></script> tags. You can download a modded ver. 2.3 file with ExternalJS property from here.

You can further enhance this code a little more, like - Restrict the ExternalJS property to not use paths or you could restrict it to a bunch of desired paths.

Tags:

Programming