Pdostatement :: fetchObject ist eine sehr praktische Methode beim Betrieb einer Datenbank mit PDO in PHP. Es kann einen Datensatz als Objekt zurückgeben und den Eigenschaften des Objekts den Wert jeder Spalte zuweisen. Wenn jedoch der Typ der Datenbankspalte nicht mit dem erwarteten Typ der Zielobjekteigenschaft übereinstimmt, können einige verwirrende Probleme auftreten, wie z. B. Fehlanpassung vom Typ, implizite Konvertierungsfehler oder Verhaltensausnahmen.
class User {
public int $id;
public string $name;
public bool $is_active;
}
$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$user = $stmt->fetchObject('User');
Nehmen wir an, dass die Spalte von IS_Active in der Benutzertabelle ein Tinyint (1) -Typ ist, und in der Benutzerklasse definieren wir den Bool -Typ. Wenn der Wert von IS_Active 1 oder 0 beträgt, können Sie erwarten, dass er automatisch in True oder False konvertiert wird. In Wirklichkeit weist PHP jedoch direkt Werte vom Typ int zu, was zu Inkonsistenzen von Typen führt und sogar direkt Fehler in den strengen Typmodus werfen.
In FetchObject wird das Datenbankfeld über __set () oder direkte Zuordnung auf Objekteigenschaften abgebildet. Es führt keine Typkonvertierung durch, weist den Wert jedoch direkt gemäß dem ursprünglichen Wert der Datenbank zu. Das heisst:
Der int -Wert in der Datenbank wird Php int int
Varchar wird String
Obwohl Tinyint (1) häufig für boolesche Werte verwendet wird, ist es tatsächlich ein Ganzzahltyp
Nach der Eingabeaufforderung von Declare (strict_types = 1) oder PHP 8.2+ wird ein Typ -Fehlanpassung zu einem Laufzeitfehler verursacht.
Ein sicherer Ansatz besteht darin, jedes Feld nach dem Erhalten des Objekts jedes Feld manuell in den entsprechenden Typ umzuwandeln. Diese Methode ist die sicherste und lesbarste.
$user = $stmt->fetchObject('User');
if ($user !== false) {
$user->id = (int)$user->id;
$user->name = (string)$user->name;
$user->is_active = (bool)$user->is_active;
}
FetchObject unterstützt die Übergabe von Konstruktorparametern. Wenn Sie einen Konstruktor entwerfen, der initialisierte Daten akzeptiert, können Sie die Typ -Konvertierung anmutig implementieren:
class User {
public function __construct(
public int $id,
public string $name,
public bool $is_active
) {}
}
$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$user = $stmt->fetchObject('User');
Das Problem hier ist jedoch: Wenn die Datenbankspaltenbestellung inkonsistent ist oder die Felder nicht genau übereinstimmen, kann eine Ausnahme ausgelöst werden.
Wenn das Datenvolumen groß ist oder die Objektstruktur komplex ist, sollten Sie eine Fabrikklasse verwenden, um die Transformationslogik zu verarbeiten.
class UserFactory {
public static function fromDb(stdClass $row): User {
return new User(
(int)$row->id,
(string)$row->name,
(bool)$row->is_active
);
}
}
$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$row = $stmt->fetchObject();
if ($row !== false) {
$user = UserFactory::fromDb($row);
}
Obwohl dies mehr Code hat, ist die Struktur klar und die Logik zentralisiert, wodurch es einfach ist, Tests und Wartung in Einheiten zu erhalten.
Sie können auch pdo :: fetch_class | verwenden PDO :: Fetch_props_Late -Modus, aber Sie müssen auch auf das Problem der Typ -Konvertierung achten. PHP macht den Typ nicht intern inferenz.
$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'User');
$user = $stmt->fetch();
Wie oben erwähnt, kann der Code, obwohl er vereinfacht ist, das Problem des obligatorischen Typs nicht lösen.
Achten Sie bei Verwendung von PDOSTATEMENT :: FetchObject für die Objektextraktion unbedingt auf die Korrespondenz zwischen Datenbankfeldtypen und Objektattributtypen. PHP führt nicht automatisch intelligente Konvertierungen durch, insbesondere nach dem Einschalten der Typ -Eingabeaufforderung müssen Entwickler die Konvertierungslogik explizit behandeln. Am meisten empfohlen ist es, die Datenextraktion und die Objektkonstruktion zu entkoppeln, z. B. die Verwendung von Fabrikklassen oder manuelle Transformationen, wodurch die Robustheit und Wartbarkeit Ihres Codes verbessert wird.
Weitere verwandte Beispiele finden Sie unter: https://gitbox.net/pdo/fetchobject-type-conversion