Topic 3: PHP with Select, Fetch
📖 13 min read · 🎯 beginner · 🧭 Prerequisites: iframe-embed-albums-embed-video-embed-maps-input-tag-introduction, javascript-objects
Why this matters
Up until now, you've learned how to store data in a database — great. But a website that only writes data and never reads it back is pretty useless. Think about any site you've used: a product listing, a news feed, a student result page. Every one of those is pulling records out of a database and showing them on screen. That's exactly what we're building today. We're going to use PHP's SELECT query and fetch to grab rows from MySQL and render them live on a webpage — the moment things start to feel real.
What You'll Learn
- How to connect PHP to a MySQL database using
mysqli - How to write and execute a
SELECTSQL query from PHP - How to iterate over results using
fetch_assoc(),fetch_row(),fetch_array(), andfetch_object() - How to build a complete, working PHP script that displays database records in a browser
The Analogy
Picture yourself as the curator of a digital museum. Deep in the basement sits a vast storage vault (the MySQL database) packed with labeled artifact crates (rows of data). Your job is to write a retrieval order (the SELECT query), hand it to the retrieval bot (PHP + mysqli), and wait while it wheels the matching crates up to the gallery floor (the web page) one at a time. The bot knows exactly which shelf to visit because you gave it the vault's address, your access badge, and the exact crate labels you need — that's your connection string and column names. Without the retrieval order, the crates sit in the dark forever.
Chapter 1: Setting Up Your Local Environment
Before a single query can run, PHP and MySQL must both be reachable from your machine. The quickest path is one of these all-in-one local server stacks:
- XAMPP — cross-platform (Windows, macOS, Linux), most popular for beginners
- WAMP — Windows-only, lightweight
- MAMP — macOS-focused, clean interface
Install any one of them, start the Apache and MySQL services from the control panel, and you have a fully functional PHP + MySQL environment running at http://localhost. All .php files go inside the htdocs (XAMPP/WAMP) or htdocs/www folder to be served by Apache.
Chapter 2: Connecting PHP to MySQL
Every database operation starts with a connection. PHP's built-in mysqli extension (MySQL Improved) handles this with a single constructor call.
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "your_database_name";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
Key points:
$servernameis"localhost"when MySQL runs on the same machine as Apache.$usernamedefaults to"root"in local XAMPP/WAMP/MAMP installations.$passwordis an empty string""unless you set one in phpMyAdmin.$dbnamemust exactly match an existing database.$conn->connect_errorholds the error string if the connection fails;die()halts the script and prints it, preventing silent failures.
Chapter 3: Writing the SELECT Query
Once connected, you compose a SQL SELECT statement as a plain PHP string and pass it to $conn->query().
<?php
$sql = "SELECT id, name, age FROM students";
$result = $conn->query($sql);
?>
$sqlis just a string — you can build it dynamically, addWHEREclauses,ORDER BY, etc.$conn->query($sql)sends the query to MySQL and returns amysqli_resultobject on success, orfalseon failure.$resultholds the full result set in memory, ready to be iterated.
Chapter 4: Fetching Results
mysqli_result objects expose four fetch methods, each returning one row at a time from the result set:
| Method | Returns |
|---|---|
fetch_assoc() | Associative array — keys are column names ($row["name"]) |
fetch_row() | Numeric array — keys are column index numbers ($row[1]) |
fetch_array() | Both associative AND numeric — combines both access styles |
fetch_object() | stdClass object — properties are column names ($row->name) |
The most readable choice for beginners is fetch_assoc(), which lets you reference columns by their actual names.
<?php
if ($result->num_rows > 0) {
// Output data of each row
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " – Name: " . $row["name"] . " – Age: " . $row["age"] . "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
$result->num_rowstells you how many rows matched the query before you start looping — a fast sanity check.- The
whileloop callsfetch_assoc()on each iteration; when all rows are exhausted, it returnsnulland the loop ends. $conn->close()releases the database connection. Always call this when you're done.
sequenceDiagram
participant Browser
participant PHP
participant MySQL
Browser->>PHP: HTTP request for fetch_students.php
PHP->>MySQL: new mysqli(...) — connect
MySQL-->>PHP: connection OK
PHP->>MySQL: SELECT id, name, age FROM students
MySQL-->>PHP: result set (rows)
loop Each row
PHP->>PHP: fetch_assoc() → $row
PHP->>Browser: echo row data
end
PHP->>MySQL: $conn->close()
PHP-->>Browser: full HTML response
Chapter 5: Putting It All Together
Here is the complete, self-contained PHP script that connects, queries, fetches, displays, and closes — all in one file.
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "your_database_name";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// SQL query to select data
$sql = "SELECT id, name, age FROM students";
$result = $conn->query($sql);
// Fetch and display data
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " – Name: " . $row["name"] . " – Age: " . $row["age"] . "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
Chapter 6: Practical Exercise — The Full Workflow
Follow these steps in order. Each step builds on the previous one.
Step 1 — Create the database and table in phpMyAdmin (or the MySQL CLI):
CREATE DATABASE school;
USE school;
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT NOT NULL
);
AUTO_INCREMENTmeans MySQL assignsidvalues automatically — you never insert them manually.NOT NULLensuresnameandagecannot be left empty.
Step 2 — Insert sample data:
INSERT INTO students (name, age) VALUES ('Alice', 23), ('Bob', 25), ('Carol', 22);
This inserts three rows in a single statement. MySQL assigns id values 1, 2, and 3 automatically.
Step 3 — Create fetch_students.php:
Save the following script as fetch_students.php inside your XAMPP/WAMP/MAMP htdocs folder:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "school";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// SQL query to select data
$sql = "SELECT id, name, age FROM students";
$result = $conn->query($sql);
// Fetch and display data
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " – Name: " . $row["name"] . " – Age: " . $row["age"] . "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
Step 4 — Run it: Open http://localhost/fetch_students.php in your browser. You should see:
ID: 1 – Name: Alice – Age: 23
ID: 2 – Name: Bob – Age: 25
ID: 3 – Name: Carol – Age: 22
🧪 Try It Yourself
Task: Add a fourth student named Dave, age 27, to the school database, then modify fetch_students.php so it only returns students older than 22 by changing the SQL query to use a WHERE clause.
Starter snippet — updated query line:
$sql = "SELECT id, name, age FROM students WHERE age > 22";
Success criterion: When you reload http://localhost/fetch_students.php, you should see only Alice (23), Bob (25), and Dave (27) — Carol (22) should not appear because 22 > 22 is false.
🔍 Checkpoint Quiz
Q1. What does $result->num_rows represent, and why check it before the while loop?
Q2. Given the following snippet, what is printed on the first iteration of the loop?
<?php
// Assume the students table has: id=1, name='Alice', age=23
while ($row = $result->fetch_assoc()) {
echo $row["name"] . " is " . $row["age"];
break;
}
?>
A) 1 is Alice
B) Alice is 23
C) name is age
D) Nothing — fetch_assoc() returns null on the first call
Q3. What is the difference between fetch_assoc() and fetch_row()?
A) fetch_assoc() returns an object; fetch_row() returns an array
B) fetch_assoc() uses column names as keys; fetch_row() uses integer indexes
C) fetch_row() is faster and always preferred
D) They return identical data structures
Q4. You have a table called products with columns product_id, product_name, and price. Write the PHP line that executes a query to select all three columns from that table and stores the result in $result.
A1. num_rows is the count of rows returned by the query. Checking it before the loop ensures you only attempt to fetch when there is actual data — otherwise you'd enter the loop with nothing to iterate, or in some MySQL versions cause an error on a null result object.
A2. B) Alice is 23 — fetch_assoc() returns an associative array keyed by column name, so $row["name"] is 'Alice' and $row["age"] is 23.
A3. B) fetch_assoc() returns an array where keys are column names (e.g., $row["name"]). fetch_row() returns a numerically indexed array (e.g., $row[1]). Use fetch_assoc() when readability matters; fetch_row() when you know the exact column order and prefer index access.
A4.
$result = $conn->query("SELECT product_id, product_name, price FROM products");
🪞 Recap
- Use
new mysqli($servername, $username, $password, $dbname)to open a database connection and always checkconnect_error. $conn->query("SELECT ...")executes the query and returns amysqli_resultobject.fetch_assoc()retrieves one row at a time as an associative array keyed by column name; loop withwhileuntil all rows are consumed.fetch_row(),fetch_array(), andfetch_object()are alternative fetch styles for numeric, combined, or object-based access respectively.- Always call
$conn->close()after you're done to release the connection.
📚 Further Reading
- PHP mysqli Documentation — the source of truth for every
mysqlimethod and property - MySQL SELECT Statement — full syntax reference for
SELECT,WHERE,ORDER BY, and more - XAMPP Download — get the local dev environment used in this lesson
- ⬅️ Previous: JavaScript Objects
- ➡️ Next: DIV Positioning