Pdostatement :: fetchObject () ist eine sehr häufige Methode bei der Verwendung von PDO für Datenbankoperationen. Es kann direkt das Ergebnis in ein Objekt für einen einfachen Zugriff zuordnen. Aber manchmal stoßen Entwickler auf ein seltsames Problem: Nach dem Aufrufen von FetchObject () sind die Eigenschaften im Inneren leer, obwohl das zurückgegebene Objekt existiert, was ein unerwartes Verhalten des Programms verursacht.
Wie sollen wir bei diesem Problem Schritt für Schritt beheben? Lassen Sie uns unten im Detail analysieren.
Der erste Schritt besteht darin, zu bestätigen, dass Ihre SQL -Abfrage selbst die Daten korrekt zurückgeben kann. Sie können es mit Fetch (pdo :: fetch_assoc) testen, bevor Sie FetchObject () ausführen.
Beispielcode:
<?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);
?>
Wenn $ data falsch ist, bedeutet dies, dass die SQL -Abfrage selbst keine Daten gefunden hat. Wenn $ Data ein Array ist, können Sie den nächsten Schritt weiterhin beheben.
Tipp: Während der Debugging -Phase können Sie Tools zum Aufzeichnen von SQL -Protokollen verwenden, z .
FetchObject () versucht, dem Objekt standardmäßig Attribute gemäß dem Spaltennamen direkt zuzuweisen. Wenn der Spaltenname kein legitimer PHP -Attributname ist , kann der Wert nicht korrekt zugewiesen werden, was dazu führt, dass das Attribut leer ist.
Zum Beispiel:
SELECT id AS "user id", name, email FROM users
Wie oben erwähnt, ist "Benutzer -ID" ein illegaler Eigenschaftsname, und das resultierende Objekt hat nicht das Attribut der Benutzer -ID .
Der korrekte Ansatz besteht darin, sicherzustellen, dass die Spaltennamen Standard-, kontinuierliche, platzfreie und spezielle Charaktere-freie Unterstriche sind (oder Ihrer Klassendefinition entsprechen).
Zum Beispiel:
SELECT id AS user_id, name, email FROM users
Auf diese Weise wird es kein Problem mit der Zuordnung geben.
Standardmäßig gibt FetchObject () ein STDClass -Objekt zurück. Wenn Sie den Klassennamen in den Attributen dieser Klasse übergeben oder privat geschützt sind, fällt die Zuweisung aus!
Beispiel:
<?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);
?>
Da die Eigenschaften der Benutzerklasse privat sind, kann PDO nicht direkt auf ihre Aufgaben zugreifen, sodass das Objekt "leer" aussieht.
Lösung :
Oder ändern Sie das Attribut in die Öffentlichkeit
Oder fügen Sie die magische Methode __set () der Klasse hinzu, um die dynamische Zuordnung zu verarbeiten
Richtige Demonstration:
<?php
class User {
public $id;
public $name;
public $email;
}
oder:
<?php
class User {
private $data = [];
public function __set($name, $value) {
$this->data[$name] = $value;
}
}
Auf diese Weise kann FetchObject () normal zugeordnet werden.
In einigen Datenbanken (insbesondere PostgreSQL) können die zurückgegebenen Feldnamen sich von dem unterscheiden, was Sie beispielsweise standardmäßig für die Feldnamen unterscheiden. Dies wirkt sich auf die Attributzuweisung aus.
Sie können beim Erstellen von PDO beispielsweise die Fallattributeinstellungen hinzufügen:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password', [
PDO::ATTR_CASE => PDO::CASE_NATURAL
]);
Dadurch gibt die Datenbank den ursprünglichen Fall des Feldnamens zurück und vermeidet übereinstimmende Ausfälle.
Wenn es nur ein Problem mit FetchObject () gibt, können Sie Fetchall (pdo :: fetch_class) verwenden, um alle Objekte gleichzeitig zu erhalten, um festzustellen, ob es einen Unterschied in der PDO -Konfiguration oder -bindungsmethode gibt.
<?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);
}
?>
Wenn dies erfolgreich ist, kann es durch eine separate FetchObject () Parameterübertragung, Ausführungsreihenfolge oder ein Datenproblem verursacht werden.
Die gemeinsame Idee der Fehlerbehebung bei Pdostatement :: FetchObject () gibt leere Objekte zurück:
SQL Abfragen selbst, wenn Daten vorhanden sind
Ist der Feldname angemessen?
Ist das Zielklassenattribut öffentlich ?
Fallempfindlichkeitsprobleme
Verwenden Sie magische Methoden, um die dynamische Zuordnung zu unterstützen
Nach Schritt -für -Schritt -Untersuchung können Sie normalerweise die spezifischen Gründe finden und das Problem schnell lösen.
Wenn Sie mehr über Tipps zur Datenbank-Tuning erfahren möchten, können Sie auch https://gitbox.net/database-tips besuchen.