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>

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.

  '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");

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.


7 thoughts on “Raw vs. cooked PHP $_POST variables

  1. 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.

Comments are closed.