Theory
The client check that was not enough
The portal's registration form uses a little JavaScript to check the email looks valid before submitting. A student disables JavaScript, or crafts a request by hand, and sends garbage straight to your PHP.
This is why one rule is iron: client-side validation is a convenience, server-side validation is the real security. The browser check can always be bypassed; the server check cannot. This lesson gives the portal proper server-side validation with PHP's filter_var, and teaches it to speak JSON, the format every modern front-end and API uses.
Theory
filter_var: validate and sanitize
PHP ships a filter engine reached through filter_var($value, FILTER_...):
- FILTER_VALIDATE_EMAIL: returns the email if valid, or false if not
- FILTER_VALIDATE_INT, FILTER_VALIDATE_URL: the same idea for numbers and URLs
- FILTER_SANITIZE_...: clean rather than check (strip unwanted characters)
The pattern: if (filter_var($email, FILTER_VALIDATE_EMAIL)) { ... } else { echo "Invalid email"; }. Because a valid result is the value and an invalid one is false, this reads cleanly. Filters are the standard, reliable way to validate on the server, better than hand-writing fragile checks.
Practical
Validate an email, then answer in JSON
<?php
$email = trim($_POST["email"] ?? "");
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$response = ["ok" => true, "message" => "Registered: " . $email];
} else {
$response = ["ok" => false, "message" => "Invalid email"];
}
// Turn the PHP associative array into a JSON string:
header("Content-Type: application/json");
echo json_encode($response);
// -> {"ok":true,"message":"Registered: riya@x.com"}
?>
Theory
json_encode and json_decode
JSON is how PHP talks to JavaScript front-ends (BCA405-01) and APIs. Two functions bridge them:
- json_encode($data): PHP array/object → JSON string. An associative array becomes a JSON object
{}; an indexed array becomes a JSON array[] - json_decode($string): JSON string → PHP. By default you get an object; pass
trueas the second argument (json_decode($s, true)) to get an associative array instead
So the portal can json_encode its registration record to send to the browser, and json_decode incoming JSON to process it. The encode/decode pair is the exam's core JSON question, along with the assoc-array-versus-object mapping.
Quiz
The portal validates an email with JavaScript in the browser. Why is server-side validation with filter_var STILL required?
- It is not; client-side JavaScript validation is sufficient
- Client-side checks can be bypassed (disabled JS, hand-crafted requests), so the server must validate too as the real guard
- filter_var is faster than JavaScript
- Server-side validation replaces the need for any client-side check
Show the answer
Client-side checks can be bypassed (disabled JS, hand-crafted requests), so the server must validate too as the real guard
Client-side validation is a usability convenience: it gives fast feedback: but it runs on the USER's machine and can always be bypassed (disable JavaScript, or send a request directly bypassing the form). So the SERVER must validate every input as the real security boundary, and filter_var is PHP's reliable tool for it. Option A is a dangerous myth that causes real breaches. Option C misses the point (speed is irrelevant to the security reason). Option D overstates it: client-side checks are still worth keeping for UX, but they NEVER replace server-side validation. Rule: validate on the client for speed, on the server for safety.
Think first
object or array from json_decode?
You json_decode an incoming JSON string of event data and want to access it like $data['seats']. What must you pass to json_decode, and what happens if you forget? Then tap.
Show the answer
Pass true as the second argument: json_decode($json, true) returns an ASSOCIATIVE ARRAY, so $data['seats'] works. If you FORGET the true, json_decode returns an OBJECT by default, and you must use OBJECT syntax instead: $data->seats. Accessing $data['seats'] on an object (or $data->seats on an array) will fail. So the second argument decides the shape: json_decode($s) gives an object (arrow access), json_decode($s, true) gives an associative array (bracket access). Pick the one matching how the rest of your code reads the data, and stay consistent. This assoc-vs-object choice is a frequent real-world and exam trip-up.
Watch out
Forms, filters, JSON traps
Trusting client validation: always re-validate on the server with filter_var.
Forgetting the true in json_decode: default gives an object (arrow access), not an array (bracket access).
Assuming filter_var returns a boolean: FILTER_VALIDATE_EMAIL returns the VALUE (truthy) or false; do not compare === true.
Not setting Content-Type: application/json: front-ends may misread the response.
Echoing decoded JSON into HTML raw: still sanitize before display (XSS).
Theory
Validated input, shared format: now, memory
The portal validates properly and speaks JSON. But it still forgets who is logged in the instant a page loads: click to a new page and you are a stranger again. The web is stateless by default, and fixing that is the next lesson: COOKIES and SESSIONS to REMEMBER a logged-in user across pages, plus sending confirmation EMAIL. This is what turns a set of pages into an actual logged-in experience.
Summary
Key takeaways
- Server-side validation is mandatory: client-side (JavaScript) checks can be bypassed and are only a UX convenience.
- filter_var($value, FILTER_VALIDATE_EMAIL/INT/URL) validates (returns value or false); FILTER_SANITIZE_* cleans.
- json_encode turns PHP data into a JSON string; associative arrays become JSON objects {}, indexed arrays become JSON arrays [].
- json_decode turns JSON into PHP: default gives an object (arrow access); pass true for an associative array (bracket access).
- Set Content-Type: application/json when returning JSON to a front-end.
- This is the same JSON you met in BCA405-01, now generated and parsed server-side.
- Memory hook: filter_var to check, json_encode out, json_decode(...,true) for an array.