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:25
Avg. Score:3.4 ± 1.3
Reproduced:10 of 12 (83.3%)
Same Version:3 (30.0%)
Same OS:0 (0.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?
 [2021-11-11 16:08 UTC] gerardnico at gmail dot com
Why o why ?

We are in 2021 and this is so well known that I bang my head around it and discover that this is just because there is someone who has implemented it as a map and another one who don't dare to modify it in the next version.

Now my form needs to know the server technology before sending multipart post data.

Backward, awkward.

Not surprising that everybody is using Json.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue May 21 14:01:33 2024 UTC