Heim  >  Artikel  >  Backend-Entwicklung  >  Wie erhalte ich ein PDO-Objekt und lege Eigenschaften fest? (Detaillierte Code-Erklärung)

Wie erhalte ich ein PDO-Objekt und lege Eigenschaften fest? (Detaillierte Code-Erklärung)

藏色散人
藏色散人Original
2019-03-15 13:10:202647Durchsuche

Wie jede andere Datenbankerweiterung kann PDO Instanzen vorhandener Klassen direkt aus ausgewählten Daten erstellen. Im Gegensatz zu anderen Erweiterungen bietet PDO jedoch viele Funktionen für eine leistungsstarke und flexible Objektmanipulation.

Wie erhalte ich ein PDO-Objekt und lege Eigenschaften fest? (Detaillierte Code-Erklärung)

Ein einzelnes Objekt abrufen

Um ein einzelnes Objekt aus Abfrageergebnissen zu erstellen, gibt es zwei Methoden .

1. Verwenden Sie die bekannte fetch()-Methode:

class User {};
$stmt = $pdo->query('SELECT name FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
$user = $stmt->fetch();

2. Spezielle fetchObject()-Methode:

class User {};
$user = $pdo->query('SELECT name FROM users LIMIT 1')->fetchObject('User');

Während Sie mit beiden Codeausschnitten die gleiche Benutzerklasseninstanz erhalten,

/* object(User)#3 (1) {
  ["name"] => string(4) "John"
} */

der letztere Ansatz sieht definitiv sauberer aus. Wenn außerdem die fetch()-Methode verwendet wird, die Klasse jedoch nicht mit einem solchen Namen definiert ist, wird ein Array stillschweigend zurückgegeben, wohingegen die Verwendung von fetchObject() einen entsprechenden Fehler auslöst.

Ein Array von Objekten abrufen

Natürlich können beide oben beschriebenen Methoden mit einer bekannten while-Anweisung verwendet werden, um aus der Datenbank ein Ergebnis zu erhalten Linie.

Verwenden Sie eine praktische fetchAll()-Methode, um alle zurückgegebenen Datensätze in einem Objekt-Array auf einmal abzurufen:

class User {};
$users = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_CLASS, 'User');

gibt Ihnen ein Array bestehend aus einem Objekt der Klasse User , geben Sie das Datenfüllattribut zurück:

/* array(2) {
  [0]=> object(User)#3 (1) {
    ["name"] => string(4) "John"
  }
  [1]=> object(User)#4 (1) {
    ["name"]=> string(4) "Mike"
  }
} */

Hinweis, Sie können diesen Modus mit PDO::FETCH_UNIQUE und PDO::FETCH_GROUP kombinieren. um ein durch eindeutige Felder indiziertes Ergebnisarray zu erhalten oder um Ergebnisse mithilfe nicht eindeutiger Felder separat zu gruppieren.

Der folgende Code gibt beispielsweise ein Array zurück, in dem die Datensatz-ID anstelle einer fortlaufenden Nummer als Array-Index verwendet wird.

class User {};
$stmt  = $pdo->query('SELECT id, id, name, car FROM users');
$users = ->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_UNIQUE, 'User');

Klassenattribute zuweisen

Unabhängig davon, welche Methode ausgewählt ist, werden alle von der Abfrage zurückgegebenen Spalten entsprechend den entsprechenden Klassenattributen zugewiesen den folgenden Regeln:

1. Wenn es ein Klassenattribut mit demselben Namen wie der Spaltenname gibt, wird der Spaltenwert dem Attribut zugewiesen

2 Wenn die Methode __set() nicht für die Klasse definiert ist, wird eine öffentliche Eigenschaft erstellt und ihr ein Spaltenwert zugewiesen.

Mit diesem Code

class User
{
    public $name;
}
$user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');

erhalten Sie beispielsweise ein Objekt, dem alle Eigenschaften automatisch zugewiesen werden, unabhängig davon, ob sie in der Klasse vorhanden sind:

/* object(User)#3 (4) {
  ["id"]   => string(3) "104"
  ["name"] => string(4) "John"
  ["sex"]  => string(4) "male"
  ["car"]  => string(6) "Toyota"
} */

Wie Sie sehen können Um die automatische Erstellung von Attributen zu vermeiden, können Sie die magische Methode __set() verwenden, um Attribute herauszufiltern. Die einfachste Filtertechnik ist eine leere __set()-Methode. Dadurch werden nur vorhandene Eigenschaften gesetzt:

class User
{
    private $name;
    public function __set($name, $value) {}
}
$user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');
/*
array(1) {
  [0]=> object(User)#3 (1) {
    ["name":"User":private]=> string(4) "John"
  }
} */

Wie oben kann PDO auch privaten Eigenschaften Werte zuweisen.

Übergabe von Konstruktorparametern an das Objekt Natürlich müssen wir für neu erstellte Objekte möglicherweise Konstruktorparameter bereitstellen. Zu diesem Zweck verfügen die Methoden

fetchObject()

und fetchAll() über einen eigenen Parameter, mit dem Sie Konstruktorparameter in Form eines Arrays übergeben können. Angenommen, wir haben eine Klasse „Benutzer“, die über eine Autoeigenschaft verfügt, die im Konstruktor durch Bereitstellung der Variablen festgelegt werden kann:

