Avatar of Rob
RobFlag for Australia asked on

Checkbox form data relating to server side scripts

I wanted to find out what's going on with how checkboxes are submitted as form data as it seems that there is a difference between server side scripts.

This question was spurned from https://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_28226128.html#a39457253

This link: http://www.w3.org/TR/html401/interact/forms.html#checkbox
states:
Several checkboxes in a form may share the same control name. Thus, for example, checkboxes allow users to select several values for the same property. The INPUT element is used to create a checkbox control.

But it also says under the section "Successful Controls" http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
All "on" checkboxes may be successful.
Now what does that mean??

It doesn't seem to be the case for PHP, where only the last checkbox's value with the same name is received : http://phpfiddle.org/main/code/td9-usz

But it is the case for coldfusion. (see referring link to the other question above), this involves submitting form data to coldfusion that will handle checkboxes with the same name (without [ ]) and compile them into a comma delimited string when the form is submitted.

So my question(s) are:
Is PHP doing what it should and am I missing something in my phpfiddle example?
How does .NET applications (and other server based technologies) handle the same form data and do they require the array indicators [ ]?
Web Languages and StandardsPHP.NET Programming

Avatar of undefined
Last Comment
Rob

8/22/2022 - Mon
Dave Baldwin

I avoid giving checkboxes the same names because it can be confusing.  Here are two files that show what happens with PHP.

Form page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>PHP checkbox test</title>
</head>
<body>
<h1>PHP checkbox test</h1>
<form action="postdump.php" method="post">
<input type="checkbox" name="same" checked="checked" />Same<br>
<input type="checkbox" name="same" checked="checked" />Same<br>
<input type="checkbox" name="same" checked="checked" />Same<br>
<input type="checkbox" name="same" checked="checked" />Same<br>
<input type="checkbox" name="same2[]" checked="checked" />Same<br>
<input type="checkbox" name="same2[]" checked="checked" />Same<br>
<input type="checkbox" name="same2[]" checked="checked" />Same<br>
<input type="checkbox" name="same2[]" checked="checked" />Same<br>
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

Open in new window


PHP Post page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>POST Gen</title>
</head>
<body>
<pre>
<?php 
var_dump($_POST);
foreach($_POST as $key => $value) {
    echo $key.' = '.$value."<br>";
}

?>
</pre>
</body>
</html>

Open in new window

ASKER
Rob

Thanks Dave, that's what I do as well.  your script gave me the following output:

Array
(
    [mytext] => 
    [same] => on
    [same2] => Array
        (
            [0] => on
            [1] => on
            [2] => on
            [3] => on
        )

)

Open in new window

That confirms that PHP requires the use of [ ] to get each checked checkbox's value.

What I want to know is why PHP does that when the w3 standards state that checkboxes can share the same name.
SOLUTION
Dave Baldwin

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER
Rob

Thanks Dave, appreciate the input.
So my question that still stands is why does php not follow the standards?
Also keen to know what .net does
Your help has saved me hundreds of hours of internet surfing.
fblack61
Ray Paseur

PHP does follow the standards!  But the terms of art may be confusing.  A checkbox is "successful" if the control provides data to the action script  This is the same thing as saying a checkbox is "checked."  Checkboxes can share the same name, but so can all kinds of input controls.  The name becomes the array index in the request (GET or POST) and the last value of the same name becomes the value that is presented to the action script.  Experiment with this script for an example:
http://www.laprbass.com/RAY_temp_tagit.php

<?php // RAY_temp_tagit.php
error_reporting(E_ALL);
echo '<pre>';

// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28228399.html

// SHOW THE REQUEST DATA
var_dump($_GET);

// CONSTRUCT A FORM WITH MULTIPLE CHECKBOXES THAT HAVE THE SAME NAME
$form = <<<EOD
<form>
Choose Color:
R <input name="color" value="red" type="checkbox" />
G <input name="color" value="grn" type="checkbox" />
B <input name="color" value="blu" type="checkbox" />
<input type="submit" />
</form>
EOD;
echo $form;

Open in new window

An input control that is a scalar, such as "color" in the script above, will return one value for each named attribute.  You can use array input controls to get multiple values by using the array[] notation in the name= attribute of the input control tag.  This is perhaps more commonly used with <select multiple> but it works just fine with checkboxes.
http://www.laprbass.com/RAY_temp_tagit_array.php

