PDOStatement::fetch() returns the next row from a query result. For a query that should return one record, execute the statement and call fetch() once.
<?php
require 'config.php';
$id=3;
$sql="SELECT id,name,class,mark
FROM student
WHERE id=:id";
$stmt=$dbo->prepare($sql);
$stmt->bindValue(
':id',
$id,
PDO::PARAM_INT
);
$stmt->execute();
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row){
echo htmlspecialchars(
(string)$row['name'],
ENT_QUOTES,
'UTF-8'
);
}else{
echo 'Record not found.';
}
If no row is available, fetch() returns false. Always check the result before trying to use its columns.
If the SQL query contains no variable or external input, a simple query() can be used.
$sql="SELECT name
FROM student
WHERE id=5";
$stmt=$dbo->query($sql);
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row){
echo htmlspecialchars(
(string)$row['name'],
ENT_QUOTES,
'UTF-8'
);
}
When the ID comes from a form, URL or variable, use a prepared statement with a parameter.
The fetch mode controls the structure of the row returned by fetch().
| Fetch mode | Returned value | Access example |
|---|---|---|
PDO::FETCH_ASSOC | Associative array | $row['name'] |
PDO::FETCH_OBJ | Object | $row->name |
PDO::FETCH_NUM | Numeric array | $row[1] |
PDO::FETCH_BOTH | Both associative and numeric indexes | $row['name'] or $row[1] |
PDO::FETCH_LAZY | PDORow with lazy property/index access | $row->name or $row['name'] |
PDO::FETCH_CLASS | Object of a specified class | $row->name |
FETCH_ASSOC returns an associative array using the database column names as keys.
$stmt=$dbo->prepare(
"SELECT id,name,class
FROM student
WHERE id=:id"
);
$stmt->bindValue(
':id',
3,
PDO::PARAM_INT
);
$stmt->execute();
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row){
echo 'ID: '.(int)$row['id'];
echo '<br>Name: '.htmlspecialchars(
(string)$row['name'],
ENT_QUOTES,
'UTF-8'
);
}
Example structure:
Array
(
[id] => 3
[name] => Arnold
[class] => Three
)
FETCH_ASSOC is convenient when readable column names are preferred in application code.
FETCH_OBJ returns the row as an object whose property names correspond to the selected columns.
$row=$stmt->fetch(PDO::FETCH_OBJ);
if($row){
echo 'ID: '.(int)$row->id;
echo '<br>Name: '.htmlspecialchars(
(string)$row->name,
ENT_QUOTES,
'UTF-8'
);
}
The returned object can be accessed using property syntax such as $row->name.
FETCH_NUM returns a numerically indexed array. The first selected column uses index 0.
$row=$stmt->fetch(PDO::FETCH_NUM);
if($row){
echo 'ID: '.(int)$row[0];
echo '<br>Name: '.htmlspecialchars(
(string)$row[1],
ENT_QUOTES,
'UTF-8'
);
}
If the SQL is:
SELECT id,name,class
FROM student
the indexes are:
[0] => id
[1] => name
[2] => class
FETCH_BOTH includes both column-name keys and numeric indexes.
$row=$stmt->fetch(PDO::FETCH_BOTH);
if($row){
echo $row[0];
echo ' - ';
echo htmlspecialchars(
(string)$row['name'],
ENT_QUOTES,
'UTF-8'
);
}
The same value may therefore appear twice in the returned array, once under its numeric index and once under its column name.
FETCH_LAZY returns a PDORow object and allows values to be accessed using object properties or array indexes.
$row=$stmt->fetch(PDO::FETCH_LAZY);
if($row){
echo (int)$row[0];
echo ' - ';
echo htmlspecialchars(
(string)$row->name,
ENT_QUOTES,
'UTF-8'
);
}
The values are made available as they are accessed rather than building the same normal array structure returned by FETCH_BOTH.
FETCH_CLASS can populate an object of a specified class using result-set column names as properties.
class Student
{
public $id;
public $name;
public $class;
}
$stmt=$dbo->query(
"SELECT id,name,class
FROM student
ORDER BY id"
);
$stmt->setFetchMode(
PDO::FETCH_CLASS,
'Student'
);
while($row=$stmt->fetch()){
echo htmlspecialchars(
(string)$row->name,
ENT_QUOTES,
'UTF-8'
).'<br>';
}
This mode is useful when query results are intended to be represented as application objects.
If a fetch mode is configured on the PDO connection, fetch() can be called without specifying the mode each time.
$dbo->setAttribute(
PDO::ATTR_DEFAULT_FETCH_MODE,
PDO::FETCH_ASSOC
);
$stmt=$dbo->prepare(
"SELECT id,name,class
FROM student
WHERE id=:id"
);
$stmt->bindValue(
':id',
1,
PDO::PARAM_INT
);
$stmt->execute();
$row=$stmt->fetch();
if($row){
echo htmlspecialchars(
(string)$row['name'],
ENT_QUOTES,
'UTF-8'
);
}
In our updated PDO config.php example, the default mode is already set to PDO::FETCH_ASSOC.
fetch() automatically returns an associative-only array. Specify the mode when the returned structure matters.Although fetch() returns one row at a time, it can be called repeatedly inside a loop to process an entire result set.
$stmt=$dbo->query(
"SELECT id,name,class
FROM student
ORDER BY id"
);
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
echo (int)$row['id'].' - ';
echo htmlspecialchars(
(string)$row['name'],
ENT_QUOTES,
'UTF-8'
);
echo '<br>';
}
For more examples of displaying several records, see fetching multiple records using PDO.
false when no more rows are available.Use fetch() when you need one row or want to process rows one at a time. fetchAll() can be convenient for smaller result sets when all rows are required together.
fetch() returns false if there is no matching row. Check the result first:
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row===false){
echo 'Record not found.';
}
The way a column is accessed depends on the fetch mode.
PDO::FETCH_ASSOC -> $row['name']
PDO::FETCH_NUM -> $row[1]
PDO::FETCH_OBJ -> $row->name
Select only the columns required by the page:
SELECT id,name,class
FROM student
WHERE id=:id
When database strings are inserted into HTML, escape them for the output context using htmlspecialchars().
Do not display stored password or credential values in record-listing examples. The updated examples use normal student data instead.
Download the PDO sample scripts from the main PDO tutorial.
Sample Student Table SQL Dump
PDOStatement::fetch() returns the next row from a query result. When there are no more rows, it returns false.
PDO::FETCH_ASSOC returns a row as an associative array using database column names as keys.
PDO::FETCH_OBJ returns a row as an object whose properties correspond to the selected database columns.
FETCH_ASSOC uses column names as array keys, while FETCH_NUM uses numeric indexes beginning with zero.
fetch() returns false. Check the returned value before accessing any columns.
fetch() returns one row at a time, while fetchAll() collects all remaining rows into one array.
Yes. Set PDO::ATTR_DEFAULT_FETCH_MODE on the PDO connection, or provide the required mode directly when calling fetch().
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.
| Plusco | 03-10-2014 |
| These are great examples! Much appreciated. | |
| sachin baghel | 13-11-2018 |
| Brilliant explaination. | |