Aim
To create a table and insert a few records into it using form data, via PDO prepared statements.
Theory
CREATE TABLE defines each column as name + type + constraints: here id INTEGER PRIMARY KEY AUTOINCREMENT (SQLite's spelling — MySQL writes id INT AUTO_INCREMENT PRIMARY KEY) gives every row an automatic unique number, and NOT NULL on name, email and course refuses empty inserts. The PRIMARY KEY is the row's identity — unique and non-null by definition.
Form values are untrusted input, so they must never be concatenated into SQL — "... VALUES ('$name')" breaks the moment someone types O'Brien, and a crafted value becomes an attack (SQL injection). Prepared statements fix this structurally: prepare() sends the SQL template with placeholders, execute() sends the values separately, and the driver guarantees a bound value can never be re-parsed as SQL. Placeholders come in positional (?) and named (:name) flavours; the snippet uses named ones, matched by the keys of the array passed to execute().
On a real page each submission arrives in $_POST — one request, one row. To make the whole flow observable in a single run, the snippet simulates three submissions with the $formSubmissions array, each element standing in for one $_POST. After an insert, $pdo->lastInsertId() would return the auto-generated id — the standard companion call, though this script verifies with a final SELECT instead.
Requirements
- XAMPP/WAMP with Apache and PHP 8.x (MySQL + phpMyAdmin when using the
mysql:DSN) - PHP PDO extension (pdo_sqlite / pdo_mysql)
- Code editor (VS Code); browser or terminal
Procedure
- Start Apache (and MySQL if you point the DSN at
mysql:host=localhost;dbname=wbp_lab_db). - Save the snippet as
p25_insert_form.phpinC:\xampp\htdocs\wbplab. - Open
http://localhost/wbplab/p25_insert_form.php, or runphp p25_insert_form.php— either way the script creates the table, replays the three simulated submissions and lists the rows. - To make it a real form page, add an HTML form with
name/email/courseinputs and replace$formSubmissionswith a single$_POSTread guarded by$_SERVER["REQUEST_METHOD"] === "POST"— each submission then inserts one row.
Explanation of the Code
ERRMODE_EXCEPTIONmakes any failed SQL throw aPDOExceptioninstead of failing silently.- Step 1 creates
studentswith four columns;AUTOINCREMENTwill hand out ids 1, 2, 3 without the inserts mentioningidat all. - Step 2 defines
$formSubmissions— three associative arrays with exactly the keys a form POST would deliver. - The
INSERTis prepared once with:name,:email,:courseplaceholders and executed three times — cheaper than re-parsing SQL per row, and injection-proof by construction. - Inside the loop
trim()cleans each value (classic form hygiene) and anInserted: ...confirmation is echoed per row. - Step 3 verifies with
SELECT ... ORDER BY idviafetchAll(PDO::FETCH_ASSOC), printing#id | name | email | coursefor every row.
Expected Output
The run prints Table 'students' created., a blank line, then Inserted: Aman (BCA), Inserted: Riya (BBA), Inserted: Rohit Kumar (BCA), then All records: followed by #1 | Aman | aman@example.com | BCA, #2 | Riya | riya@example.com | BBA and #3 | Rohit Kumar | rohit@example.com | BCA — the ids 1–3 supplied automatically by AUTOINCREMENT.
🎯 Viva Questions
- What is SQL injection? Crafting input so that, when concatenated into SQL, it changes the query's structure — e.g.
' OR '1'='1making a condition always true. - How do prepared statements prevent it? The query template and the data travel separately; bound values are treated purely as data and can never become SQL syntax.
?versus:nameplaceholders? Both bind safely;?is positional (order matters),:nameis named and matched by array key — clearer with many columns.- What does
AUTOINCREMENT/AUTO_INCREMENTdo? The database assigns the next unique integer toidautomatically on each insert. - How would you obtain the id just generated?
$pdo->lastInsertId()immediately after theexecute(). - Where would the three rows come from in the real lab? From
$_POST— one form submission per request, each handled by the same prepared insert.
CO Mapping
CO1, CO2