Notice: Use of undefined constant NONE - assumed 'NONE' in /home/developpez/www/developpez-com/upload/entityphp/index.php on line 21
EntityPHP • Retrieve data
EntityPHP

This page is not translated yet!

Retrieve data

  1. Une nouvelle classe : EntityRequest
  2. Filtrer les données
  3. Ordonner les résultats
  4. Limiter le nombre de résultats

Une nouvelle classe : EntityRequest

Afin de pouvoir tester les exemples qui vont venir, nous admettrons que le code ci-dessous a été executé afin de remplir la base de données :

<?php
    $smallLife  = Objects::getById(1);
    $normalLife = Objects::getById(2);
    $bigLife    = Objects::getById(3);
    $smallMana  = Objects::getById(4);
    $normalMana = Objects::getById(5);
    $bigMana    = Objects::getById(6);
 
    $monster1 = PetMonsters::add(new PetMonsters('Monster 1', 100));
    $monster2 = PetMonsters::add(new PetMonsters('Monster 2', 80));
    $monster3 = PetMonsters::add(new PetMonsters('Monster 3', 60));
 
    $character1 = new Characters('Char1', 200, 'Character 1', 'Normal', $monster1);
    $character2 = new Characters('Char2', 130, 'Character 2', 'Paralysé', $monster2);
    $character3 = new Characters('Char3', 120, 'Character 3', 'Normal', $monster3);
 
    //On admet que le setter setObjects a été défini dans la classe Characters
    $character1->setObjects(array($smallLife,$smallLife,$smallMana,$normalMana,$bigMana));
    $character2->setObjects(array($smallMana,$smallMana,$normalLife,$normalLife,$bigLife));
    $character3->setObjects(array($normalLife,$normalMana,$bigLife,$bigMana));
 
    Characters::add($character1);
    Characters::add($character2);
    Characters::add($character3);
?>

Jusque là, nous avons récupéré nos données uniquement avec la méthode getById().
Cette méthode est très pratique pour récupérer les informations d'une entité, mais qu'en est-il si nous souhaitons faire des requêtes plus complexes ?

C'est là qu'entre en jeu une autre classe apportée par EntityPHP : EntityRequest.

Cette classe permet de générer des requêtes sur notre base afin de sélectionner précisément ce que nous souhaitons récupérer. Pour créer une instance de EntityRequest, il suffit d'appeler la méthode createRequest() de la classe à requêter :

<?php
    $request = Characters::createRequest();
?>

Une instance d'EntityRequest possède plusieurs méthodes vous permettant de construire une requête de sélection. Une fois celle-ci terminée, il vous suffit d'appeler la méthode exec() pour l'exécuter :

<?php
    $request = Characters::createRequest();
 
    $results = $request->exec();
 
    echo '<pre>',var_dump($results),'</pre>';
?>
	object(EntityPHP\EntityArray)#8 (3) {
	  ["i":"EntityPHP\EntityArray":private]=>
	  int(0)
	  ["array":"EntityPHP\EntityArray":private]=>
	  array(4) {
		[0]=>
		object(Characters)#3 (9) {
		  ["name":protected]=>
		  string(4) "Toto"
		  ["life":protected]=>
		  string(3) "100"
		  ["description":protected]=>
		  string(3) "..."
		  ["dateCreation":protected]=>
		  string(10) "2012-05-30"
		  ["status":protected]=>
		  string(6) "Normal"
		  ["monster":protected]=>
		  NULL
		  ["objects":protected]=>
		  array(0) {
		  }
		  ["id":protected]=>
		  string(1) "1"
		  ["id_monster"]=>
		  string(1) "2"
		}
		[...]
	  }
	  ["entity":"EntityPHP\EntityArray":private]=>
	  string(10) "Characters"
	}

Exécuter une requêtre retourne une instance d'EntityArray contenant les entités trouvées par la requête. Comme vous pouvez le constater, appeler exec() sans rien faire d'autres permet donc de récupérer toutes les entités de la classe appelante. Pour informations, l'exemple ci-dessus aurait pu s'écrire de cette façon, plus simple :

