When using PHP for database development, PDOStatement::fetchObject is a very practical method that can directly map query results into an object. However, in PHP 5 and PHP 7, there are some subtle but important differences in the behavior of fetchObject . Unable to understand these compatibility issues, it may cause unanticipated errors in the code on different versions.
This article will explain these differences in depth and provide actual code examples to help understand.
The basic usage of PDOStatement::fetchObject is to grab a row from the result set as an object:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users');
$user = $stmt->fetchObject();
echo $user->id;
echo $user->name;
?>
The default return is a stdClass object. Of course, you can also specify a custom class name to receive data.
PHP 5 : After the object is instantiated, the constructor (__construct) is called after the attribute is assigned .
PHP 7 : When an object is instantiated, the constructor is called first before the attribute is assigned.
This leads to an important problem: If your constructor relies on certain fields initialization, it may behave completely differently in PHP 5 and PHP 7.
Suppose there is a simple class:
<?php
class User {
public $id;
public $name;
public function __construct() {
echo "The constructor is called:id = {$this->id}, name = {$this->name}\n";
}
}
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT id, name FROM users LIMIT 1');
$user = $stmt->fetchObject('User');
?>
In PHP 5 , the output might be:
The constructor is called:id = 1, name = John
In PHP 7 , the output might be:
The constructor is called:id = , name =
Because PHP 7 calls the constructor before attribute assignment!
In PHP 5 and 7, the signature of the fetchObject method is slightly different:
fetchObject ([ string $class_name = "stdClass" [, array $ctor_args = array() ]] ) : object
PHP 5 : Support $class_name and $ctor_args
PHP 7 : It also supports $class_name and $ctor_args , but after PHP 7.2, parameter type verification is more stringent, for example, $ctor_args must be an array.
If you pass in PHP 7 a non-array as the second parameter, you will directly contact the TypeError error.
<?php
// Error demonstration(PHP 7.2+ Will report an error)
$user = $stmt->fetchObject('User', 'Wrongctor_args');
?>
The correct way to write it should be:
<?php
$user = $stmt->fetchObject('User', ['parameter1', 'parameter2']);
?>
PHP 5 : If the specified $class_name does not exist, fetchObject just returns false .
PHP 7 : If the specified $class_name does not exist, a Error exception will be directly thrown!
So in PHP 7 you have to make sure $class_name is loaded correctly, otherwise the code will break.
A safe approach is:
<?php
$className = 'User';
if (class_exists($className)) {
$user = $stmt->fetchObject($className);
} else {
throw new Exception("kind {$className} Does not exist");
}
?>
If you rely on database fields in class constructors, be sure to revisit the initialization logic in PHP 7 to avoid directly using properties that have not been assigned yet in the constructor.
Ensure that the array passed to $ctor_args is always an array to prevent type errors after PHP 7.2.
Before calling fetchObject , use class_exists to check whether the class exists to improve robustness.
If you need to be compatible with PHP 5 and PHP 7, it is recommended to use simple stdClass uniformly and manually assign values to the required objects.