PHP Fundamentals
HTML Forms & PHP
HTML Forms & PHP
Forms are the primary way users interact with web applications. PHP makes it easy to process form data and create dynamic, interactive experiences.
Basic Form Structure
HTML forms use the <form> element with two important attributes:
- method: Specifies how data is sent (GET or POST)
- action: Specifies where the data is sent (PHP file)
<!-- Basic Form -->
<form method="post" action="process.php">
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<button type="submit">Submit</button>
</form>
Important: The
name attribute is crucial. It becomes the key in the $_POST or $_GET array. Without it, PHP cannot access the field data.
GET vs POST Methods
GET Method
<!-- GET Form -->
<form method="get" action="search.php">
<input type="text" name="query" placeholder="Search...">
<button type="submit">Search</button>
</form>
Characteristics of GET:
- Data appears in URL:
search.php?query=php - Limited data size (URL length limit)
- Data is visible and can be bookmarked
- Good for searches and filters
- NOT secure for sensitive data
POST Method
<!-- POST Form -->
<form method="post" action="register.php">
<input type="text" name="username">
<input type="password" name="password">
<button type="submit">Register</button>
</form>
Characteristics of POST:
- Data sent in request body (not visible in URL)
- No size limit on data
- More secure for sensitive information
- Good for forms, login, registration
- Cannot be bookmarked
Rule of Thumb: Use GET for retrieving data (search, filters) and POST for creating/updating data (login, registration, forms).
Processing Form Data
<?php
// contact.php - Form processing
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Form was submitted
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
echo "Thank you, $name!";
echo "We received your message.";
} else {
// Show the form
?>
<form method="post" action="">
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>
<?php
}
?>
Form Input Types
<!-- Text Inputs -->
<input type="text" name="username">
<input type="email" name="email">
<input type="password" name="password">
<input type="number" name="age">
<input type="tel" name="phone">
<input type="url" name="website">
<input type="date" name="birthday">
<!-- Text Area -->
<textarea name="message" rows="5"></textarea>
<!-- Radio Buttons -->
<input type="radio" name="gender" value="male"> Male
<input type="radio" name="gender" value="female"> Female
<!-- Checkboxes -->
<input type="checkbox" name="terms" value="1"> Agree to terms
<input type="checkbox" name="newsletter" value="1"> Subscribe
<!-- Select Dropdown -->
<select name="country">
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
</select>
<!-- Multiple Select -->
<select name="skills[]" multiple>
<option value="php">PHP</option>
<option value="js">JavaScript</option>
<option value="python">Python</option>
</select>
Processing Different Input Types
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Text inputs
$username = $_POST['username'];
$email = $_POST['email'];
// Radio button (single value)
$gender = $_POST['gender']; // "male" or "female"
// Checkbox (check if set)
$terms = isset($_POST['terms']) ? true : false;
$newsletter = isset($_POST['newsletter']) ? true : false;
// Select dropdown
$country = $_POST['country'];
// Multiple select (array)
$skills = isset($_POST['skills']) ? $_POST['skills'] : [];
// Display selected skills
if (!empty($skills)) {
foreach ($skills as $skill) {
echo "Skill: $skill<br>";
}
}
}
?>
Checkbox Warning: Unchecked checkboxes are NOT sent in the form data. Always use
isset() to check if a checkbox was checked.
Complete Registration Form Example
<?php
// register.php
$errors = [];
$success = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Get form data
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
$age = intval($_POST['age']);
$gender = $_POST['gender'];
$terms = isset($_POST['terms']);
// Basic validation
if (empty($username)) {
$errors[] = "Username is required";
}
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Valid email is required";
}
if (strlen($password) < 6) {
$errors[] = "Password must be at least 6 characters";
}
if ($password !== $confirm_password) {
$errors[] = "Passwords do not match";
}
if ($age < 18) {
$errors[] = "You must be 18 or older";
}
if (!$terms) {
$errors[] = "You must agree to the terms";
}
// If no errors, process registration
if (empty($errors)) {
// Hash password
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// In real application: save to database
// For now, just show success
$success = true;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>User Registration</title>
<style>
.error { color: red; }
.success { color: green; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input, select { padding: 5px; width: 300px; }
</style>
</head>
<body>
<h1>User Registration</h1>
<?php if ($success): ?>
<div class="success">
<h2>Registration Successful!</h2>
<p>Welcome, <?php echo htmlspecialchars($username); ?>!</p>
</div>
<?php else: ?>
<?php if (!empty($errors)): ?>
<div class="error">
<h3>Please fix the following errors:</h3>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php echo $error; ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form method="post" action="">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" name="username"
value="<?php echo isset($username) ? htmlspecialchars($username) : ''; ?>" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email"
value="<?php echo isset($email) ? htmlspecialchars($email) : ''; ?>" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="confirm_password">Confirm Password:</label>
<input type="password" id="confirm_password" name="confirm_password" required>
</div>
<div class="form-group">
<label for="age">Age:</label>
<input type="number" id="age" name="age" min="1" max="120"
value="<?php echo isset($age) ? $age : ''; ?>" required>
</div>
<div class="form-group">
<label>Gender:</label>
<input type="radio" name="gender" value="male"
<?php echo (isset($gender) && $gender === 'male') ? 'checked' : ''; ?>> Male
<input type="radio" name="gender" value="female"
<?php echo (isset($gender) && $gender === 'female') ? 'checked' : ''; ?>> Female
</div>
<div class="form-group">
<input type="checkbox" id="terms" name="terms" value="1">
<label for="terms" style="display: inline;">I agree to the terms and conditions</label>
</div>
<button type="submit">Register</button>
</form>
<?php endif; ?>
</body>
</html>
Preserving Form Values
When validation fails, preserve user input so they don't have to retype everything:
<!-- Text input with preserved value -->
<input type="text" name="username"
value="<?php echo isset($_POST['username']) ? htmlspecialchars($_POST['username']) : ''; ?>">
<!-- Radio button preserved selection -->
<input type="radio" name="gender" value="male"
<?php echo (isset($_POST['gender']) && $_POST['gender'] === 'male') ? 'checked' : ''; ?>>
<!-- Checkbox preserved state -->
<input type="checkbox" name="newsletter"
<?php echo isset($_POST['newsletter']) ? 'checked' : ''; ?>>
<!-- Select dropdown preserved selection -->
<select name="country">
<option value="us" <?php echo (isset($_POST['country']) && $_POST['country'] === 'us') ? 'selected' : ''; ?>>USA</option>
<option value="uk" <?php echo (isset($_POST['country']) && $_POST['country'] === 'uk') ? 'selected' : ''; ?>>UK</option>
</select>
Redirect After Form Processing
Prevent form resubmission by redirecting after successful processing (PRG pattern - Post/Redirect/Get):
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Process form...
if ($success) {
// Redirect to success page
header('Location: success.php?name=' . urlencode($username));
exit;
}
}
?>
PRG Pattern Benefits:
- Prevents duplicate form submissions on page refresh
- Provides better user experience
- Makes URLs shareable and bookmarkable
- Always call
exitafterheader()redirect
Security Best Practices
<?php
// 1. Always check request method
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Process form
}
// 2. Sanitize output (prevent XSS)
$name = htmlspecialchars($_POST['name'], ENT_QUOTES, 'UTF-8');
// 3. Validate email
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
// 4. Trim whitespace
$username = trim($_POST['username']);
// 5. Type cast numbers
$age = intval($_POST['age']);
// 6. Check if field exists
if (isset($_POST['field_name'])) {
// Use field
}
// 7. Hash passwords
$hashed = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
Practice Exercise
Task: Create a job application form with:
- Full name (text input)
- Email (email input)
- Phone (tel input)
- Position applying for (select dropdown with 3 options)
- Experience level (radio buttons: Entry, Mid, Senior)
- Skills (multiple checkboxes: PHP, JavaScript, SQL, HTML, CSS)
- Cover letter (textarea)
- Agree to privacy policy (checkbox, required)
Requirements:
- Validate all fields
- Preserve form values on validation errors
- Display success message with applicant info
- Use proper HTML5 input types
Summary
In this lesson, you learned:
- How to create HTML forms and process them with PHP
- Differences between GET and POST methods
- How to handle different input types (text, radio, checkbox, select)
- Processing arrays from multiple selects and checkboxes
- Preserving form values after validation errors
- The Post/Redirect/Get (PRG) pattern
- Security best practices for form handling
- Complete registration form implementation
Next, we'll dive deeper into form validation techniques!