<?php // RAY_temp_tagit_array.php
error_reporting(E_ALL);
echo '<pre>';

// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28228399.html

// SHOW THE REQUEST DATA
var_dump($_GET);

// CONSTRUCT A FORM WITH MULTIPLE CHECKBOXES THAT HAVE THE SAME NAME
$form = <<<EOD
<form>
Choose Color:
R <input name="color[]" value="red" type="checkbox" />
G <input name="color[]" value="grn" type="checkbox" />
B <input name="color[]" value="blu" type="checkbox" />
<input type="submit" />
</form>
EOD;
echo $form;

Open in new window

One of the confusing things about checkboxes is the nature of "successful" inputs.  A checkbox that is not checked is not "succesful" and all that this means is that it provides no influence on the input data for the request.  This subtlety gives us an interesting way to provide a default value for a request variable.  We can combine a hidden control with a checkbox control of the same name.
http://www.laprbass.com/RAY_temp_tagit_hidden.php

<?php // RAY_temp_tagit_hidden.php
error_reporting(E_ALL);
echo '<pre>';

// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28228399.html

// SHOW THE REQUEST DATA
var_dump($_GET);

// CONSTRUCT A FORM WITH MULTIPLE CHECKBOXES THAT HAVE THE SAME NAME
$form = <<<EOD
<form>
Choose Color:
  <input name="color" value="???" type="hidden"   />
R <input name="color" value="red" type="checkbox" />
G <input name="color" value="grn" type="checkbox" />
B <input name="color" value="blu" type="checkbox" />
<input type="submit" />
</form>
EOD;
echo $form;

Open in new window

Some more "fun with checkboxes" examples are available here.
https://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_5450-Common-Sense-Examples-Using-Checkboxes-with-HTML-JavaScript-and-PHP.html

Feel free to copy any of these forms and try submitting to a .net site.  I am nearly 100% certain that you will see similar behaviors.
Dave Baldwin

"why does php not follow the standards? "

Like Ray also said, PHP does follow the standards.  It accepts all those inputs with the same name and treats them exactly like PHP treats any other variables.  You can not get PHP to act any differently with a variable in any other circumstance.
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Dave Baldwin

Classic ASP returns them both as a comma-separated list.
same: 1, 2, 3, 4

same2[]: 1, 2, 3, 4

submit: Submit

Open in new window


"which behavior is actually the norm."

I wouldn't look at it that way.  I would expect each language to handle them according to it's own standard methods.  It seems to me that PHP is acting exactly as it should according to the way it handles variables.  

I'm not so sure that CF and ASP aren't making 'special rules' for handling the info from the server which is where these values come from.  The HTTP Request with the POST data goes to the web server which hands the data off to the language interpreter.  If you wrote...

same = 1
same = 2
same = 3
same = 4

in Classic ASP, you would end up with '4', not '1,2,3,4'.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER CERTIFIED SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
_agx_

@Dave - Sure, each language has its own rules. I'm just comparing the behaviors against developer expectation (admittedly mine may be biased)

> 1) Classic ASP returns them both as a comma-separated list.
> 2) If you wrote... in Classic ASP, you would end up with '4'

I'm not sure I follow the 2nd part.  Which code returns the csv list and which returns "4"?

(EDIT) @Ray - Thanks, let me take a look.
_agx_

> So my conclusion is that the "norm" is language-dependent.

It does seem that way. I guess it makes sense in that the specs only state what should be transmitted. How the server side language handles it is up to them.

I took a look at JSP and it's handling more similar to PHP:

request.getParameter();
You should only use this method when you are sure the parameter has only one value. If the parameter might have more than one value, use getParameterValues(java.lang.String).

If you use this method with a multivalued parameter, the value returned is equal to the first value in the array returned by getParameterValues.

request.getParameterValue();

Returns an array of String objects containing all of the values the given request parameter has, or null if the parameter does not exist.

If the parameter has a single value, the array has a length of 1.

So it looks like we have 2 languages that convert multiple values to a csv (CF, ASP Classic)  and two which don't (PHP, JSP).
Ray Paseur

Yes, that looks correct to me.  And we have a whole bunch of other languages we haven't tested yet (C, Perl, Python, Ruby, and TCL would be popular).
http://en.wikipedia.org/wiki/Server-side_scripting
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Dave Baldwin

