Only the value of checked checkboxes are submitted to the server. This is an HTML/browser design thing and has nothing to do with PHP. How else do you reliably distinguish a checked checkbox from an unchecked one?
...then how do I know whether the script failed to pass along the value or the checkbox was just not set?
You can trust the browser and PHP to get it right. If it's not set, the box wasn't checked. If you're running some Javascript that submits the form and may get it wrong, it's your responsibility to debug your script.
Regarding "it's bad design":
It's efficient design. There are only two other possibilities, given the limitation that values are send as text only:
- Send both the value and the state separately, like
checkbox:state=checked&checkbox:value=myvalue
. Let's pretend for a second that this would not cause major headaches and ambiguities in what is allowed for input element names and what is not.
- Use a magic value to mean "unchecked":
checkbox=false
. That means I can't make a checkbox like this: <input type="checkbox" name="checkbox" value="false" />
Let's pretend that either solution above would be used and problems associated with them would be solved. That would mean that for every checkbox on the page a POST value would be send. Usually that's not a big deal, but let's imagine a page with 50 checkboxes. Not too unrealistic I'd say. What about one with 200? That's 200 * ~10+
characters extra in HTTP headers for each POST, probably most of them just telling you what the user did not do.
Since this technique was invented when bandwidth was very precious, it's the most efficient to simply not send values of unchecked checkboxes.