<?php
    $results = Characters::getAll();
 
    echo '<pre>',var_dump($results),'</pre>';
?>

Filtrer les données

Récupérer toutes les données d'une table est pratique, mais pas forcément adapté à nos besoins. Il est donc possible de les filtrer via la méthode where().

Cette méthode prend en paramètre une chaine de caractères indiquant les conditions à vérifier afin de sélectionner les instances.
Notez que vous pouvez utilisez toutes les comparaisons propres aux requêtes SQL, il est juste nécessaire de remplacer toutes les valeurs qui ne sont pas des noms de propriétés par un point d'interrogation.

La méthode accepte un second paramètre qui doit être un tableau contenant les valeurs qui remplaceront les points d'interrogation du premier paramètre. Un exemple vous aidera sûrement à comprendre le principe :

<?php
    $request = Characters::createRequest();
 
    //On ne récupère que les personnages ayant 120 points de vie ou moins
    $results = $request->where('life <= ?', array(120))
                       ->exec();
 
    //Affichage de chaque objet trouvé
    foreach($results as $obj)
    {
        echo $obj;
    }
?>
	Characters Object
	(
		[name:protected] => Toto
		[life:protected] => 100
		[description:protected] => ...
		[dateCreation:protected] => 2012-05-30
		[status:protected] => Normal
		[monster:protected] => 
		[objects:protected] => Array
			(
			)

		[id:protected] => 1
		[id_monster] => 2
	)
	Characters Object
	(
		[name:protected] => Char3
		[life:protected] => 120
		[description:protected] => Character 3
		[dateCreation:protected] => 2012-06-02
		[status:protected] => Normal
		[monster:protected] => 
		[objects:protected] => Array
			(
			)

		[id:protected] => 4
		[id_monster] => 5
	)

Nous avons également la possiblité de filtrer selon les proprités des entités possédées par nos entités.
Ainsi, si nous souhaitons récupérer les personnages ayant un total de points de vie deux fois moins important que leur monstre, nous pouvons écrire :

<?php
    $request = Characters::createRequest();
 
    $results = $request->where('life = monster.life*?', array(2))
                       ->exec();
 
    //Affichage de chaque objet trouvé
    foreach($results as $obj)
    {
        echo $obj;
    }
?>

Notez bien que nous utilisons les noms des propriétés de nos classes : nous ne nous nous occupons pas des clés étrangères générées par EntityPHP ni des jointures à effectuer entre les tables : la librairie s'en occupe pour nous !

Pour les curieux, vous avez la possibilité de récupérer la requête SQL générée en appelant la méthode getSQLRequest() :

<?php
    $request = Characters::createRequest();
 
    $results = $request->where('life = monster.life*?', array(2));
 
    echo $results->getSQLRequest();
?>
	SELECT Characters.name,Characters.life,Characters.description,Characters.dateCreation,Characters.status,Characters.id_monster,Characters.id
	FROM Characters
	JOIN PetMonsters
	ON PetMonsters.id=Characters.id_monster
	WHERE Characters.life = PetMonsters.life * 2 ORDER BY Characters.id;

Ce qui est quand même moins agréable à lire et à écrire, n'est-ce pas ?

Ordonner les résultats

La classe EntityRequest permet également d'ordonner les résulats, et ce avec la méthode orderBy().

Elle prend comme paramètre une chaine de caractères contenant le nom de la propriété sur laquelle doit se baser le tri :

<?php
    $request = Characters::createRequest();
 
    //On tri selon les points de vie des personnages
    $results = $request->orderBy('life')
                       ->exec();
 
    //Affichage de chaque objet trouvé
    foreach($results as $obj)
    {
        //On admet que les getters ont été définis dans la classe Characters
        echo $obj->getName(),' (',$obj->getLife(),')<br />';
    }
?>
	Toto (100)
	Char3 (120)
	Char2 (130)
	Char1 (200)

Il est également possible d'utiliser le mot-clé DESC afin de définir un tri descendant :

