PHP: Forms

This page forms the code summary of 03.forms.html, part of the Webscripting1 — Serverside Webscripting course, part of the Professional Bachelor ICT study programme, taught at Odisee, Ghent, Belgium. The materials and this summary were developed by Bram(us) Van Damme, lecturer ICT at Odisee, who blogs over at bram.us and Twitters as @bramus. The materials and this summary may be used freely, as long as credit to Bramus is present and a clear an upfront link to ikdoeict.be remains in place. Suggestions and additions may be mailed to Bramus, or sent via a pull request on GitHub.

General remarks

A PHP file typically consists of two parts:

Processing a form

Use isset() to extract parameters from $_GET/$_POST

<?php

	$name = isset($_GET['name']) ? (string) $_GET['name'] : '';
	$pass = isset($_GET['pass']) ? (string) $_GET['pass'] : '';
	$gender = isset($_GET['gender']) ? (string) $_GET['gender'] : '';
	$cont = isset($_GET['cont']) ? (int) $_GET['cont'] : 0;
	$meals = isset($_GET['meals']) ? (array) $_GET['meals'] : array();
	$remark = isset($_GET['remark']) ? (string) $_GET['remark'] : '';

// …

Persisting a form

Always use htmlentities() when outputting something on screen. If you don't, visitors will be able to perform an XSS attack!

<?php

	// Get values from $_GET, or provide a default one if not set
	$name = isset($_GET['name']) ? (string) $_GET['name'] : '';
	$pass = isset($_GET['pass']) ? (string) $_GET['pass'] : '';
	$gender = isset($_GET['gender']) ? (string) $_GET['gender'] : '';
	$cont = isset($_GET['cont']) ? (int) $_GET['cont'] : 0;
	$meals = isset($_GET['meals']) ? (array) $_GET['meals'] : array();
	$remark = isset($_GET['remark']) ? (string) $_GET['remark'] : '';

?><!DOCTYPE html>
<html>
<head>
	<title>Testform</title>
	<meta charset="UTF-8" />
	<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>

	<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">

		<fieldset>

			<h2>Testform</h2>

			<dl class="clearfix">

				<dt><label for="name">Name</label></dt>
				<dd class="text"><input type="text" id="name" name="name" value="<?php echo htmlentities($name); ?>" class="input-text" /></dd>

				<dt><label for="pass">Password</label></dt>
				<dd class="text"><input type="password" id="pass" name="pass" value="<?php echo htmlentities($pass); ?>" class="input-text" /></dd>

				<dt><label>Gender</label></dt>
				<dd>
					<label for="gender_male"><input type="radio" class="option" name="gender" id="gender_male" value="male"<?php if ($gender == 'male') { echo ' checked="checked"'; } ?> />Male</label>
					<label for="gender_female"><input type="radio" class="option" name="gender" id="gender_female" value="female"<?php if ($gender == 'female') { echo ' checked="checked"'; } ?> />Female</label>
				</dd>

				<dt><label for="cont">Continent</label></dt>
				<dd>
					<select name="cont" id="cont">
						<option value="0"<?php if ($cont === 0) { echo ' selected="selected"'; } ?>>Please select...</option>
						<option value="1"<?php if ($cont === 1) { echo ' selected="selected"'; } ?>>Africa</option>
						<option value="2"<?php if ($cont === 2) { echo ' selected="selected"'; } ?>>America</option>
						<option value="3"<?php if ($cont === 3) { echo ' selected="selected"'; } ?>>Antarctica</option>
						<option value="4"<?php if ($cont === 4) { echo ' selected="selected"'; } ?>>Asia</option>
						<option value="5"<?php if ($cont === 5) { echo ' selected="selected"'; } ?>>Europe</option>
						<option value="6"<?php if ($cont === 6) { echo ' selected="selected"'; } ?>>Oceania</option>
					</select>
				</dd>

				<dt><label>Meals</label></dt>
				<dd>
					<label for="meal0"><input type="checkbox" class="option" name="meals[]" id="meal0" value="breakfast"<?php if (in_array('breakfast', $meals)) { echo ' checked="checked"'; } ?> />breakfast</label>
					<label for="meal1"><input type="checkbox" class="option" name="meals[]" id="meal1" value="lunch"<?php if (in_array('lunch', $meals)) { echo ' checked="checked"'; } ?> />lunch</label>
					<label for="meal2"><input type="checkbox" class="option" name="meals[]" id="meal2" value="dinner"<?php if (in_array('dinner', $meals)) { echo ' checked="checked"'; } ?> />dinner</label>
				</dd>

				<dt><label for="remark">Remark</label></dt>
				<dd class="text"><textarea name="remark" id="remark" rows="5" cols="40"><?php echo htmlentities($remark); ?></textarea></dd>

				<dt class="full clearfix" id="lastrow">
					<input type="hidden" name="moduleAction" value="processForm" />
					<input type="submit" id="btnSubmit" name="btnSubmit" value="Send" />
				</dt>

			</dl>

		</fieldset>

	</form>

</body>
</html>

Formchecking

Use a hidden input named moduleAction to check if a form was sent or not.

Always use urlencode() when passing parameters into URLs

Always use exit() after redirecting using header() to prevent further execution of the script.

<?php

	// initial values
	$name = isset($_POST['name']) ? (string) $_POST['name'] : '';
	$moduleAction = isset($_POST['moduleAction']) ? (string) $_POST['moduleAction'] : '';
	$msgName = '*';

	// form is sent: perform formchecking!
	if ($moduleAction == 'processForm') {

		$allOk = true;

		// name not empty
		if (trim($name) == '') {
			$msgName = 'Please enter your name';
			$allOk = false;
		}

		// end of form check. If $allOk still is true, then the form was sent in correctly
		if ($allOk === true) {
			header('Location: formchecking_thanks.php?name=' . urlencode($name));
			exit();
		}

	}

?><!DOCTYPE html>
<html>
<head>
	<title>Testform</title>
	<meta charset="UTF-8" />
	<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>

	<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

		<fieldset>

			<h2>Testform</h2>

			<dl class="clearfix">

				<dt><label for="name">Name</label></dt>
				<dd class="text">
					<input type="text" id="name" name="name" value="<?php echo htmlentities($name); ?>" class="input-text" />
					<span class="message error"><?php echo $msgName; ?></span>
				</dd>

				<dt class="full clearfix" id="lastrow">
					<input type="hidden" name="moduleAction" value="processForm" />
					<input type="submit" id="btnSubmit" name="btnSubmit" value="Send" />
				</dt>

			</dl>

		</fieldset>

	</form>

</body>
</html>

Working with file uploads

Inputs with type="file" cannot be persisted.

<!DOCTYPE html>
<html>
<head>
	<title>Testform</title>
	<meta charset="UTF-8" />
	<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>

	<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">


		<fieldset>

			<h2>Testform</h2>

			<dl class="clearfix">

				<dt><label for="image">Image</label></dt>
				<dd class="text"><input type="file" id="image" name="image" value="" class="input-text" /></dd>

				<dt class="full clearfix" id="lastrow">
					<input type="hidden" name="moduleAction" value="processUpload" />
					<input type="submit" id="btnSubmit" name="btnSubmit" value="Send" />
				</dt>

			</dl>

		</fieldset>

	</form>

</body>
</html>

In 05.files.and.folders.html we'll see how to handle an upload