Web Development
Using PHP

Follow on
Twitter

Forms

Creating a Basic Form

Generic form, nothing specific to PHP.

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

  <title>Sample Form</title>
</head>

<body>
  <h1>Form Test</h1><!-- All elements of the form should be contained
      inside the form tags. -->

  <form action="form_process.php" method="get">
    <!-- Enter name -->
    First name: <input type="text" name="firstname" /><br />
    Last name: <input type="text" name="lastname" /><br />
    <br />
    <!-- Enter male/female -->

    <fieldset>
      <input type="radio" name="sex" value="male" /> Male<br />
      <input type="radio" name="sex" value="female" /> Female
    </fieldset><br />
    <!-- Enter transportation -->

    <fieldset>
      I have a bike: <input type="checkbox" name="vehicles[]" value="Bike" /><br />
      I have a car: <input type="checkbox" name="vehicles[]" value="Car" /><br />
      I have an airplane: <input type="checkbox" name="vehicles[]" value="Airplane" />
    </fieldset><br />
    <!-- Add submit button -->
     <input type="submit" value="Submit" />
  </form>
</body>
</html>

This will 'catch' the results of the form. No processing or PHP specific things yet. Try it out. Look at the URL line and see what is in it.

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Submitted</h1>
</body>
</html>

Try it out: [link]

Using Form Results

This will take the input values from the prior form and print.

(See what happens if you access the page directly.)

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Submitted</h1><?php
  $firstname = $_GET['firstname'];
  $lastname = $_GET['lastname'];

  echo "Hello ".$firstname." ".$lastname." .";
  ?>
</body>
</html>

Try it out: [link]

Get vs. Post

Change the $_GET to a $_POST. Does it work? Try changing the form tag in the form page to a "post" instead of a get. Now does it work? If you use $_REQUEST it works with either.

Here is a page that shows simple validation. Note that it also demonstrates:

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Submitted</h1>
  <?php
  // Process first and last name
  $firstname = $_GET['firstname'];
  $lastname = $_GET['lastname'];
  echo "Hello $firstname $lastname. <br />";

  // Did the user hit a one of the sex radio buttons?
  if( isset($_GET['sex'])) {
   // ...they did. Which one?
   $sex = $_GET['sex'];
   echo "You are $sex. <br />";
  }

  // Did the use check any of the vehicles?
  if( isset($_GET['vehicles'])) {
   // They did. Get an array of each one
   $vehicles = $_GET['vehicles'];
   // How many items in the array?
   $n = count($vehicles);
   // Print the array
   for($i=0; $i<$n;$i++) {
    echo "<br />$vehicles[$i]";
   }
  }
  ?>
</body>
</html>

Try it out: [link]

Encoding HTML Entities

This works. But it is not safe at all. For example, try entering these for the first name:

<h1>Paul 
<p 
<plaintext>Paul 
<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT> 
There are a lot of really evil things a person could do with this.

HTML Entities

Before displaying any variable on a web page, it should be encoded. For example, try entering the following as a first name in the form example:

"><h1>hi</h1>

To properly manage this field, try encoding the field instead:

<input type="text" name="firstname" value="<?php 
if(!empty($firstname))
	echo htmlentities($firstname);
?>"/>

This uses a new function, htmlentities. This function takes all quotes, and HTML-like characters and encodes them so that they appear properly in an HTML page. This code also uses the function empty to see if a variable exists. The first time the page is brought up, that variable will not have been created, and an error will occur if the program does not check first.

What are HTML entities? HTML entities allow special characters to be displayed in an HTML page without actually using those characters. This keeps the source file as plain ASCII text, and allows some of the characters to be set aside to be used for code.

Take a look at the table shown here:
http://www.w3schools.com/HTML/html_entities.asp

Note: This is different than URL encoding. If there is a parameter in the URL, and that URL has special characters in it, the characters need to be encoded. See:
http://www.w3schools.com/tags/ref_urlencode.asp

Validating Input Part 1

First, learn regular expressions:
http://www.phpro.org/tutorials/Introduction-to-PHP-Regex.html

Regular expressions are useful:
http://xkcd.com/208/

