One significant difference between the way that checkboxes work and the way that all other form fields work is that checkboxes only get passed with the other form fields when the checkbox is selected. All other form fields are always passed with the form unless they are disabled.
Actually that isn't quite true because other fields also don't get passed if there is a second field later on in the form that has the same name. With the exception of radio buttons which are all grouped with the same name and where only one in the group can be selected, all other form fields should have unique names as otherwise only the last form field with a given name will be passed with the form. The exception to this is if you make the fields into an array by adding  after the name.
We can in fact make use of this dropping of duplicate named fields in order to ensure that there is always a value passed with the form whether or not a checkbox is actually checked. How we do it is to add a hidden field directly in front of the checkbox field and give it the same name as the checkbox. We give the hidden field the value that we want to pass when the checkbox is not checked and give the checkbox the value that we want to pass when it is checked. Since doing this is going to pass one value or the other we can no longer simply test for the existance of the checkbox field on the server to see if the checkbox was checked (but that is what we are trying to change anyway).
Here's an example:
<input type="hidden" name='mycheck" value="no" />
<input type="checkbox" name="mycheck" value="yes" />
Specifying a value on the checkbox field ensures that when it is passed with the form that it is passed with a specific value rather than the browser default (usually 0 or on). Since the hidden field has the same name as the checkbox the hidden field will not get passed when the checkbox is checked because with duplicate field names only the last field with that name gets passed. When the checkbox is not checked then the checkbox field doesn't get passed with the rest of the form and is effectively treated as if the field is not there. This means that when the checkbox is not checked that the preceding hidden field with the same name is now the last active field with that name within the form and so it gets passed instead. We can now be sure that the "mycheck" field is always passed with the form and can now test (or display) the value passed in the field rather than having to test whether or not the field was passed. We have effectively duplicated the effect of having two radio buttons in the form in so far as what gets passed while using a single checkbox in the form itself (at least so far as the person filling out the form is concerned).
This article written by Stephen Chapman, Felgall Pty Ltd.