Comme toute autre extension de base de données, PDO peut créer des instances de classes existantes directement à partir des données sélectionnées. Cependant, contrairement à d’autres extensions, PDO fournit de nombreuses fonctionnalités permettant une manipulation d’objets puissante et flexible.
Obtenir un seul objet
Pour créer un seul objet à partir des résultats d'une requête, il existe deux méthodes .
1. Utilisez la méthode fetch() familière :
class User {}; $stmt = $pdo->query('SELECT name FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS, 'User'); $user = $stmt->fetch();
2. >Bien que les deux extraits de code vous donnent la même instance de la classe User,
class User {}; $user = $pdo->query('SELECT name FROM users LIMIT 1')->fetchObject('User');
Cette dernière approche semble définitivement plus propre. De plus, si la méthode fetch() est utilisée mais que la classe n'est pas définie avec un tel nom, un tableau sera renvoyé silencieusement, tandis que l'utilisation de fetchObject() générera une erreur appropriée.
/* object(User)#3 (1) { ["name"] => string(4) "John" } */
Bien sûr, les deux méthodes décrites ci-dessus peuvent être utilisées avec une instruction while familière pour obtenir du résultat de la base de données doubler.
Utilisez une méthodefetchAll()
pratique pour obtenir tous les enregistrements renvoyés dans le tableau d'objets à la fois :vous donnera un tableau composé d'un utilisateur composition de l'objet de classe, renvoie les propriétés de remplissage des données :
class User {}; $users = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_CLASS, 'User');
/* array(2) { [0]=> object(User)#3 (1) { ["name"] => string(4) "John" } [1]=> object(User)#4 (1) { ["name"]=> string(4) "Mike" } } */
PDO::FETCH_UNIQUE et PDO::FETCH_GROUP Utilisez-le en combinaison pour obtenir un tableau de résultats indexés par champs uniques, ou séparément pour regrouper les résultats à l'aide de champs non uniques. Par exemple, le code ci-dessous renverra un tableau où l'identifiant de l'enregistrement sera utilisé comme index de tableau au lieu d'un nombre consécutif.
class User {}; $stmt = $pdo->query('SELECT id, id, name, car FROM users'); $users = ->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_UNIQUE, 'User');
Quelle que soit la méthode sélectionnée, toutes les colonnes renvoyées par la requête seront affectées aux colonnes correspondantes en fonction aux règles suivantes Attributs de classe :
1. S'il existe un attribut de classe dont le nom est le même que le nom de la colonne, alors la valeur de la colonne sera attribuée à l'attribut 2. il n'existe pas d'attribut de ce type, alors il sera appelé Une méthode magique __set()3. Si la méthode __set() n'est pas définie pour la classe, alors une propriété publique sera créée et assignée à une valeur de colonne. . Par exemple, ce codevous donnera un objet avec toutes les propriétés automatiquement attribuées, qu'elles existent ou non dans la classe :
class User { public $name; } $user = $pdo->query('SELECT * FROM users LIMIT 1')->fetchObject('User');
De ceci Comme vous pouvez le voir, afin d'éviter de créer automatiquement des propriétés, vous pouvez utiliser la méthode magique __set() pour filtrer les propriétés. La technique de filtrage la plus simple est une méthode __set() vide. En utilisant cela, seules les propriétés existantes seront définies :
/* object(User)#3 (4) { ["id"] => string(3) "104" ["name"] => string(4) "John" ["sex"] => string(4) "male" ["car"] => string(6) "Toyota" } */
Comme ci-dessus, PDO peut également attribuer des valeurs aux propriétés privées.
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" } } */
Bien sûr, pour les objets nouvellement créés, nous devrons peut-être fournir des paramètres de constructeur. A cet effet, les méthodes fetchObject()
etfetchAll() disposent d'un paramètre dédié que vous pouvez utiliser pour passer les paramètres du constructeur sous la forme d'un tableau. Supposons que nous ayons une classe User qui possède une propriété car qui peut être définie dans le constructeur en fournissant une variable :
Lors de l'obtention de l'enregistrement, nous devrions ajouter un tableau de paramètres du constructeur :
class User { public function __construct($car) { $this->car = $car; } }
$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" } */
mysql_fetch_object()
Remarque :Si vous utilisez mysql_fetch_object et spécifiez une classe, les propriétés seront définies avant l'exécution du constructeur. Ce n'est généralement pas un problème, mais si votre propriété est définie via la méthode magique __set()
, alors la logique du constructeur doit être exécutée en premier, sinon cela peut causer des problèmes majeurs.Malheureusement, mysql est une extension mysqli, mais nous utilisons PDO. Alors, existe-t-il un moyen de dire à PDO d'attribuer des propriétés après l'exécution du constructeur. Pour cela, la constante PDO::FETCH_PROPS_LATE doit être utilisée.
Utiliser fetchAll() sera très simple,Lors de la récupération d'une seule ligne, nous devons appeler setFetchMode() et fetchObject() en même temps, ce qui peut être un un peu gênant.
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']);
Le code ci-dessus n'est pas efficace car il faut écrire deux fois le nom de la classe.
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" } */
Mais, comme mentionné ci-dessus, cela ne nous aidera pas à gérer les messages d'erreur si une classe n'est pas définie.
$stmt = $pdo->query('SELECT name, car FROM users LIMIT 1'); $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'User', ['Caterpillar']); $user = $stmt->fetch();
Il existe également un indicateur plus intéressant qui indique à PDO d'obtenir la classe à partir de la valeur du nom de la première colonne. En utilisant cet indicateur, vous pouvez éviter d'utiliser setFetchMode() et fetch() :
De plus, ce mode sera utile si des objets de classes différentes peuvent être créés à partir de la même requête
$data = $pdo->query("SELECT 'User', name FROM users") ->fetch(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE); /* object(User)#3 (1) { ["name"]=> string(4) "John" } */
Cependant, lors de l'utilisation de ce modèle, il semble impossible de transmettre des paramètres dans le constructeur de classe.
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" } }*/
除了创建新对象,PDO还可以更新现有对象。只使用setFetchMode(),它将现有变量作为参数。显然,使用fetchAll()是无用的。 如上,fetch()调用返回的是相同的对象,这在我看来是多余的。还要注意,与PDO::FETCH_CLASS不同,这种模式不分配私有属性。 Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!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"
} */