<?php
    $request = Characters::createRequest();
 
    //On tri selon les points de vie des personnages
    $results = $request->orderBy('life DESC')
                       ->exec();
 
    //[...] => Affichage de chaque objet trouvé
?>
	Char1 (200)
	Char2 (130)
	Char3 (120)
	Toto (100)

Il est également possible de trier selon plusieurs propriétés : pour cela, il vous suffit de les séparer par une virgule.
De plus, tout comme pour la méthode where(), il est possible de trier selon les propriétés des entités possédées :

<?php
    $request = Characters::createRequest();
 
    //On tri selon les nom des personnages, puis selon les prix de leurs objets
    $results = $request->orderBy('name DESC, objects.price')
                       ->exec();
 
    //Dé-doublonnage des résultats
    $results->unique();
 
    //Affichage de chaque objet trouvé
    foreach($results as $character)
    {
        echo '<b>',$character->getName(),'</b><br />';
 
        $objects = $character->load('objects')->getObjects();
 
        foreach($objects as $obj)
        {
            //On admet que les getters ont été définis dans la classe Objects
            echo $obj->getName(),' (',$obj->getPrice(),')<br />';
        }
    }
?>
	Toto
	Petite potion de soin (3.00)
	Petite potion de soin (3.00)
	Grande potion de soin (8.00)
	Grande potion de mana (9.00)
	Char3
	Potion de soin (5.00)
	Potion de mana (6.00)
	Grande potion de soin (8.00)
	Grande potion de mana (9.00)
	Char2
	Petite potion de mana (4.00)
	Petite potion de mana (4.00)
	Potion de soin (5.00)
	Potion de soin (5.00)
	Grande potion de soin (8.00)
	Char1
	Petite potion de soin (3.00)
	Petite potion de soin (3.00)
	Petite potion de mana (4.00)
	Potion de mana (6.00)
	Grande potion de mana (9.00)

Notez dans cet exemple l'appel à la méthode unique() de EntityArray : celle-ci permet de supprimer tous les doublons du tableau.
La requête SQL générée retourne en effet chaque personnage pour chaque objet qu'il contient. Essayez ce code en supprimant l'appel à unique() pour bien comprendre !

Limiter le nombre de résulats

Il est possible de ne récupérer qu'un nombre précis de résultats en utilisant la méthode getOnly().
Ainsi, si nous ne souhaitons récupérer que trois objets, il nous faut écrire ceci :

<?php
    $request = Objects::createRequest();
 
    //On ne récupère que les trois premiers objets
    $results = $request->orderBy('id')
                       ->getOnly(3)
                       ->exec();
 
    //Affichage de chaque objet trouvé
    foreach($results as $obj)
    {
        echo $obj->getName(),'<br />';
    }
?>
	Petite potion de soin
	Potion de soin
	Grande potion de soin

Cette méthode accepte un second paramètre qui permet d'indiquer à partir de quel index récupérer les données. Notez que le premier résultat a pour index 0 !

<?php
    $request = Objects::createRequest();
 
    //On ne récupère que les trois premiers objets à partir de l'index 3
    $results = $request->orderBy('id')
                       ->getOnly(3,3)
                       ->exec();
 
    //[...] => Affichage de chaque objet trouvé
?>
	Petite potion de mana
	Potion de mana
	Grande potion de mana

Autre point important : si vous demandez à getOnly() de ne récupérer qu'un seul résultat, exec() ne renverra alors plus une instance d'EntityArray, mais directement l'objet Entity s'il est trouvé ! Si celui-ci est introuvable, null sera renvoyé, tout comme la méthode getById() de Entity :

<?php
    $request = Objects::createRequest();
 
    //On ne veut récupérer que le dernier objet enregistré
    $obj = $request->orderBy('id DESC')
                   ->getOnly(1)
                   ->exec();
 
    if(!is_null($obj))
    {
        echo $obj;
    }
?>
	Objects Object
	(
		[name:protected] => Grande potion de mana
		[price:protected] => 9.00
		[id:protected] => 6
	)