php 101

Working with Forms

The key to almost all interaction between users and servers is through forms, which are used to enter search queries, fill out shopping carts, sign up for newsletters, and so on. We didn't cover forms in our HTML 101 tutorial because, without server-side processing, there isn't much you can do with a form. Now that you know some PHP, it's possible to create interactive forms that do interesting things.

Forms are a fairly complex topic, with many security gotchas to be aware of. This section of the tutorial will acquaint you with form processing, but you should definitely do more reading on forms, security, and PHP before putting forms into production. If your form interacts with a database and you haven't taken the right precautions, attackers can do very bad things to your site. Better yet, use a well-established framework like Cake or CodeIgniter which takes care of form construction and input sanitization for you. The exercise we'll do here does not interact with a database and is perfectly safe.

Most forms do one of three things:

  • Perform a search lookup
  • Submit data into a database
  • Generate an email

We need to know how to obtain the value of fields in a form from PHP, so we can do things with them. Let's take this simple form:

This will give you a simple form into which you can type your name. When you click Submit, notice that the value you typed in your form field now appears in the URL, like this:

http://example.com/tutorial/formtest.php?your_name=Scot

The string appears in the URL because our form used method="get", and that's what the "get" method does - it appends the form's field names and values to the URL. Notice also the action="" attribute on the form. You can either leave this blank, or insert a relative or absolute URL. If you insert a URL, the script at that URL will be triggered when the form is submitted. If you insert nothing, the script will submit to itself. That's what we're doing here. Notice also that the parameter in the URL has the same name as the your_name input field. If your form has multiple fields, your resulting URL would have multiple parameters.

As we learned at the beginning of this tutorial, we can access parameters from the URL with the $_REQUEST['fieldname'] global variable. So try modifying your script to look like this:

See what we've done here? At the top of the document, we jump into PHP mode and do a test (a conditional) to see whether 'your_name' is present in the URL parameters. If so, we say hello to that person. Since we don't have an else{} clause, we do nothing if the parameter is not present.

In many cases, you'll only want to show the form before the submit button has been clicked. Afterwards, you want to show something else, like a list of search results. We use a similar technique to do that (here's some pseudo-code for clarity):

It's almost like we've programmed two web pages in one! Here's actual working code for you to try:

Notice that we do a bit of extra fancy footwork in that example. On line 6, right in the middle of the else{} clause, we exit PHP mode. We're now back in HTML mode, so we can draw our form on the page. When the form is done, we re-enter PHP mode to close the else{} clause. This is a very common technique.

There's one big gotcha in the approach we're using here. What if you were building a login form for a website that requested the user's username and password? The method="get" technique puts all of the form fields in URL parameters, and you'd end up displaying the user's password in the URL field, visible to anyone who walked by! Big security no-no.

The solution is to use method="post" instead. POST carries all of the field values in browser memory, but doesn't alter the URL. But our script depends on the presence of those parameters! Or does it? Try changing "get" to "post" in the script above to see what happens. It still works! That's because the $_REQUEST global variable contains everything in the browser request in memory. In fact, we never did say "Obtain the value from the URL" - we said "Obtain the value from the $_REQUEST global variable," so we're all set.

In general, use the GET method for forms when you want the URL to carry the parameters, as in search requests. Use POST at all other times.

Again, please read up on forms and security before deploying them, especially if your script is talking to a database. Or better yet, use a web framework such as Cake or CodeIgniter to do the heavy lifting for you.