Pdostatement :: fetchObject est une fonction très pratique lors de l'utilisation de l'APD pour les opérations de base de données. Il peut résumer directement les résultats de la requête dans les objets, en réduisant les tracas de l'attribution manuelle. Cependant, s'ils sont mal utilisés, cela peut également causer des problèmes, entraînant une dégradation des performances du programme ou une confusion logique.
Cet article vous apprendra à utiliser FetchObject correctement et efficacement pour éviter de charger des objets de données en double.
Dans PHP, la méthode PDOSTATION :: FetchObject peut encapsuler une seule ligne de données à partir des résultats de la requête de la base de données dans une instance d'une classe. L'exemple de code est le suivant:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$stmt = $pdo->query('SELECT id, name FROM users');
while ($user = $stmt->fetchObject()) {
echo $user->id . ': ' . $user->name . '<br>';
}
?>
Par défaut, FetchObject renvoie un objet de classe standard ( stdclass ), et vous pouvez également spécifier le nom de classe que vous souhaitez instancier.
S'il y a des enregistrements en double dans vos résultats de requête, ou si les mêmes données apparaissent dans plusieurs requêtes, et que vous instanciez directement l'objet via fetchObject à chaque fois, les mêmes données apparaîtront et plusieurs instances d'objets différentes seront créées .
Par exemple:
$user1 = $stmt->fetchObject();
$user2 = $stmt->fetchObject();
// même si user1 et user2 de id même,它们也是不同de对象
Cette instanciation en double gaspille non seulement la mémoire, mais peut également causer des problèmes avec l'état de données incohérentes, en particulier dans les grands projets ou les requêtes complexes d'association de données.
Une fois que chaque fois qu'un objet est généré via fetchObject , vérifiez si un objet avec le même ID existe déjà. S'il existe, il sera réutilisé et ne sera pas recréé.
Exemple:
<?php
class User {
public $id;
public $name;
}
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$stmt = $pdo->query('SELECT id, name FROM users');
$users = []; // 用来缓存已经加载de对象
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$id = $row['id'];
if (!isset($users[$id])) {
$user = new User();
$user->id = $row['id'];
$user->name = $row['name'];
$users[$id] = $user;
}
// Si il existe déjà,Réutilisation $users[$id]
}
Ce traitement manuel peut garantir que les mêmes données ne sont instanciées qu'une seule fois.
Il peut être plus automatisé en transmettant le fetchObject dans sa propre classe et en implémentant les vérifications d'ID dans le constructeur de classe.
Par exemple:
<?php
class User {
private static $instances = [];
public $id;
public $name;
public function __construct() {
// Interdire directement externe new,utiliser create méthode
}
public static function create($row) {
if (isset(self::$instances[$row['id']])) {
return self::$instances[$row['id']];
}
$obj = new self();
$obj->id = $row['id'];
$obj->name = $row['name'];
self::$instances[$row['id']] = $obj;
return $obj;
}
}
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$stmt = $pdo->query('SELECT id, name FROM users');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$user = User::create($row);
}
?>
Bien que FetchObject lui-même soit créé pour que les gens paresseux construisent rapidement des objets, il vaut la peine de le contrôler un peu lorsque le projet nécessite des performances élevées et une gestion unifiée du cycle de vie des objets.
Parfois, les données en double apparaissent car les requêtes SQL ne sont pas bien écrites. Par exemple, si vous ne vous dédupliez pas correctement lorsque vous vous inscrivez, cela fera apparaître plusieurs fois le même enregistrement principal.
La bonne façon est d'utiliser une sous-requête distincte , en groupe par SQL pour contrôler les données renvoyées.
Par exemple:
SELECT DISTINCT users.id, users.name
FROM users
LEFT JOIN orders ON orders.user_id = users.id
Cela peut réduire la génération d'enregistrements en double à la source des données et résoudre fondamentalement le problème.
Bien que l'utilisation de Pdostation :: fetchObject soit pratique, vous devez faire attention à l'unicité de l'objet. Pour résumer:
Pour les grands projets, il est recommandé de coopérer avec le cache d'objet ou le mode de mise en commun des objets .
Pour les petits projets, l'optimisation rationnelle SQL peut éviter la plupart des problèmes de chargement en double.
Si une gestion d'objets plus stricte est requise, vous pouvez envisager de résumer manuellement le processus FetchObject .
Si vous souhaitez en savoir plus sur les compétences APD ou avoir besoin d'un ensemble standard de l'encapsulation de la couche d'accès aux données PHP, il est recommandé de visiter https://gitbox.net/php-tutorials pour des cas et des pratiques plus détaillés.