php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #51633 Accept "post" input of multiple fields with the same name
Submitted: 2010-04-22 14:49 UTC Modified: 2011-01-28 01:09 UTC
Votes:15
Avg. Score:4.2 ± 0.9
Reproduced:10 of 11 (90.9%)
Same Version:2 (20.0%)
Same OS:1 (10.0%)
From: bart at tremby dot net Assigned:
Status: Wont fix Package: HTTP related
PHP Version: 5.2.13 OS: Ubuntu
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: bart at tremby dot net
New email:
PHP Version: OS:

 

 [2010-04-22 14:49 UTC] bart at tremby dot net
Description:
------------
I currently have to handle post data which is submitted as multipart/form-data and has multiple fields with the same name. The latter means I can't use $_POST (I only get the last of the fields with the same name) and the former means I can't use php://input or $HTTP_RAW_POST_DATA.

According to http://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.1.2.3 it's fine to have multiple fields with the same name.

The obvious answer to my problem would be to append "[]" to the end of the field names so that PHP parses them into an array. But in this case I don't have control over the data source.

And in fact the HTML4.01 specification says at http://www.w3.org/TR/html4/types.html#h-6.2
'ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".")'
So putting "[]" at the end of field names is actually against the HTML specification so it seems bad to require them.

So I have two suggestions here (let me know if I should file a separate request for the latter):

1. Whenever there is more than one field with the same name make an array, rather than only when the field name ends in "[]". This could of course cause issues with existing scripts which are being passed multiple values when they don't expect it or which are relying on a later field with the same name overwriting an earlier one, but I would wager that this is rare.

2. I could work around this right now if I could get php://input or $HTTP_RAW_POST_DATA, only they're not available since it's multipart/form-data. Why shouldn't the raw post data be available when it's encoded this way? It'd make it possible to work around broken post data (in this case as far as I can see the post data is fine according to the spec but I can imagine having to deal with actual broken data).


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-27 11:16 UTC] t33th4n at gmail dot com
Source is:
<form method="get">
  <select name="something" multiple size="2">
    <option selected="selected" value="1">One</option>
    <option selected="selected" value="2">Two</option>
    <option value="3">Three</option>
  </select>
  <input type="submit" value="Try it" />
</form>

Expected result: Multiple values for same key, possibly in an array or comma separated string (i would prefer this and more easy to implement in php core i think :).
Current result: In browser address, the values appears, but php does not provides those values.

PHP Version: 5.3.5
Apache version: 2.2.11.0
 [2011-01-27 12:19 UTC] t33th4n at gmail dot com
In the meantime, i made a workaround of the problem
process_browser_params(); must be called in the very beginning of things.
After this, $_NEWREQUEST will containt both get and post parameters.

function process_browser_params()
{
  GLOBAL $_NEWREQUEST;
  $datas = explode('&', file_get_contents("php://input"));
  for($i=0;$i<count($datas);$i++)
  {
    $datas[$i] = explode('=', $datas[$i]);
  }
  unset($data);
  for($i=0;$i<count($datas);$i++)
  {
    if ((count($data)>0) && (array_key_exists($datas[$i][0], $data)))
    {
      $data[$datas[$i][0]] = $data[$datas[$i][0]].",".urldecode($datas[$i][1]);
    } else
    {
     $data[$datas[$i][0]] = urldecode($datas[$i][1]);
    }
  }
  $_NEWREQUEST = $data;
}

Enjoy
 [2011-01-27 12:23 UTC] bart at tremby dot net
That workaround is fine for data sent as application/x-www-form-urlencoded but won't work if the data is sent as multipart/form-data.
 [2011-01-28 00:44 UTC] aharvey@php.net
-Status: Open +Status: Wont fix
 [2011-01-28 00:44 UTC] aharvey@php.net
This would absolutely shred backward compatibility: there's already a
documented way of accomplishing this with [], and although HTML allows
multiple values regardless of name, PHP doesn't, and this behaviour is
well established.

Closing won't fix.
 [2011-01-28 01:09 UTC] bart at tremby dot net
Could you comment the second suggestion I made?

That is, why is php://input unavailable when data is sent as multipart/form-data?
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Fri Feb 15 19:01:25 2019 UTC