If you have this code in ASP, it will print '4' like it would in PHP, not a comma-separated list.
<%
same = 1
same = 2
same = 3
same = 4
Response.Write(same)
%>

Open in new window

_agx_

@Dave - Ahh, ok.  In the case of a simple assignment, that's the result I would expect. ie Successive statements override the previous one, preserving only the last assignment value.

> (C, Perl, Python, Ruby, and TCL would be popular).
@Ray_Paseur - Well .. I've been looking for an excuse to try Python :) (I'll have to see if I still remember any Perl. Last time I used it was years ago)
Dave Baldwin

I tried to make a Perl version of my POST list program but apparently I don't know enough Perl.  All I was able to get using CGI was '1234' for both variables and that's not very useful so I would assume there is another way and I just don't know about it.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
Rob

Great discussion everyone! Exactly what out was hoping to achieve by this :-)
Let me digest what's been posted and I'll get back to you
Dave Baldwin

One of the things that I noticed is that only PHP considers the square brackets '[]' to be 'array' indicators.  ASP and Perl seem to think that they are just part of a name for a single variable.
ASKER
Rob

I go back on what i said re PHP following the standards (Thanks @Ray).  I've found this is not so much about following the standards as it is about how each language interprets it.  

Though interesting to note there isn't a standard way of receiving GET / POST data across languages so extra care would have to be taken on how each parses the data (eg array, comma sep string, single value etc).

Back to this issue, the browser does what it's meant to and submits all the form data, including the "duplicate" checkboxes (as Ray has shown re the querystring example above).  

I've found here: http://www.php.net/manual/en/faq.html.php#faq.html.arrays that the [ ]
reads as if it is a PHP only feature
PHP's "array from form element" feature
.  So it's PHP specific and not mentioned anywhere in the w3 standards (as expected if PHP only). As @Dave rightly said, other languages (tested) just interpret it as just another name so CF / ASP would do the comma separated list for multiple checkboxes with the same name as they did before however this time you would access the variable like Request.Form("color[]") if I've understood this correctly.

Curious though the definition from w3:
Several checkboxes in a form may share the same control name. Thus, for example, checkboxes allow users to select several values for the same property. The INPUT element is used to create a checkbox control.

The problem I have is that "art form" that @Ray has referred to.  If PHP followed the w3 structure word for word (there's no mention of "array(s) from form element(s) using [ ]") then I would expect as a developer to receive an array, as it seems would @_agx_.  
Don't get me wrong, I agree with the execution and assignment of how PHP works eg each successive assignment is overwritten, however this is data received externally from PHP in a specfied and well documented structure on how the data is structured and laid out.

PHP it seems has decided to make up their own way, rather than be in line what CF, ASP Classic and JSP do (from reading above, JSP will give you the all the values for a single element, you just have to use the right function call "getParameterValues(), which I would use regardless to ensure I got all the values I was after").

The issue I have is rather than taking the structure as it is presented, PHP have said you need to change the structure and add the [ ] if you want the form data read as an array, even though the specification doesn't say this.

Don't get me wrong, I actually think PHP have the right idea with the addition of [ ] but I think it should be consistent across languages and specified in the w3 specification before it is implemented.

At the end of the day, you guys have answered my question and I got the kind of great discussion I was after from the EE brains.  I'll accept the answers that got me there but I'm more than happy to keep the discussion going if there's any more thoughts on this.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER
Rob

Thanks again everyone for the very informative insight.
Dave Baldwin

I think it should be consistent across languages and specified in the w3 specification before it is implemented.

The first thing is that W3C is specifying what the browser should be doing... Nothing else.  Second is that those values are sent to the Web Server.  It's the Web Server that passes them on to the language like ASP and PHP.

I can't find a function that will return the raw CONTENT string in PHP.  It is not listed in $_SERVER variables even under ALL_HTTP.
_agx_

Though interesting to note there isn't a standard way of receiving GET / POST data across languages so extra care would have to be taken on how each parses the data (eg array, comma sep string, single value etc).

Well, there is .. in a sense ;-) The specs lay out what should be transmitted by the browser, and how it should be formatted. So regardless of what  syntax is used, every server side language will look for the same delimiters when parsing the raw request data.  I guess what's missing in the overall picture is a standard on how server side languages should represent those values - once it has them. Apparently that decision is left up to the server side language.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
Rob

