Raw vs. cooked PHP $_POST variables


A little quirk of PHP $_POST var I encountered while fixing a Salesforce web-to-Lead bug. A WordPress site was using a form to submit user requests to the Salesforce web-service. The form that submitted the data had the following fields along with the others. The problem was with the multi-select field, only the last value selected in the multi-select was getting captured.

.
.
<select  id="days" multiple="multiple" name="days" >
<option value="Monday">Monday</option>
<option value="Tuesday">Tuesday</option>
<option value="Wednesday">Wednesday</option>
<option value="Thursday">Thursday</option>
<option value="Friday">Friday</option>
<option value="Saturday">Saturday</option>
<option value="Sunday">Sunday</option>
 </select>
.
.

After looking at the php code I found the problem, it was sending the values for the ‘days’ field using the following line.

<input type="hidden" name="days" value="<?= $_POST['days']; ?>" />

Which I naturally changed to the following. Note the array specifier for ‘days’.

foreach($_POST['days'] as $day) 
{                
    echo '<input type="hidden" name="days[]" value="'.$day.'" />';
}

and the html to:

<select  id="days" multiple="multiple" name="days[]" >
.
.

But which surprisingly did not work. Salesforce was still showing only the last value of the multi-select. After spending some confused time over the issue, it struck me that maybe the endpoint at Salesforce was using raw http post data. The post data that we get in the PHP $_POST variable is a ‘cooked’ version of the actual data sent by the browser. I say ‘cooked’ because PHP neatly stores the retrieved data in an associative array, ready for our easy consumption. I wrongly assumed that Salesforce was using the same $_POST variable (or the variants in whatever language they use for the backend) to access post data.

I removed the field array specifier [] as given below, and the code worked.

foreach($_POST['days'] as $day) 
{                
    echo '<input type="hidden" name="days" value="'.$day.'" />';
}

The point here being that we are so accustomed to one way of doing things, that when something different comes along it takes us by surprise.

Raw vs. cooked POST data in PHP

Here is a little more on the php $_POST var. Say you have something like the following HTML:

Example 1.

.
.
<input type="text" name="number" value="1" />
<input type="text" name="number" value="2" />
<input type="text" name="number" value="3" />
 
<input type="text" name="name" value="sam" />
.
.

If you do a var_dump($_POST) on the above data, you will get the following.

array
  'number' => string '3' (length=1)
  'name' => string 'sam' (length=3)

Notice that the ‘number’ field takes the last value of the three. Because as you know, PHP converts the POST variables in an associative array. So the last value overwrites the previous values in the ‘number’ field.

Whereas if you read the POST data using the following:

$postdata = file_get_contents("php://input");
var_dump($postdata);

You will get all the fields, although in an raw encoded form and not in an array. Below is the var_dump of the same.

string 'number=1&number=2&number=3&name=sam' (length=35)

So in conclusion, if you are working with POST data, do not assume that the program on the other end will process the data the same way as you do.

This site is a digital habitat of Sameer Borate, a freelance web developer working in PHP, MySQL and WordPress. I also provide web scraping services, website design and development and integration of various Open Source API's. Contact me at metapix[at]gmail.com for any new project requirements and price quotes.

7 Responses

1

Joseph Scott

September 20th, 2010 at 9:18 am

The content-type plays into this, your ‘cooked’ is referring to a content-type of ‘application/x-www-form-urlencoded’, which is what most forms get submitted as.

2

Chris

September 21st, 2010 at 6:12 am

Why is a post variable being inserted directly into an HTML tag without any kind of XSS protection here?

sameer

September 21st, 2010 at 8:56 pm

I’ve taken some liberties with the code to keep it simple and to the point. The actual code passes the variables through filters.

4

Webs Developer » Sameer Borate’s Blog: Raw vs. cooked PHP $_POST variables

October 21st, 2010 at 3:00 pm

[...] Borate as a new post to his blog today looking at some of the quirks he’s found when dealing with the $_POST superglobal in PHP. A little quirk of PHP $_POST [...]

5

ichandu

October 30th, 2010 at 3:09 am

Here cooked is in build variable and raw is user define variable.

———————————————-
learn php

6

Programowanie w PHP » Blog Archive » Sameer Borate’s Blog: Raw vs. cooked PHP $_POST variables

December 2nd, 2010 at 12:33 am

[...] Borate as a new post to his blog today looking at some of the quirks he’s found when dealing with the $_POST superglobal in PHP. A little quirk of PHP $_POST [...]

7

lawrence

May 3rd, 2011 at 5:33 am

Thanks for such a awesome post.Lot of things to learn

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
forex managed funds

Your thoughts

Sign up for fresh content in your email