Bei Verwendung von PHP für die Datenbankentwicklung ist PDOSTATEMENT :: FetchObject eine sehr praktische Methode, mit der die Ergebnisse der Abfragen direkt in ein Objekt abbilden können. In Php 5 und Php 7 gibt es jedoch einige subtile, aber wichtige Unterschiede im Verhalten von FetchObject . Es kann diese Kompatibilitätsprobleme nicht verstehen, und kann unerwartete Fehler im Code in verschiedenen Versionen verursachen.
Dieser Artikel erläutert diese Unterschiede in der Tiefe und liefert tatsächliche Code -Beispiele für das Verständnis.
Die grundlegende Verwendung von Pdostatement :: FetchObject besteht darin, eine Zeile aus dem Ergebnis als Objekt zu holen:
<?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;
?>
Die Standardrendite ist ein STD -Class -Objekt. Natürlich können Sie auch einen benutzerdefinierten Klassennamen angeben, um Daten zu empfangen.
Php 5 : Nachdem das Objekt instanziiert wurde, wird der Konstruktor (__construct) aufgerufen , nachdem das Attribut zugewiesen wurde .
Php 7 : Wenn ein Objekt instanziiert wird, wird der Konstruktor zuerst aufgerufen, bevor das Attribut zugewiesen wird.
Dies führt zu einem wichtigen Problem: Wenn Ihr Konstruktor auf bestimmte Felder -Initialisierung angewiesen ist, kann er sich in Php 5 und Php 7 völlig unterschiedlich verhalten.
Angenommen, es gibt eine einfache Klasse:
<?php
class User {
public $id;
public $name;
public function __construct() {
echo "Der Konstruktor heißt: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 könnte der Ausgang sein:
Der Konstruktor heißt:id = 1, name = John
In Php 7 könnte der Ausgang sein:
Der Konstruktor heißt:id = , name =
Weil Php 7 den Konstruktor vor Attributzuweisung aufruft!
In Php 5 und 7 unterscheidet sich die Signatur der FetchObject -Methode geringfügig:
fetchObject ([ string $class_name = "stdClass" [, array $ctor_args = array() ]] ) : object
Php 5 : Unterstützung $ class_name und $ ctor_args
PHP 7 : Es unterstützt auch $ class_name und $ ctor_args , aber nach PHP 7.2 ist die Überprüfung des Parametertyps strenger, beispielsweise muss $ ctor_args ein Array sein.
Wenn Sie als zweites Parameter Php 7 ein Nicht-Array übergeben, kontaktieren Sie direkt den TypeError- Fehler.
<?php
// Fehlerdemonstration(PHP 7.2+ Meldet einen Fehler)
$user = $stmt->fetchObject('User', 'Falschctor_args');
?>
Der richtige Weg, es zu schreiben, sollte sein:
<?php
$user = $stmt->fetchObject('User', ['Parameter1', 'Parameter2']);
?>
Php 5 : Wenn der angegebene $ class_name nicht existiert, gibt FetchObject nur false zurück.
Php 7 : Wenn der angegebene $ class_name nicht vorhanden ist, wird eine Fehlerausnahme direkt ausgeworfen!
In PHP 7 müssen Sie also sicherstellen, dass $ class_name korrekt geladen wird, andernfalls wird der Code brechen.
Ein sicherer Ansatz ist:
<?php
$className = 'User';
if (class_exists($className)) {
$user = $stmt->fetchObject($className);
} else {
throw new Exception("Art {$className} Existiert nicht");
}
?>
Wenn Sie sich auf Datenbankfelder in Klassenkonstruktoren verlassen, sollten Sie die Initialisierungslogik in PHP 7 noch einmal besuchen, um direkte Eigenschaften zu vermeiden, die im Konstruktor noch nicht zugewiesen wurden.
Stellen Sie sicher, dass das an $ ctor_args übergebene Array immer ein Array ist, das nach PHP 7.2 Typ -Fehler verhindern.
Verwenden Sie vor dem Aufrufen von FetchObject Class_exists , um zu überprüfen, ob die Klasse vorhanden ist, um die Robustheit zu verbessern.
Wenn Sie mit PHP 5 und PHP 7 kompatibel sein müssen, wird empfohlen, einfache STD -Klasse einheitlich zu verwenden und den erforderlichen Objekten die Werte manuell zuweisen.