PHP & Laravel — Zero to Hero Episode 09: Forms and User Input — Making PHP Interactive

What Are We Doing in This Post?

So far every PHP program we wrote had fixed data. We hardcoded names, prices, and scores directly in the code. That is fine for learning — but real websites do not work that way.

Real websites take input from users. A user types their name, clicks a button, and the page responds. That is what forms do. And PHP is what processes them on the server.

This episode is where PHP stops being a calculator and starts being a real web application.


How Do HTML Forms and PHP Work Together?

Here is the flow, step by step.

A user opens a webpage that has an HTML form — text fields, buttons, dropdowns.

The user fills in the form and clicks Submit.

The browser sends that data to the server via an HTTP request.

PHP on the server receives that data, processes it, and sends a response back.

The user sees the result.

This entire cycle happens in under a second on real websites.


GET vs POST — The Two Ways to Send Form Data

When an HTML form sends data to the server, it uses one of two methods: GET or POST.

GET method:

Data is sent in the URL itself. If you search for something on Google, look at the URL — you will see your search term right there in the address bar. That is GET.

GET is used for retrieving data — searches, filters, page numbers. It is not suitable for sensitive data like passwords because the data is visible in the URL.

POST method:

Data is sent in the body of the HTTP request — invisible in the URL. POST is used for sending sensitive or large data — login forms, registration forms, file uploads, anything where you do not want the data exposed in the URL.

Real world analogy: GET is like writing your message on a postcard — anyone who handles it can read it. POST is like putting your message inside a sealed envelope — only the recipient opens it.


Your First PHP Form

Let us build one. Create a new file called form.php in your phplearning folder and write this:

<!DOCTYPE html>
<html>
<head>
    <title>My First PHP Form</title>
</head>
<body>

<h2>Say Hello</h2>

<form method="POST" action="form.php">
    <label>Your Name:</label>
    <input type="text" name="username" />
    <br><br>
    <label>Your Age:</label>
    <input type="number" name="age" />
    <br><br>
    <button type="submit">Submit</button>
</form>

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = $_POST["username"];
    $age  = $_POST["age"];

    echo "<h3>Hello, $name! You are $age years old.</h3>";
}

?>

</body>
</html>

Visit http://localhost:8080/phplearning/form.php

Type your name and age, click Submit. The page reloads and displays your personalized message below the form.

Let us understand every part of this.


Breaking Down the Form

method="POST"

This tells the browser to send form data using the POST method — hidden in the request body, not in the URL.

action="form.php"

This tells the browser where to send the data. We are sending it back to the same file — form.php processes both displaying the form and handling the submitted data. This is called a self-processing form.

name="username"

Every input field must have a name attribute. This is the key PHP uses to find that field's value on the server. Whatever you write in name="username" becomes the key in the $_POST array.


The $_POST Superglobal

$_POST is a special built-in PHP array that automatically holds all data submitted via a POST form.

When the user submits the form, PHP automatically populates $_POST with key-value pairs where the key is the input's name attribute and the value is whatever the user typed.

<?php

// After form submission, $_POST looks like this:
// $_POST["username"] = "Gagan"
// $_POST["age"] = "22"

$name = $_POST["username"];
$age  = $_POST["age"];

?>

Similarly, $_GET holds data sent via GET method — from URL parameters.


$_SERVER["REQUEST_METHOD"] — Why We Check This

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {

}

?>

When someone first visits the page, they are making a GET request — just loading the page. No form has been submitted yet. $_POST is empty.

When they submit the form, the request method becomes POST. The if check makes sure we only try to read $_POST values after actual form submission. Without this check, PHP would throw errors trying to read $_POST["username"] when it does not exist yet.

$_SERVER is another superglobal — it contains information about the current HTTP request, server details, and the current file path.


Basic Input Validation

Never trust raw user input. Ever. This is one of the most important rules in web development.

Users can accidentally leave fields blank. Users can intentionally send malicious data. Always validate and clean input before using it.

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    $name = trim($_POST["username"]);
    $age  = trim($_POST["age"]);

    if (empty($name)) {
        echo "<p style='color:red;'>Name is required.</p>";
    } elseif (empty($age)) {
        echo "<p style='color:red;'>Age is required.</p>";
    } elseif (!is_numeric($age) || $age < 1 || $age > 120) {
        echo "<p style='color:red;'>Please enter a valid age.</p>";
    } else {
        echo "<h3>Hello, $name! You are $age years old.</h3>";
    }
}

?>

trim() removes accidental whitespace from both ends of the input.

empty() returns true if the value is an empty string, null, or zero.

is_numeric() checks whether a value is a valid number.

This is basic validation — but it already catches the most common user errors.


The $_GET Superglobal — URL Parameters

GET data comes from the URL. You have seen this before on every website — URLs like:

example.com/products?category=laptops&page=2

Everything after the ? is called the query string. PHP reads it automatically into $_GET.

Create a new file called search.php:

<!DOCTYPE html>
<html>
<head>
    <title>Search</title>
</head>
<body>

<h2>Product Search</h2>

<form method="GET" action="search.php">
    <input type="text" name="query" placeholder="Search products..." />
    <button type="submit">Search</button>
</form>

<?php

if (isset($_GET["query"])) {
    $search = trim($_GET["query"]);

    if (!empty($search)) {
        echo "<p>You searched for: <strong>$search</strong></p>";
        echo "<p>Showing results for '$search'...</p>";
    } else {
        echo "<p>Please enter a search term.</p>";
    }
}

?>

</body>
</html>

Visit http://localhost:8080/phplearning/search.php

Type something and search. Notice the URL changes to search.php?query=yourterm — the search term is right there in the URL. This is exactly how Google, Amazon, and every search feature works.

isset() checks if a variable or array key exists at all. We use it instead of empty() here because $_GET["query"] does not exist until the form is submitted — and accessing a non-existent array key throws a warning in PHP.


A Complete Real World Example — Contact Form

Let us build a complete contact form with proper validation and a success message.

Create contact.php in your phplearning folder:

<!DOCTYPE html>
<html>
<head>
    <title>Contact Us</title>
</head>
<body>

<h2>Contact Us</h2>

<?php

$errors  = [];
$success = false;

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    $name    = trim($_POST["name"] ?? "");
    $email   = trim($_POST["email"] ?? "");
    $message = trim($_POST["message"] ?? "");

    if (empty($name)) {
        $errors[] = "Name is required.";
    }

    if (empty($email)) {
        $errors[] = "Email is required.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = "Please enter a valid email address.";
    }

    if (empty($message)) {
        $errors[] = "Message is required.";
    } elseif (strlen($message) < 20) {
        $errors[] = "Message must be at least 20 characters long.";
    }

    if (empty($errors)) {
        $success = true;
    }
}

if (!empty($errors)) {
    echo "<div style='background:#fff0f0; border:1px solid #f00; padding:12px; border-radius:6px; margin-bottom:16px;'>";
    echo "<strong>Please fix the following errors:</strong><ul>";
    foreach ($errors as $error) {
        echo "<li>$error</li>";
    }
    echo "</ul></div>";
}

if ($success) {
    echo "<div style='background:#f0fff4; border:1px solid #0a0; padding:16px; border-radius:6px;'>";
    echo "<h3>Thank you, $name!</h3>";
    echo "<p>Your message has been received. We will get back to you at $email shortly.</p>";
    echo "</div>";
} else {

?>

<form method="POST" action="contact.php">

    <label>Full Name *</label><br>
    <input type="text" name="name" value="<?php echo htmlspecialchars($_POST['name'] ?? ''); ?>" style="width:100%; padding:8px; margin:6px 0 14px;" /><br>

    <label>Email Address *</label><br>
    <input type="email" name="email" value="<?php echo htmlspecialchars($_POST['email'] ?? ''); ?>" style="width:100%; padding:8px; margin:6px 0 14px;" /><br>

    <label>Message * (minimum 20 characters)</label><br>
    <textarea name="message" rows="5" style="width:100%; padding:8px; margin:6px 0 14px;"><?php echo htmlspecialchars($_POST['message'] ?? ''); ?></textarea><br>

    <button type="submit" style="background:#6366f1; color:#fff; padding:10px 24px; border:none; border-radius:6px; font-size:15px; cursor:pointer;">Send Message</button>

</form>

<?php } ?>

</body>
</html>

Visit http://localhost:8080/phplearning/contact.php

Try submitting with empty fields. Try an invalid email. Try a message that is too short. Then fill everything correctly and submit. Each scenario shows a different response.

Let us highlight two important things from this example.

filter_var with FILTER_VALIDATE_EMAIL:

PHP has a built-in function for validating email addresses. filter_var($email, FILTER_VALIDATE_EMAIL) returns the email if it is valid, or false if it is not. Never write your own email validation regex — use this built-in filter instead.

htmlspecialchars():

When we put user input back into the HTML form (to preserve what they typed after a failed submission), we wrap it in htmlspecialchars(). This converts special characters like < and > into safe HTML entities so that malicious users cannot inject HTML or JavaScript into your page. This is called XSS prevention — Cross-Site Scripting. Always use htmlspecialchars() when outputting user data back into HTML.

The ?? operator:

$_POST['name'] ?? '' means: if $_POST['name'] exists, use it — otherwise use an empty string. This prevents PHP warnings when the form has not been submitted yet and $_POST is empty.


What Did We Learn in This Post?

HTML forms send user data to PHP via GET or POST methods. GET sends data in the URL. POST sends data in the request body — suitable for sensitive information.

$_POST holds all data submitted via POST forms. $_GET holds data from URL query strings. Both are superglobals — automatically available everywhere in PHP.

$_SERVER["REQUEST_METHOD"] tells you whether the current request is GET or POST — use it to check if a form was actually submitted before trying to read $_POST.

isset() checks if a variable or array key exists. empty() checks if a value is empty. Always validate before using user input.

filter_var() with FILTER_VALIDATE_EMAIL is the proper way to validate email addresses in PHP.

htmlspecialchars() prevents XSS attacks by converting special characters before outputting user data back into HTML.

The ?? null coalescing operator safely handles missing array keys without throwing PHP warnings.


What is Coming in Episode 10?

Now that we can receive and validate user input through forms, the next step is keeping that data alive across multiple pages.

Episode 10 covers PHP sessions and cookies — how PHP remembers who a user is from one page to the next. This is how login systems work. This is how shopping carts persist. This is how "Welcome back, Gagan" appears on every page after you log in.

See you in the next one.


Next Episode: Sessions and Cookies — How PHP Remembers Users

This is Episode 09 of the PHP and Laravel — Zero to Hero series.

No comments:

Post a Comment

PHP & Laravel — Zero to Hero Episode 14: Interfaces, Abstract Classes, and Namespaces — The Last Core PHP Concepts Before Laravel

What Are We Doing in This Post? This is the final Core PHP episode. After this, we start Laravel. In Episode 13 we learned classes, objec...