The first thing is that W3C is specifying what the browser should be doing
I agree but That's also my point, the browser is sending data in a certain structure regardless of server and language.  However PHP is bending the rules by requiring [ ].

Really I'd like to see it accept both methods, with or without [ ] and any elements with the same name would be seen as an array.  That would make sense as that's how it's intended in the HTML it should be expected then same way on the server.
ASKER
Rob

Good point about representation _agx_. I like that :)
Dave Baldwin

"However PHP is bending the rules by requiring [ ]. "  That's your interpretation and I don't agree with you.  Those rules you are referring to stop when the data is received by the server.  And after 20 years of the World Wide Web, nothing you say will change that.

For you to say "that's how it's intended in the HTML" is you misstating what you read in the W3C standard.  It does not say Anything about arrays (as you pointed out earlier), it only says that the data for all of the checked boxes that are checked should be sent.  Nothing more.  Nothing about what to do with it or how it is handled.

"Apparently that decision is left up to the server side language. "

Clearly it is.  If everything was going to be the same, we'd be stuck with Classic ASP still... but 'real' programmers, UNIX programmers, would be doing everything in C instead of one of the interpreted languages.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ASKER
Rob

Ok we'll have to agree to disagree on this. I'm not misstating anything, and ill quote it again


Several checkboxes in a form may share the same control name. Thus, for example, checkboxes allow users to select several values for the same property

Tell me how that isn't an array?

The server side languages use the spec because it would lead to unexpected results if they didn't.

I'm not saying everything about a language should be the same as others that's not practical or useful.  What I am saying is they should parse data in an similar way given a fairly specific structure to follow regarding form data.
Dave Baldwin

Tell me how that isn't an array?
It is just a string of characters.  An array in any language has defined relationships and access methods.  This is just a string containing the name/value pairs from each 'input' statement separated by a '&'.  Are you aware that the only thing represented here is name/value pairs?  There is Nothing about whether it came from a checkbox, a radio-box, a text input or a textarea.  You could have one of each with the same name and get this same string passed to the server.
Content-Length: 97
same=1&same=2&same=3&same=4&same2%5B%5D=1&same2%5B%5D=2&same2%5B%5D=3&same2%5B%5D=4&submit=Submit

Open in new window

One of the reasons I'm going on about this is that thinking that it 'should be' a certain way gets in the way of figuring out how it is.  When I encounter things like this, I look them up and/or run tests to see what happens.  I try not to think about how it 'should be' because that clouds my view of 'how it is' which is what I really need to know.
ASKER
Rob

Of course I'm aware of the name value pairs and Dave like you I do my own testing to find out how things work with the language etc. And I work within its structure. I'm more focused on why, rather than how it is. I'm not looking to change php, just understand how they got there with this.
Don't get me wrong @Dave, You make good points and are all taken on board :-)
In this case you have to be acutely aware of how your chosen flavour of language will parse a query string / posted form data.
With what you've said re different controls or elements of a different type sharing the same name how they are treated in CF et al but I would still expect the comma separated string.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
_agx_

(EDIT:  Just catching up here... lively discussion we've got going! )

@DaveBaldwin - If everything was going to be the same, we'd be stuck with Classic ASP still...

No. Now we'd be using ASP.NET :P

@tagit - Tell me how that isn't an array?

I'd have to agree with Dave on that one.  While using an array to represent the parsed values would make more sense, the specs only say the values must be transmitted as strings, with the specified delimiters:  

       name=value&name=value...

@tagit - ... they should parse data in an similar way given a fairly specific structure to follow regarding form data.

Well like I mentioned earlier, they do.  The problem is there are no specs that say what a language must do with those values once it parses them.   That is why PHP's handling went against my expectations.  Arrays or csv lists aside, PHP's handling is still significantly different than the others in one regard: none of the other languages  we've seen so far impose any constraints on the client side html element "names" in order to (easily) access all of the submitted values.  (Yes, I know it is possible, but from what was described here there is no simple core function, as in most other languages).  That additional requirement seems a little like overreaching IMO.

@DaveBaldwin - .. thinking that it 'should be' a certain way gets in the way of figuring out how it is.

Well if you're just complaining ... then yeah I'd agree ;-) Otherwise I find that researching, running tests, and objectively examining how I "think" something should be vs how its actually implemented in language xyz often leads to a better understanding of why it is implemented that way. I find that gives me a deeper understanding of the language.  Granted at the end of the day, you ultimately need to follow the rules of whatever language you are using. But gaining a better understanding of your tools is never a bad thing IMO :-)
_agx_

