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!
