Notice: There is now a more powerful stand-alone version 3 available. You might want to get it instead of this version. It’s better offering the same as this form and a lot more. Check it out.
This is the official page for my Secure and Accessible PHP Contact Form v.2.0. This easy-to-install form has many accessibility, usability, and security features over my old form that used to be offered on this page. The line between accessibility and security is a fine one. Hopefully I drew it well. (Want a copy of this for WordPress?) On this page you will find the following information:
Accessibility & Usability
I went to great lengths to make sure this form is as accessible and usable as possible. If you have suggestions to make it better, please let me know. As far as I know, though, for legitimate users, it just can’t get much better than this.
- Semantic mark-up, proper form elements, and proper alt- and label-input associations are all provided. From a standards-compliant and web accessibility point of view, this form is spot-on.
- Written to XHTML 1.0 Strict, but the form admin can change it to HTML 4.01 Strict by simply making one change in the configuration file.
- Features a
#resultsfragment identifier on form submit, all error headings, and the success results heading. When the form is submitted it brings the user directly to the result itself, instead of bringing him or her to the top of the applicable results page. To visual browser users this is inconsequential, but for text browser and screen-reader users, or anyone using a keyboard to get around, this is a huge benefit.
- Logical groupings within fieldsets are provided. Additionally, all fieldsets are within a wrapper fieldset to better identify the form as a single working unit.
- Tabindexing is built in and can be modified by the form administrator. All values are set to zero by default which means they are already useful to Opera browser users. These values are added not only to the input fields, and also on specific form-related links.
- Names and form instructions are meant to clear and simple to understand.
- Screen Reader Tested: Listen to the form demo page using the Jaws 8 screen reader. Hear it in Forms Mode or Virtual Cursor Mode. Recordings courtesy of Nick Fitzsimons.
| Menu |
I went off the deep end on matters of security. While one feature, regardless of how good it may be, may suffice, two features are better, and have employed fourteen features to prevent abuse. Only one really requires the form user to do anything. Most anti-spam controls are passive and only targeted to stop remote machine posting and spam ‘bot abuse.
- Form submit email is hidden by PHP to keep it from being harvested by email harvesting ‘bots.
- Required fields are supplied to prevent meaningless submissions by abusive human users.
- Email structure is validated and sanitized. Full email validation isn’t provided to ensure fast processing.
- Pulldown menu (select) is required to make abusive repetitive form-use less convenient for human users. Legitimate users won’t be bothered by this.
- Markup and code is removed from all inputs by PHP using built in PHP functionality.
- All variables are sanitized or “scrubbed” and trimmed to prevent any form of malicious injection, blind carbon copies (bcc), script, etc.
- Inputs have the maxlength attribute, and this is also strictly enforced by PHP to mitigate circumvention by spam ‘bots.
- A simple anti-spam question must be answered correctly. Form admin can change this and examples are provided. For the admin and the user, the answer-data entered is case-insensitive for simplicity’s sake as is other match-require variable data. If the question can’t be answered by a legitimate user, a convenient option is provided so that user can still communicate.
- To prevent exploit distribution (if one is found), each form features a unique ID and will not submit if it doesn’t match the code submitted. This form ID code is unique for each form and each form user.
- The form features a type-hidden spam-trap field. Again, to prevent exploit distribution, it features an IDs unique to each form and each form user. The details of this trap will not be discussed here, but it’s specifically designed to passively mitigate spam ‘bot use.
- The form features a CSS-hidden spam-trap field, with available notation. The details of this trap will not be discussed here, but it’s specifically designed to passively mitigate spam ‘bot use.
- To prevent usage by spam ‘bots and yet again to prevent exploit distribution, the submit ID must be matched and has a value unique to each form and each form user. If problematic to a legitimate user (it shouldn’t be), a convenient option is provided so that user can still communicate.
- Pulldown (select) choices must be present in the array used to populate this value so one of the existing choices must be used. If not, an error is returned. This is yet another anti-spam ‘bot tool.
- The referrer must match and not be blocked to submit form. If it is blocked by a legitimate user, a convenient option is provided so that user can still communicate.
- Complete educated header and input injection exploit detector and killer ensures the form, if exploited, can’t be used for evil purposes or pose a threat to others.
- And if worst comes to worst and you have a human visitor that simply wants to make your life difficult, this form features an IP Blacklist function. This is a last resort option, but it is available.
| Menu |
The Form Files
The following files are provided with the download:
- gbcf_readme.txt - The installation and configuration instructions.
- gbcf_config.php - The form admin’s form configuration file.
- gbcf_form.php - The form body and script file — it should not need any editing.
- gbcf_focus.js - The form-focus script file for IE users.
- gbcf_styles.css - The form’s basic Cascading Style Sheet.
| Menu |
This form is simple to install and can be done in a matter of minutes. The following must be done:
- Unpack the *.zip file and extract the individual files.
- Using a text editor like Notepad, open the file named
gbcf_config.phpand complete at least section one of the configuration steps.
- Upload the files
gbcf_focus.jsin a single “form-files-directory” on your server. Name the directory however you want.
- You can also place the
gbcf_styles.cssin the same directory, but you will likely just want to add the file’s contents to your own CSS file. It’s your call.
- Using the PHP include function, include the file
gbcf_form.phpin any *.php page file where you want it to be. It must be below the
<body>tag and preferably below the main heading. I recommend placing it in the main content area. See Example 1, below.
<head></head>of the page. See Example 2, below. Place it in a conditional comment since it’s only needed for IE. You won’t need this unless your are providing form field focus (recommended).
- That’s it. Your done. At this point you will want to link to the style sheet if you’re not adding the elements, selectors, classes, and IDs to your own style sheet, modify the configuration file further if wanted, and of course test your new form. To link to the style sheet, please see Example 3, below.
Example 1 <?php include("form-files-directory/gbcf_form.php"); ?>
Example 3 <link rel="stylesheet" type="text/css" href="form-files-directory/gbcf_styles.css" media="screen" /> Note: XHTML method shown, for HTML drop the slash at the end and close the gap.
| Menu |
This form’s admin configuration is broken down into eight sections to help clarify and simplify. Only one section is required, and default values are provided, but you might want to modify the other sections to suit your individual needs. The sections and variables are as follows:
- General form configuration:
- “Enter your email address” (what the form submits to).
- “Enter your name or company” (for the email greeting).
- “Set site/form possession” (this changes wording from “me” to “us,” my” to “our,” etc. This is for the main heading, error messages, etc.).
- “Enter website name” (or page name, company name, whatever).
- “Enter time offset if needed” (if server time varies from local) from "0"; for no change (default) to "+1"; plus one hour, "-1"; minus one hour, +/-2, plus/minus two hours, +/-3, plus/minus three hours, +/-4, plus/minus four hours, or whatever you need.
- “Contact Reason” menu: Use this to enter options for the pulldown (select) menu. Enter as many options you want, the form will adapt. Some common ones are provided.
- “Anti-Spam” q/a options: Use this to enter a simple question and answer. Suggestions are provided.
- Heading options:
- “Set heading size” (enter a numeric value, 1-6).
- “Enter your error heading” (what your errors say, set color to .error class in CSS).
- “Enter your success heading” (what your success result says, set color to .success class in CSS).
- Other config options menu:
- “Choose XHTML or HTML” (enter the form markup type needed for your site).
- “Enter your button text” (enter optional text for your “Submit Form” button).
- “Enter credit link option” (a simple yes or no determines if you want the link back to me to show… I hope you keep it as “yes” but it’s your call).
- “Enter privacy link url” (if you answered “yes” to above option, enter the absolute URL or relative path to that policy).
- Custom tabindex assignments: If you want to set tabindex values, use this section to do so. All are set to zero by default.
- IP Blacklist: If you have a need to block a certain IP address, you can enter it in this array. The array is structured for you but left blank by default. Use this only as a last resort and know that this is not effective against anyone who doesn’t have a static IP address. When you get emails sent to you, the user’s IP address is part of the data you will receive.
- Form location specification: This is done for you by way of a PHP code snippet, but if you have a problem with the form giving referrer mismatch errors during testing, it may be due to its location or in instances where you have custom URLs resulting from apache_mod_rewrite rules being in effect. If so, enter your absolute URL or relative path to the form page (shown in the nav bar on your browser) in place of the snippet used in the form_location variable.
| Menu |
Get Form Support
Use the Form Demo Page to request support or if you have any special customization requirements. Basic support is free as a courtesy to you — I will answer simple questions but it is requested that you first refer to the installation and configuration instructions to try and answer the question yourself. Advanced support requests and all customization work are for-hire services. Donations are always accepted if you find this form useful to you; use the Form Demo Page to get in touch. While comments remain open, you can also ask questions or give feedback in the dedicated announcement post.
| Menu |
9 out 10 gurus will agree, but I’ll beat them to it and say it first: I’m not a PHP guru. Thus, while I have made this form to the best of my current abilities — which is a whole heck of a lot better than my version 1 — it is not perfect and may very well have some flaws so using it is at your own risk. I make no warranties, direct or implied. Do know, however, that it’ll be upgraded now and then, and will improve further over time. If you’re using it, you may want to check back here now and then to view the Change Log - Updates to see if version 2.0 improvements are available. I promise to try and make any changes in such a way that all you have to do as a user is drag-and-drop the form script file
gbcf_form.php (which I recommend not editing yourself for this reason) to overwrite the existing file and implement the changes.
| Menu |
Change Log & Updates
If any errors are found or changes made, they will be logged here and summarized in brief. (From oldest to most recent.)
- 2006.10.04: Typo found and fixed on
Line 28of the
gbcf_config.phpfile. Line should end with comma, not semi-colon. Affects first 7 downloads. Recommendation: Correct this yourself in the affected file by replacing character.
- 2006.10.04: Demo header and footer included in
gbcf_form.phpfile. Oops. Header and footer removed. Affects downloads 8-15. Recommendation: Re-download *.zip and simply replace the affected file.
- 2006.10.04: Anti-Spam Trap 2 modified in
gbcf_form.phpfile. Attribute type changed to text, but hidden by CSS. A notation was added to explain it those users not supporting or using CSS. Affects first 15 downloads. Recommendation: Re-download *.zip and simply replace the affected file.
- 2006.10.06: Exploit detector/killer added, functions clean-up performed, AOL-user modification made, and email validation improved/modified in
gbcf_form.phpfile, and two styles sheet edits made in
div#gb_form_dvwas changed to
div#gb_form_div, and the main heading class was changed from
.formheadstill remains for error headings) for more user flexibility. Affects first 49 downloads. Recommendation: Re-download *.zip and simply replace the
gbcf_form.phpand make manual edits to those two CSS classes (if needed).
- 2006.10.16: Time offset variable added in
gbcf_config.phpfile, in Section 1 of 8, and function added in
gbcf_form.phpfile (and the
gbcf_readme.txtwas updated). This was updated to allow the ability to alter the date/time for those users whose server is not in their time zone. If you’re not concerned about this or your server is in your time zone, you have no need to worry about this, (but you may want to anyway just in case there are future upgrades available). Affects first 127 downloads. Recommendation: Read more about your four options.
- 2006.10.23: I updated the
gbcf_focus.jsfile. There was a comment in the file that was preventing the script from running thus offering no form field focus in IE6. I replaced the file. Affects first 171 downloads. Recommendation: Replace the file if you offer form field focus and care that it works in IE6. Otherwise, do nothing.
- 2006.10.23: I updated the
gbcf_styles.cssfile. I added hacks just for IE6 to keep button stable. I replaced the file. Affects first 174 downloads. Recommendation: Add the hacks in the new file to your file and modify them if you offer form field focus and care that it works in IE6. Otherwise, do nothing.
- 2006.10.26: I updated the
gbcf_form.phpfile. The problem was referrer mis-matching if the form admin set the URL manually with/without a WWW and the form user accessed the form page in an opposite manner. If you’re using the default
$form_locationcode snippet don’t worry about this, but if you set it manually and users can access your form with/without the WWW in the URL you’ll want/need to address this. Affects first 222 downloads. Recommendation: If applicable to you, as described, swap out the
gbcf_form.phpand the problem is solved.
- 2006.11.01: I updated the
gbcf_config.phpfiles. The basic changes I made to the form file now allows admins to now enable or disable the Carbon Copy function, the carbon copy email sent to users was modified extensively and is a separate mail, an identified auto-fill user bug was fixed (Spam Trap 2 was being populated), and the referrer match-up was changed significantly as that was giving people problems. The config file was changed to add the carbon copy selection (line in config section 1), and I also added an include security function (line at very top of file). Affects first 343 downloads. Recommendation: Swap out the two files mentioned and reconfigure OR swap out the form file and add the two added lines to the config file. That’s it.
- 2006.11.05: Minor tweaks made to the
gbcf_form.phpfile to make it look nicer in the source. Also made one tweak to mitigate the possibility of an “open relay attack” being carried out. Affects first 417 downloads. Recommendation: Swap out the
- 2006.11.25: Success message typo corrected in the
gbcf_form.phpfile. Affects first 779 downloads. Recommendation: Swap out the
- 2007.01.20: Minor tweaks made to the
gbcf_form.phpto negotiate IP addresses differently, changed character set to UTF-8 to allow more characters in emails, fixed a typo, and changed the “from” to the sender to allow use with host that require SMTP authentication. Affects first 1728 downloads. Recommendation: Swap out the
- 2007.02.03: Minor tweaks made to the
gbcf_form.phpto plug a possible header injection exploit hole, general tweaks and mods. Ordering of
gbcf_config.phpfile made. Affects first 1999 downloads. Recommendation: Swap out the
- 2007.02.13: A modification was made to the
gbcf_form.phpfile to update the header injection exploit error message. Affects first 2211 downloads. Recommendation: Swap out the
- 2007.03.03: The ordering of the negotiations was modified in the
gbcf_form.phpfile for even greater email security. Affects first 2680 downloads. Recommendation: Swap out the
- 2007.03.29: In the
gbcf_form.phpfile the blockquote’s cite attribute in the success result was changed, the “Referrer Mismatch” error was modified, the random exploit distribution codes were changed, and mail function detection was added to help users determine if they can use the form. The readme file was also updated. Affects first 3413 downloads. Recommendation: Swap out the
- 2007.04.03: In the
gbcf_form.phpthere was a really stupid validation error — I should have checked. I didn’t properly close the main form heading. Affects downloads 3413 through 3509. Recommendation: Swap out the
- 2007.04.07: I made several changes in the
gbcf_form.phpmostly to further enhance security, small tweaks. Affects the first 3641 downloads. Recommendation: Swap out the
- 2007.04.14: Due to threats from a disgruntled user I have removed all link-backs in the
gbcf_form.phpfile if Showcredit “No” is selected in the config. Affects first 3863 downloads. Recommendation: Swap out the
gbcf_form.phpfile. This was never meant to dupe or spam anyone. It was used purely for software promotion and innocuous tracking.
- 2008.02.07: I moved the labels, reduced their length, spanned the legends, added
3Dto make a working Whois query input. Most changes were for greater accessibility. Affects first 13652 downloads. Recommendation: Swap out the
- 2008.07.31: I shortened the variable lengths due to some server issues some people encountered. I also remove the negative top margin from the hidden input (better for tabbing to use left only). Affects first 17284 downloads. Recommendation: Swap out the
- 2008.11.18: I added the
-fparameter to help those with requiring email providers such as AOL. Affects first 19476 downloads. Recommendation: Swap out the
| Menu |
Fee-based form customizations are available. This service might include the addition or removal of user inputs, etc. To learn more or to ask for quote request, please contact me.
| Menu |
Download the Form
To date, this “Secure and Accessible PHP Contact Form v.2.0″ has been downloaded
34085 times since its release on: Oct. 3rd, 2006.
| Menu |
Credits & Thanks
The following people or groups helped me with this form in some way, whether it be giving me a simple but brilliant idea, lending a little scripting support, providing answers by way of documentation, testing the completed form, or in some cases just trying to help. I offer them my gratitude whether their ideas were put to use or not: Joe Dolson, Jonathan Fenocchi, Stephan Segraves, Tommy Olsson, Harmen Janssen, Mel Pedley, Jemma Turner, Adam Messinger, andrabr, Jon Gibbins, Pierre Far, Karen Mardahl, some of the folks at Site Point (most notably “clamcrusher”), and, of course, PHP.net.
| Content Top |