@tagit - Sorry, I know you guys have moved on from some of these points. I just kept getting interrupted before I could finish responding! Darn interruptions...
ASKER
Rob

No worries, it's good to have all kinds of views on this, I'll sign off now.  You guys are great.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Ray Paseur

I revisited this question more or less by accident, and it caused me to think about request variables and how PHP handles the interpretation.  The man page for parse_str() and the code sample below may shed some more light on it.

Since these are checkboxes and not radio buttons, the browser will give you the opportunity to check more than one box.  In the QUERY STRING you'll find the request with the boxes you checked (zero, one or many).  In the $_GET array you'll find only the "last" checked box because PHP will use the name= attributes as array indexes when it builds the $_GET array.  Initial array index names create an element in the $_GET array.  Duplicate array index names cause previous elements to be overwritten.

<?php // RAY_temp_tagit.php
error_reporting(E_ALL);
echo '<pre>';

// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28228399.html

// SHOW THE RAW REQUEST VARIABLES
var_dump($_SERVER['QUERY_STRING']);

// SHOW THE PARSED REQUEST VARIABLES
parse_str($_SERVER['QUERY_STRING'], $arr);
var_dump($arr);

// SHOW THE REQUEST DATA INTERPRETED BY PHP
var_dump($_GET);

// CONSTRUCT A FORM WITH MULTIPLE CHECKBOXES THAT HAVE THE SAME NAME
$form = <<<EOD
<form>
Choose Color:
R <input name="color" value="red" type="checkbox" />
G <input name="color" value="grn" type="checkbox" />
B <input name="color" value="blu" type="checkbox" />
<input type="submit" />
</form>
EOD;
echo $form;

Open in new window

My overall conclusion after looking at this over a cup of coffee is that radio buttons should be used when zero or one, but not many, options exist.  And checkboxes should be used when zero, one or many options exist.  In the latter case, if we really want the client to be able to select more than one option, it probably makes programmatic sense to use the [] array designator or to use different name= attributes.  Otherwise the PHP programmer will have to parse the request data manually.
ASKER
Rob

Thanks Ray,  appreciate the follow up.  Just working through in my own head what you've said:

I've copied your code to phpfiddle to see it in action.  I added a radio group as well and a checkbox group with the [].  As you say, te querystring does contain all values submitted regardless of name but PHP ignores and only retains the last one in a set with the same name (when [] are not present).  So it is possible to parse manually in this case if it is needed.

http://phpfiddle.org/api/run/c2i-sh9

I agree that radio buttons should only ever be used to select ONE option from a mutually exclusive group (if a choice is required otherwise ZERO is ok), such as gender, city you live etc, you're only one or the other but not both.  It is possible to use radio buttons singularly (different name attribute) to impersonate a checkbox group but that's like using a hammer to eat your cereal...

Checkboxes are for selecting ONE or more attributes on a common theme (mutually inclusive) e.g. colour (as in your code).  For arguments sake, "what colours did you use?" (can select more than one).
Dave Baldwin

Checkboxes:  Actually that would be None or more...  And if None are selected, nothing is submitted for that variable.  Same thing applies to Radio buttons.  If there is no default and none are selected, nothing is submitted.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
Rob

Unless a choice is required by your form validation as I tried to indicate with "(if a choice is required otherwise ZERO is ok)"
Dave Baldwin

That's a good practice but it doesn't change what I said.  I always write my PHP to account for things like that.  That is also, for me, good practice.
ASKER
Rob

Yes of course, you have to allow for all possibilities and account for them in your PHP.

My point was about the form element and it's use and the logic to why it is used not focus on how it is parsed.  Yes you can have zero or one option for a radio group and zero or more options for a checkbox but it's why you have a radio and when to have a checkbox group.
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
Dave Baldwin

I wouldn't think of separating those issues since you can't have one without the other.
ASKER
Rob

Neither would I