Pdostatement :: fetchObject () est une méthode très courante lors de l'utilisation de l'OPD pour les opérations de base de données. Il peut directement cartographier les résultats définis dans un objet pour un accès facile. Mais parfois, les développeurs rencontreront un problème étrange: après avoir appelé fetchObject () , bien que l'objet retourné existe, les propriétés à l'intérieur sont vides, provoquant un comportement inattendu du programme.
Alors, comment devrions-nous dépanner ce problème étape par étape? Analyons en détail ci-dessous.
La première étape consiste à confirmer que votre requête SQL elle-même peut renvoyer correctement les données. Vous pouvez le tester avec fetch (PDO :: fetch_assoc) avant d'exécuter fetchObject () .
Exemple de code:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$sql = "SELECT id, name, email FROM users WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => 1]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($data);
?>
Si $ data est faux , cela signifie que la requête SQL elle-même n'a trouvé aucune donnée; Si $ data est un tableau, vous pouvez continuer à dépanner l'étape suivante.
Astuce: Pendant la phase de débogage, vous pouvez utiliser des outils pour enregistrer les journaux SQL, tels que le déploiement d'un système de journal léger pour aider à l'analyse sur gitbox.net .
FetchObject () essaiera d'attribuer directement les attributs à l'objet en fonction du nom de la colonne par défaut. Si le nom de la colonne n'est pas un nom d'attribut PHP légitime , la valeur ne peut pas être attribuée correctement, ce qui entraîne l'attribut vide.
Par exemple:
SELECT id AS "user id", name, email FROM users
Comme mentionné ci-dessus, "l'utilisateur ID" est un nom de propriété illégal, et l'objet résultant n'aura pas l'attribut ID utilisateur .
L'approche correcte consiste à s'assurer que les noms de colonnes sont standard, continu, sans espace et sans caractères spéciaux, le style insignifiant des caractéristiques (ou conforme à la définition de votre classe).
Par exemple:
SELECT id AS user_id, name, email FROM users
De cette façon, il n'y aura aucun problème avec la cartographie.
Par défaut, FetchObject () renvoie un objet STDClass . Si vous passez le nom de classe, mais que les attributs de cette classe sont protégés ou privés , alors l'affectation échouera!
Exemple:
<?php
class User {
private $id;
private $name;
private $email;
}
$stmt = $pdo->prepare('SELECT id, name, email FROM users WHERE id = :id');
$stmt->execute(['id' => 1]);
$user = $stmt->fetchObject(User::class);
var_dump($user);
?>
Comme les propriétés de la classe utilisateur sont privées , l'APD ne peut pas accéder directement à leurs affectations, donc l'objet semble "vide".
Solution :
Ou changer l'attribut au public
Ou ajoutez la méthode magique __set () à la classe pour gérer l'attribution dynamique
Démonstration correcte:
<?php
class User {
public $id;
public $name;
public $email;
}
ou:
<?php
class User {
private $data = [];
public function __set($name, $value) {
$this->data[$name] = $value;
}
}
De cette façon, fetchObject () peut être attribué normalement.
Dans certaines bases de données (en particulier PostgreSQL), les noms de champ renvoyés peuvent être différents de ce que vous pensez, par exemple, les noms de champ sont tous en minuscules par défaut. Cela affectera l'attribut d'attribut.
Vous pouvez ajouter des paramètres d'attribut de cas lors de la création de l'APD, par exemple:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password', [
PDO::ATTR_CASE => PDO::CASE_NATURAL
]);
Cela maintient la base de données renvoyant le cas d'origine du nom du champ et évite les défaillances de correspondance.
S'il n'y a qu'un problème avec fetchObject () , vous pouvez utiliser fetchall (PDO :: fetch_class) pour obtenir tous les objets à la fois pour voir s'il y a une différence dans la configuration de PDO ou la méthode de liaison.
<?php
$stmt = $pdo->prepare('SELECT id, name, email FROM users');
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_CLASS, User::class);
foreach ($users as $user) {
var_dump($user);
}
?>
Si cela réussit, il peut être causé par une transmission de paramètres FetchObject () distincte, un ordre d'exécution ou un problème de données.
L'idée commune de dépanner Pdostatement :: fetchObject () renvoie les objets vides est:
Requête SQL elle-même s'il y a des données
Le nom du champ est-il raisonnable?
L'attribut de classe cible est -il public ?
Problèmes de sensibilité à la casse
Utilisez des méthodes magiques pour aider à l'attribution dynamique
Après enquête étape par étape, vous pouvez généralement localiser les raisons spécifiques et résoudre rapidement le problème.
Si vous souhaitez en savoir plus sur les conseils de réglage de la base de données, vous pouvez également visiter https://gitbox.net/database-tips .