class User {
    public function __construct($car) {
        $this->car = $car;
    }
}

Beim Abrufen des Datensatzes sollten wir einen Konstruktor mit einem Array von Parametern hinzufügen:

$users = $pdo->query('SELECT name FROM users LIMIT 1')
             ->fetchAll(PDO::FETCH_CLASS, 'User', ['Caterpillar']);

$user = $pdo->query('SELECT name FROM users LIMIT 1')
            ->fetchObject('User',['Caterpillar']);
/* object(User)#3 (2) {
    ["name"] => string(4) "John"
    ["car"]  => string(11) "Caterpillar"
} */

Wie Sie sehen, werden die Werte in der Datenbank überschrieben, da PDO standardmäßig Klasseneigenschaften zuweist, bevor der Konstruktor aufgerufen wird. Dies kann ein Problem sein, lässt sich aber leicht beheben:

Klasseneigenschaften nach Aufruf des Konstruktors festlegen

mysql_fetch_object()

Hinweis: Wenn Sie mysql_fetch_object verwenden und eine Klasse angeben, werden die Eigenschaften festgelegt, bevor der Konstruktor ausgeführt wird. Dies ist normalerweise kein Problem, aber wenn Ihre Eigenschaft über die magische Methode

__set()

festgelegt wird, muss zuerst die Konstruktorlogik ausgeführt werden, da es sonst zu größeren Problemen kommen kann. Leider ist MySQL eine MySQL-Erweiterung, aber wir verwenden PDO. Gibt es also eine Möglichkeit, PDO anzuweisen, Eigenschaften zuzuweisen, nachdem der Konstruktor ausgeführt wurde? Hierzu muss die Konstante PDO::FETCH_PROPS_LATE verwendet werden.

Die Verwendung von fetchAll() wird sehr einfach sein,

class User {
    public function __construct($car) {
        $this->car = $car;
    }
}
$stmt  = $pdo->query('SELECT name, car FROM users LIMIT 1');
$users = $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']);

Wenn wir eine einzelne Zeile abrufen, müssen wir setFetchMode() und fetchObject() gleichzeitig aufrufen, was etwas umständlich sein kann .

class User {
    public function __construct($car) {
        $this->car = $car;
    }
}
$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User');
$user = $stmt->fetchObject('User', ['Caterpillar']);
/*
object(User)#3 (2) {
  ["car"]  => string(6) "Toyota"
  ["name"] => string(4) "John"
} */

Der obige Code ist nicht sehr effizient, da wir den Klassennamen zweimal schreiben müssen.

Alternativ können wir fetch():

$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']);
$user = $stmt->fetch();

Aber wie oben erwähnt hilft es uns nicht bei der Verarbeitung von Fehlermeldungen, wenn eine Klasse zufällig undefiniert ist.

Erhalten Sie den Klassennamen aus der Datenbank Es gibt auch ein interessanteres Flag, das PDO anweist, die Klasse aus dem Wert des zu beziehen erster Spaltenname. Mit diesem Flag können Sie die Verwendung von setFetchMode() und fetch() vermeiden:

$data = $pdo->query("SELECT 'User', name FROM users")
            ->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
/*
object(User)#3 (1) {
  ["name"]=> string(4) "John"
} */

Außerdem ist dieser Modus nützlich, wenn Objekte verschiedener Klassen aus derselben Abfrage erstellt werden können

class Male {};
class Female {};
$stmt = $pdo->query('SELECT sex, name FROM users');
$users = $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
/*
array(6) {
  [0]=> object(Male)#3 (1) {
    ["name"]=> string(4) "John"
  }
  [1]=> object(Male)#4 (1) {
    ["name"]=> string(4) "Mike"
  }
  [2]=> object(Female)#5 (1) {
    ["name"]=> string(4) "Mary"
  }
  [3]=> object(Female)#6 (1) {
    ["name"]=> string(5) "Kathy"
  }
}*/

Allerdings Bei Verwendung dieses Musters scheint es unmöglich zu sein, Parameter im Klassenkonstruktor zu übergeben.

Vorhandenes Objekt aktualisieren

除了创建新对象,PDO还可以更新现有对象。只使用setFetchMode(),它将现有变量作为参数。显然,使用fetchAll()是无用的。

class User
{
    public $name;
    public $state;

    public function __construct()
    {
        $this->name = NULL;
    }
}
$user = new User;
$user->state = "up'n'running";
var_dump($user);

$stmt = $pdo->query('SELECT name FROM users LIMIT 1');
$stmt->setFetchMode(PDO::FETCH_INTO, $user);
$data = $stmt->fetch();
var_dump($data, $user);
/*
object(Foo)#2 (2) {
  ["name"]  => NULL
  ["state"] => string(12) "up'n'running"
}
object(Foo)#2 (2) {
  ["name"]  => string(4) "John"
  ["state"] => string(12) "up'n'running"
}
object(Foo)#2 (2) {
  ["name"]  => string(4) "John"
  ["state"] => string(12) "up'n'running"
} */

如上,fetch()调用返回的是相同的对象,这在我看来是多余的。还要注意,与PDO::FETCH_CLASS不同,这种模式不分配私有属性。

Das obige ist der detaillierte Inhalt vonWie erhalte ich ein PDO-Objekt und lege Eigenschaften fest? (Detaillierte Code-Erklärung). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn