fetch_object
In this article, we will focus on the mysqli_fetch_object() function in PHP, which is used to fetch the next row of a MySQLi result set as an object. We will
mysqli_fetch_object() reads the next row of a MySQLi result set and returns it as a PHP object whose properties are named after the columns in your query. It is the object-oriented cousin of mysqli_fetch_assoc() and mysqli_fetch_array(): instead of writing $row['name'] you write $row->name.
This chapter covers the function signature, how to access columns, how to hydrate rows into your own classes, error handling, and when to reach for it versus the array-based fetchers.
Syntax
mysqli_fetch_object(
mysqli_result $result,
string $class = "stdClass",
array $constructor_args = []
): object|null|falseIn the object-oriented style the same call is $result->fetch_object().
| Parameter | Description |
|---|---|
$result | A result set returned by mysqli_query(), mysqli_store_result(), or mysqli_use_result(). |
$class | Optional. The name of the class to instantiate for each row. Defaults to stdClass (a generic anonymous object). |
$constructor_args | Optional. An array of arguments passed to the class constructor. |
Return value:
- An object populated with the row's columns when a row is available.
nullwhen there are no more rows (this is what ends thewhileloop).falseon failure.
Basic usage
Call the function in a while loop. Each iteration advances the internal row pointer by one until null is returned:
<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");
$result = mysqli_query($mysqli, "SELECT name, email FROM users");
if ($result) {
while ($row = mysqli_fetch_object($result)) {
printf("%s (%s)\n", $row->name, $row->email);
}
mysqli_free_result($result);
}
mysqli_close($mysqli);
?>Each $row is a stdClass object, so its properties match the selected column names (or their aliases). If a column does not exist on the row you will get a notice and null, so always select the columns you intend to read.
Important — column names, not positions. Because the object is keyed by name,
SELECT *andSELECT name, emailbehave differently for ordering. Prefer naming columns explicitly so a schema change can't break property access.
Hydrating rows into your own class
The real strength of mysqli_fetch_object() over the array fetchers is that it can build instances of your class. Pass the class name as the second argument:
<?php
class User
{
public string $name;
public string $email;
public function greet(): string
{
return "Hi, I'm {$this->name}";
}
}
$result = mysqli_query($mysqli, "SELECT name, email FROM users");
while ($user = mysqli_fetch_object($result, User::class)) {
echo $user->greet(), "\n"; // calls a real method on a real User object
}
?>Property assignment happens before the constructor runs. PHP sets the column values directly onto the object's properties first, then calls __construct(). If your class needs the constructor to see those values, account for that order:
<?php
class Product
{
public string $name;
public float $price;
public string $label;
public function __construct(string $currency = "USD")
{
// $this->name and $this->price are already set here
$this->label = "{$this->name}: {$this->price} {$currency}";
}
}
// Constructor args are passed as the third parameter:
$product = mysqli_fetch_object($result, Product::class, ["EUR"]);
?>Handling no rows and errors
Distinguish "no more rows" (null) from a genuine failure (false):
<?php
$result = mysqli_query($mysqli, "SELECT name FROM users WHERE id = 999");
if ($result === false) {
echo "Query failed: " . mysqli_error($mysqli);
} else {
$row = mysqli_fetch_object($result);
if ($row === null) {
echo "No user found.";
} else {
echo $row->name;
}
}
?>For production code, enable exception mode so failed queries throw instead of returning false:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);fetch_object vs. the other fetchers
| Function | Returns | Access columns by |
|---|---|---|
mysqli_fetch_object() | object | $row->name |
mysqli_fetch_assoc() | associative array | $row['name'] |
mysqli_fetch_array() | array (both) | $row['name'] and $row[0] |
mysqli_fetch_row() | enumerated array | $row[0] |
mysqli_fetch_all() | array of all rows | by index or name |
Choose mysqli_fetch_object() when you want clean ->property access or when you want each row turned into a domain object with behavior (methods). Choose the array fetchers when you just need plain data to loop over or serialize.
Best practices
- Use prepared statements for any value that comes from user input to prevent SQL injection; you can still call
fetch_object()on the result of a prepared statement. - Free the result with
mysqli_free_result()when you are done to release memory on large result sets. - Select only the columns you need so object properties are predictable and queries stay fast.
Conclusion
mysqli_fetch_object() walks a MySQLi result set one row at a time, returning each row as an object with column-named properties — or, when given a class name, as a fully constructed instance of your own class. It returns null when the rows run out and false on failure. Reach for it when object syntax or domain hydration reads cleaner than the array-based fetchers like mysqli_fetch_assoc().