Next, start with a basic form:

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Test</h1>

  <form action="form_process.php" method="get">
    <!-- Enter name -->
    First name: <input type="text" name="firstname" /><br />
    <input type="submit" value="Submit" />
  </form>
</body>
</html>

Then, use the command preg_match to see if the input matches the regular expression:

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Submitted</h1><?php
  /* Validation of first name */
  if(empty($_REQUEST['firstname'])) {
      /* First, if there is no firstname in the request, print an error. */
          echo "<p>Error, no first name entered.</p>";
          $firstname=NULL;
  } else {
          /* There is a first name. Set a variable to its value. */
          $firstname = $_REQUEST['firstname'];
          /* Use the regular expression ^[A-Za-z]{1,25}$ and see if the value matches it */
          if (!preg_match("/^[A-Za-z]{1,25}$/", $firstname)) {
                  /* No match. End the script immediately with 'die'. */
                  /* Note, using 'die' as a bad practice. */
                  die("Bad name, please re-enter.");
          }
  }

  echo "Hello $firstname."
  ?>
</body>
</html>

Try it out: [link]

The command preg_match is new. This command takes a regular pattern (preg) and attempts to match it against a string.

Unfortunately this example will not validate names like "O'Malley" or "Van Wyk" or "Newton-John". To support this, the pattern would need to be updated to add these characters to the list of what is permissable.

This code also introduces the command die. Dying should only be done in the most desperate of circumstances. A normal user should not be able to trip a die command. Obviously, the command has been used improperly here. Look at the resulting html output from the page. What happened?

Search the web and come up with regular expressions for phone numbers, and e-mail addresses. Try them out.

Validating Input Part 2

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Test</h1><?php
  if(!empty($messages)) {
          foreach ($messages as $message) {
              echo $message;
          }
  }
  ?>

  <form action="form_process.php" method="get">
    <!-- Enter name -->
    First name: <input type="text" name="firstname" /><br />
    <!-- Add submit button -->
    <input type="submit" value="Submit" />
  </form>
</body>
</html>
<?php
/* Keep track if there is an error or not */
$error=FALSE;

/* Validation of first name */
if(empty($_REQUEST['firstname'])) {
	/* There was no first name, that's odd */
	$error=TRUE;
	/* Create an array of messages to display the user */
	$messages['firstname']="<p class='errormsg'>Error - Invalid First Name</p>";
} else {
	/* Get the first name from the request */
	$firstname = $_REQUEST['firstname'];
	/* See if the first name matches our not-very-good filter */
	if (!preg_match("/^[A-Za-z]{1,25}$/", $firstname)) {
		/* No match, display an error */
		$error=TRUE;
			/* Create an array of messages to display the user */
		$messages['firstname']="<p class='errormsg'>Error - Invalid First Name</p>"; 
		
	}
}

/* If there was an error, include the form again. Otherwise continue on. */
if($error) {
	include("form.php");
} else {
	include("next.php");
}
?>
<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Submitted</h1><?php
  echo "Hello $firstname."
  ?>
</body>
</html>

Try it out: [link]

This is one way of processing the form, but it isn't perfect. If a user bookmarks the form after a failed attempt, or if the user bookmarks the following page, then the bookmark will be for the form_process.php page, rather than the form or the following link.

Even more obvious, the form value lost, and the user must re-enter the data.

Preserving form input

This version of form.php will preserve the value save in the form.

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Test</h1><?php
  if(!empty($messages)) {
          foreach ($messages as $message) {
              echo $message;
          }
  }
  ?>

  <form action="form_process.php" method="get">
    <!-- Enter name -->
    First name: <input type="text" name="firstname" <?php
	if( isset($firstname) ) {
		echo 'value="';
		echo htmlentities ($firstname);
		echo '"';
	}
	?>/><br />
    <!-- Add submit button -->
    <input type="submit" value="Submit" />
  </form>
</body>
</html>

Try it out: [link]

Complex form with many input types

There are many other types of input. This next example is more complex. The code below properly handles several types of input. It also places an error next to the field that is not correct.

<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
  <style type="text/css">
        .errormsg { color: red; }
  </style>
</head>

