Siksha Sarovar

Siksha Sarovar (sikshasarovar.com) is a free educational web application that helps students in India learn programming and prepare for academic and competitive exams. The platform offers structured coding courses (C, C++, Python, Java, HTML, CSS, PHP, Power BI, AI, Machine Learning, Data Science), complete university curriculum notes for BCA/MCA students with previous year question papers, Class 10 and Class 12 CBSE/HBSE school notes, and dedicated preparation material for SSC, UPSC, Banking, Railway and other government exams. Browsing the site is completely free and requires no account. Users may optionally sign in with Google solely to save their learning progress, quiz scores and personal preferences across devices.

Privacy Policy | Terms of Service | Contact Siksha Sarovar | About Siksha Sarovar

v4.0.9 · PWA
Siksha Sarovar logo
Siksha Sarovar
Your Learning Universe

Siksha Sarovar is a free e-learning platform for coding courses, BCA university notes and competitive exam preparation. Optional Google sign-in saves your learning progress across devices.

Initializing knowledge base…
Compiling modules 0%

Practical 15: Login Form Design and Validation in PHP

Lesson 22 of 35 in the free Web Based Programming Lab notes on Siksha Sarovar, written by Rohit Jangra.

Aim

To design a login form and validate it with PHP — server-side field checks plus hashed password verification using password_hash() / password_verify().

Theory

Validation must happen on the server. HTML attributes like required and JavaScript checks only improve the user experience; anyone can bypass them with DevTools or curl. The server therefore re-checks everything: trim() strips accidental whitespace and empty() catches missing or blank fields before any credential work begins.

Passwords are never stored or compared as plain text. password_hash($pwd, PASSWORD_DEFAULT) produces a salted bcrypt string (~60 characters) that encodes the algorithm, cost, random salt and digest together. Because the salt is random, hashing the same password twice gives different strings — so equality tests on hashes are useless; password_verify($input, $hash) extracts the salt, re-hashes the input and compares safely. Practical 10 compared plain strings; this is the production upgrade.

The validation ladder runs cheapest-first: empty fields → unknown username → wrong password → success. One trade-off: the distinct messages User '…' not found. and Incorrect password. are instructive in a lab but let an attacker enumerate valid usernames — production systems reply with one generic "invalid credentials" message.

Requirements

  • XAMPP/WAMP with Apache and PHP 8.x
  • Code editor (VS Code)
  • Browser (Chrome/Edge) — the form must be POSTed, so run it under Apache, not the CLI

Procedure

  1. Start Apache from the XAMPP Control Panel.
  2. Save the snippet as p15_login_validation.php in C:\xampp\htdocs\wbplab.
  3. Open http://localhost/wbplab/p15_login_validation.php — the login form appears.
  4. Try an unknown username, then rohit with a wrong password, then rohit / rohit@123 — each stage of the ladder produces its own message.
  5. Click Logout on the success panel to return to the form.

Explanation of the Code

  • $users maps usernames to freshly computed password_hash() values — two demo accounts, rohit and student. (Real apps hash once, at registration, and store the result in a database.)
  • The handler runs only when $_SERVER["REQUEST_METHOD"] === "POST" and the login button is present in $_POST.
  • trim($_POST["username"] ?? "") reads each field safely; ?? supplies a fallback when the key is missing.
  • The ladder: empty() on either field → All fields are required!; !isset($users[$username])User '…' not found.; !password_verify($password, $users[$username])Incorrect password.; otherwise $success = true and the name is kept in $loggedUser.
  • $dashDisplay/$loginDisplay ternaries flip the success panel and the form — the same self-posting pattern as Practical 10. $error is echoed through htmlspecialchars(), essential here because the "not found" message embeds the typed username.
  • The Logout button only calls the client-side doLogout() display toggle; genuine session logout is Practical 16's subject.

Expected Output

First load shows the teal Login form with the hint rohit / rohit@123. Submitting admin with any password gives the red message User 'admin' not found.; rohit with a wrong password gives Incorrect password.; blank fields (with required bypassed) give All fields are required!. The pair rohit / rohit@123 replaces the form with a green panel — ✓ Login Validated, Welcome, rohit! and a note that the password was checked with password_verify() — whose red Logout button flips back to the form with ✓ Logged out successfully.

🎯 Viva Questions

  1. The inputs have required — why validate in PHP at all? Client-side checks are advisory; requests can be forged without the browser, so only server-side validation is authoritative.
  2. What does password_hash() return? A self-contained string (~60 chars for bcrypt) encoding algorithm, cost, random salt and digest — everything password_verify() later needs.
  3. Why not compare password_hash($input) === $storedHash? Each call uses a fresh random salt, so the same password never hashes to the same string; only password_verify() can match them.
  4. Why are separate "user not found" / "incorrect password" messages risky in production? They confirm which usernames exist, enabling user enumeration; production returns one generic failure message.
  5. What do trim() and the ?? operator contribute? trim() removes stray whitespace so " rohit " still matches; ?? avoids undefined-index warnings when a key is absent.
  6. Where would the $users array live in a real application? In a database table storing hashes created at registration, with the logged-in state then carried by a session rather than a page-local variable.

CO Mapping

CO1, CO2