<body>
  <h1>Form Test</h1><?php

  if(!empty($messages)) {
          foreach ($messages as $message) {
              echo "<p class='errormsg'>$message</p>";
          }
  }
  ?><!-- All elements of the form should be contained
      inside the form tags. -->

  <form action="form_process.php" method="post">
    <!-- Enter name -->
    First name: <input type="text" name="firstname" value=
    "<?php if( isset($firstname)) { echo htmlentities($firstname); } ?>" />
     <?php if( isset($messages['firstname'])) echo "<span class='errormsg'>".$messages['firstname']."</span>"; ?><br />

    Last name: <input type="text" name="lastname" value=
    "<?php if( isset($lastname)) { echo htmlentities($lastname); } ?>" />
     <?php if( isset($messages['lastname'])) echo "<span class='errormsg'>".$messages['lastname']."</span>"; ?><br />

    <br />
    <!-- Enter male/female -->

    <fieldset>
      <input type="radio" name="sex" value=
      "male" <?php if( isset($sex) and $sex=="male" ) {echo "checked='yes'";} ?> />
      Male<br />
      <input type="radio" name="sex" value=
      "female" <?php if( isset($sex) and $sex=="female" ) {echo "checked='yes'";} ?> />
       Female
    </fieldset><br />
    <!-- Enter transportation -->

    <!-- The [] in the name attribute triggers special handling with
       PHP. It means nothing special in HTML -->

    <fieldset>
      I have a bike: <input type="checkbox" name="vehicles[]"
      value="Bike" <?php if( isset($vehicles_associative['Bike']) ) {echo "checked='yes'";} ?> />
      <br />
      I have a car: <input type="checkbox" name="vehicles[]" value=
      "Car" <?php if( isset($vehicles_associative['Car']) ) {echo "checked='yes'";} ?> />
      <br />
      I have an airplane: <input type="checkbox" name="vehicles[]"
      value=
      "Airplane" <?php if( isset($vehicles_associative['Airplane']) ) {echo "checked='yes'";} ?> />
      </fieldset><br />
    <!-- Add submit button -->
     <input type="submit" value="Submit" />
  </form>
</body>
</html>
<?php
$error=FALSE;

if(!empty($_REQUEST['firstname'])) {
	$firstname = $_REQUEST['firstname'];
	if (!preg_match("/^[A-Za-z]{1,25}$/", $firstname)) {
		$error=TRUE;
		$messages['firstname']="Error - Invalid First Name"; 
	}
} else {
	$firstname="";
	$error=TRUE;
	$messages['firstname']="Error - Invalid First Name";
}

if(!empty($_REQUEST['lastname'])) {
	$lastname = $_REQUEST['lastname'];
	if (!preg_match("/^[A-Za-z]{1,25}$/", $lastname)) {
		$error=TRUE;
		$messages['lastname']="Error - Invalid Last Name"; 
	}
} else {
	$error=TRUE;
	$messages['lastname']="Error - Invalid Last Name";
}

if(!empty($_REQUEST['sex'])) {
	$sex = $_REQUEST['sex'];
	if (!preg_match("/^(male|female)$/", $sex)) {
		$error=TRUE;
		$messages['sex']="Error - Invalid Sex"; 
	}
} else {
	$error=TRUE;
	$messages['sex']="Error - No sex selected";
}

// Did the use check any of the vehicles?
if( isset($_REQUEST['vehicles'])) {
 // They did. Get an array of each one
 $vehicles = $_REQUEST['vehicles'];
 // How many items in the array?
 $n = count($vehicles);
 // Print the array
 for($i=0; $i<$n;$i++) {
 	if (!preg_match("/^(Bike|Car|Airplane)$/", $vehicles[$i])) {
		$error=TRUE;
		$messages['Vehicles']="Error - Invalid Vehicle Selection"; 
	} else {
		$vehicles_associative[$vehicles[$i]] = TRUE;
	}
 }
}

if($error==TRUE) {
	include("form.php");
} else {
	include("next.php");
}
?>
<!DOCTYPE html>

<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Sample PHP</title>
</head>

<body>
  <h1>Form Submitted</h1><?php
    echo "Hello $firstname."
    ?>
</body>
</html>

Try it out: [link]

To fix the issue of improper URLs, it is necessary to learn how to use sessions.

You are not logged in. Log in here and track your progress.