Difference between revisions of "Selecting data using JDatabase/fr"
From Joomla! Documentation
(Created page with "Nous pouvons utiliser plusieurs jonctions pour opérer une requête pour plus de deux tables :") |
(Updating to match new version of source page) |
||
(125 intermediate revisions by 4 users not shown) | |||
Line 2: | Line 2: | ||
<noinclude>{{Joomla version|version=3.x}}{{Joomla version|version=2.5|status=eos}}</noinclude> | <noinclude>{{Joomla version|version=3.x}}{{Joomla version|version=2.5|status=eos}}</noinclude> | ||
{{-}} | {{-}} | ||
− | {{tip| | + | {{tip|Remarquez que de nombreux exemples cités utilisent <code>$db->query()</code> au lieu de <code>$db->execute()</code>. C'était une méthode ancienne dans Joomla! 1.5 et 2.5 qui va émettre un message d'obsolescence à partir de Joomla 3.0+.|title=Note de version}} |
Ce didacticiel est divisé en deux parties indépendantes : | Ce didacticiel est divisé en deux parties indépendantes : | ||
* L'insertion, la mise à jour et la suppression de données de la base de données. | * L'insertion, la mise à jour et la suppression de données de la base de données. | ||
− | * La sélection | + | * La sélection de données à partir d'une ou plusieurs tables et la récupération sous différentes formes. |
− | + | Cette section de la documentation se focalise sur la sélection de données à partir d'une table de la base de données et la récupère dans différents formats. Pour voir l'autre partie | |
+ | [[S:MyLanguage/Inserting,_Updating_and_Removing_data_using_JDatabase|cliquez ici]] | ||
==Introduction== | ==Introduction== | ||
− | Joomla! | + | Joomla! fournit une couche d'abstraction sophistiquée de base de données pour en simplifier l'utilisation pour les développeurs tierces. Les nouvelles versions de l'API de la Plateforme Joomla! fournissent des fonctionnalités supplémentaires qui permettent d'étendre encore plus la couche de base de données et d'inclure des fonctionnalités telles que des connecteurs pour une plus grande variété de serveurs de base de données ou encore le chaînage de requêtes pour améliorer la lisibilité du code de connexion et simplifier le codage SQL. |
− | Joomla | + | Joomla peut utiliser différentes sortes de systèmes de base de données SQL et s'exécuter dans des environnements variés avec différents préfixes de table. En plus de ces fonctions, la classe (JDatabase) crée automatiquement la connexion à la base de données. Il suffit de deux lignes de code lors de l'instanciation de l'objet pour obtenir un résultat à partir de la base de données dans différents formats. L'utilisation de la couche de base de données Joomla assure un maximum de compatibilité et de flexibilité pour vos extensions. |
− | ==La | + | ==La Requête== |
− | Joomla' | + | Faire une requête dans la base de données Joomla a changé avec l'introduction de Joomla 1.6. Le moyen recommandé pour construire des requêtes de base de données se fait via le "chaînage de requêtes" (même si les requêtes en chaînes de caractères sont encore supportées). |
− | Le chaînage de | + | Le chaînage de requête fait référence à une méthode se connectant à un nombre de méthodes, les unes après les autres, où chaque méthode retourne un objet supportant la prochaine méthode, améliorant ainsi la lisibilité et la simplification du code. |
− | Pour obtenir une nouvelle instance de la classe | + | Pour obtenir une nouvelle instance de la classe JDatabaseQuery, nous utilisons la méthode getQuery de la classe JDatabaseDriver: |
<source lang="php"> | <source lang="php"> | ||
Line 28: | Line 29: | ||
</source> | </source> | ||
− | <tt>JDatabaseDriver::getQuery</tt> | + | <tt>JDatabaseDriver::getQuery</tt> prend un argument optionnel, <tt>$new</tt>, qui peut être ''true'' (vrai) ou ''false'' (faux) (la valeur par défaut est ''false''). |
− | Pour interroger notre source de données, nous pouvons | + | Pour interroger notre source de données, nous pouvons appeler un nombre de méthodes de la classe <tt>JDatabaseQuery</tt>; ces méthodes encapsulent le langage de requête de la source de données (dans la plupart des cas SQL), en occultant la syntaxe de requête spécifique au développeur et en augmentant la portabilité du code source du développeur. |
− | Les méthodes les plus fréquemment utilisées | + | Les méthodes les plus fréquemment utilisées incluent; <tt>select, from, join, where et order</tt>. Il y a aussi des méthodes comme <tt>insert, update et delete</tt> pour modifier des enregistrements dans la base de données. En chaînant ces appels de méthodes à d'autres, vous pouvez créer presque n'importe quelle requête à votre base de données sans compromettre la portabilité de votre code.. |
− | ==Sélectionner des enregistrements | + | ==Sélectionner des enregistrements d'une seule table== |
− | Ci-dessous un exemple de création | + | Ci-dessous se trouve un exemple de création de requête de base de données utilisant la classe <tt>JDatabaseQuery</tt>. En utilisant les méthodes ''select'', ''from'', ''where'' et ''order'', nous pouvons créer des requêtes flexibles, facilement lisibles et portable: |
<source lang="php"> | <source lang="php"> | ||
Line 49: | Line 50: | ||
$query->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering'))); | $query->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering'))); | ||
$query->from($db->quoteName('#__user_profiles')); | $query->from($db->quoteName('#__user_profiles')); | ||
− | $query->where($db->quoteName('profile_key') . ' LIKE '. $db->quote( | + | $query->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('custom.%')); |
$query->order('ordering ASC'); | $query->order('ordering ASC'); | ||
Line 58: | Line 59: | ||
$results = $db->loadObjectList(); | $results = $db->loadObjectList(); | ||
</source> | </source> | ||
+ | |||
+ | (Here the <tt>quoteName()</tt> function adds appropriate quotes around the column names to avoid conflicts with any database reserved word, now or in the future.) | ||
La requête peut également être chaînée pour la simplifier davantage : | La requête peut également être chaînée pour la simplifier davantage : | ||
Line 65: | Line 68: | ||
->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering'))) | ->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering'))) | ||
->from($db->quoteName('#__user_profiles')) | ->from($db->quoteName('#__user_profiles')) | ||
− | ->where($db->quoteName('profile_key') . ' LIKE '. $db->quote( | + | ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('custom.%')) |
->order('ordering ASC'); | ->order('ordering ASC'); | ||
</source> | </source> | ||
− | + | Les appels de méthode de chaînage améliorent la lisibilité du code et réduisent le gonflement du code à mesure que les requêtes deviennent plus longues et plus complexes. | |
Le groupement peut également être réalisé simplement. La requête suivante compterait le nombre d'articles dans chaque catégorie. | Le groupement peut également être réalisé simplement. La requête suivante compterait le nombre d'articles dans chaque catégorie. | ||
Line 75: | Line 78: | ||
<source lang="php"> | <source lang="php"> | ||
$query | $query | ||
− | ->select( array('catid', 'COUNT(*)') ) | + | ->select(array('catid', 'COUNT(*)')) |
->from($db->quoteName('#__content')) | ->from($db->quoteName('#__content')) | ||
->group($db->quoteName('catid')); | ->group($db->quoteName('catid')); | ||
</source> | </source> | ||
− | Une limite pour une requête | + | Une limite peut être définie pour une requête en utilisant <tt>setLimit</tt>. Par exemple, dans la requête suivante, jusqu'à 10 enregistrements seront retournés. |
<source lang="php"> | <source lang="php"> | ||
Line 89: | Line 92: | ||
</source> | </source> | ||
− | ==Sélectionner des enregistrements | + | |
− | + | ==Sélectionner des enregistrements de plusieurs tables== | |
+ | En utilisant les méthodes de [http://api.joomla.org/11.4/Joomla-Platform/Database/JDatabaseQuery.html#join jointure] de JDatabaseQuery, on peut sélectionner des enregistrements de multiples tables reliées. La méthode générique "join" prend deux arguments; le "type" de jointure (inner, outer, left, right) et la condition de jointure. Dans l'exemple suivant vous remarquerez que l'on peut utiliser tous les mots-clés qu'on utiliserait normalement si on écrivait une requête SQL native, incluant le mot-clé AS pour donner un surnom aux tables et le mot-clé ON pour créer des relations entre les tables. Remarquez aussi que le surnom de la table est utilisé dans toutes les méthodes qui font référence aux colonnes de la table (c-a-d select, where, order). | ||
<source lang="php"> | <source lang="php"> | ||
Line 105: | Line 109: | ||
->select(array('a.*', 'b.username', 'b.name')) | ->select(array('a.*', 'b.username', 'b.name')) | ||
->from($db->quoteName('#__content', 'a')) | ->from($db->quoteName('#__content', 'a')) | ||
− | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON | + | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id')) |
− | ->where($db->quoteName('b.username') . ' LIKE | + | ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%')) |
->order($db->quoteName('a.created') . ' DESC'); | ->order($db->quoteName('a.created') . ' DESC'); | ||
Line 116: | Line 120: | ||
</source> | </source> | ||
− | + | La méthode de jointure ci-dessus nous permet d'interroger les deux tables "content" et "users", en récupérant les articles avec leur auteur. Il y a aussi des méthodes pratiques pour les jointures: | |
* [http://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_innerJoin innerJoin()] | * [http://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_innerJoin innerJoin()] | ||
* [http://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_leftJoin leftJoin()] | * [http://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_leftJoin leftJoin()] | ||
Line 122: | Line 126: | ||
* [http://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_outerJoin outerJoin()] | * [http://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_outerJoin outerJoin()] | ||
− | Nous pouvons utiliser plusieurs | + | Nous pouvons utiliser plusieurs jointures pour interroger plus de deux tables : |
<source lang="php"> | <source lang="php"> | ||
Line 128: | Line 132: | ||
->select(array('a.*', 'b.username', 'b.name', 'c.*', 'd.*')) | ->select(array('a.*', 'b.username', 'b.name', 'c.*', 'd.*')) | ||
->from($db->quoteName('#__content', 'a')) | ->from($db->quoteName('#__content', 'a')) | ||
− | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON | + | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id')) |
− | ->join('LEFT', $db->quoteName('#__user_profiles', 'c') . ' ON | + | ->join('LEFT', $db->quoteName('#__user_profiles', 'c') . ' ON ' . $db->quoteName('b.id') . ' = ' . $db->quoteName('c.user_id')) |
− | ->join('RIGHT', $db->quoteName('#__categories', 'd') . ' ON | + | ->join('RIGHT', $db->quoteName('#__categories', 'd') . ' ON ' . $db->quoteName('a.catid') . ' = ' . $db->quoteName('d.id')) |
− | ->where($db->quoteName('b.username') . ' LIKE | + | ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%')) |
->order($db->quoteName('a.created') . ' DESC'); | ->order($db->quoteName('a.created') . ' DESC'); | ||
</source> | </source> | ||
− | + | Remarquez comment le chaînage rend le code source plus lisible pour ces longues requêtes. | |
− | + | Dans certains cas, vous aurez aussi besoin d'utiliser la clause AS lors de la sélection d'éléments pour éviter des conflits de nom de colonne. Dans ce cas, plusieurs déclarations "select" peuvent être chaînées en conjonction de l'utilisation de <tt>$db->quoteName</tt> dans le second paramètre. | |
<source lang="php"> | <source lang="php"> | ||
Line 145: | Line 149: | ||
->select($db->quoteName('b.name', 'name')) | ->select($db->quoteName('b.name', 'name')) | ||
->from($db->quoteName('#__content', 'a')) | ->from($db->quoteName('#__content', 'a')) | ||
− | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON | + | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id')) |
− | ->where($db->quoteName('b.username') . ' LIKE | + | ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%')) |
->order($db->quoteName('a.created') . ' DESC'); | ->order($db->quoteName('a.created') . ' DESC'); | ||
</source> | </source> | ||
− | + | Un second tableau peut aussi être utilisé comme deuxième paramètre de la déclaration de "select" pour alimenter les valeurs de la clause AS. Souvenez-vous d'inclure des "nulls" dans le second tableau aux colonnes correspondantes du premier tableau pour lesquelles vous ne voulez pas utiliser la clause AS: | |
<source lang="php"> | <source lang="php"> | ||
Line 157: | Line 161: | ||
->select($db->quoteName(array('b.username', 'b.name'), array('username', 'name'))) | ->select($db->quoteName(array('b.username', 'b.name'), array('username', 'name'))) | ||
->from($db->quoteName('#__content', 'a')) | ->from($db->quoteName('#__content', 'a')) | ||
− | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON | + | ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id')) |
− | ->where($db->quoteName('b.username') . ' LIKE | + | ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%')) |
->order($db->quoteName('a.created') . ' DESC'); | ->order($db->quoteName('a.created') . ' DESC'); | ||
</source> | </source> | ||
+ | ==Using OR in queries== | ||
+ | When using multiple WHERE clauses in your query, they will be treated as an AND. | ||
− | == | + | So, for example, the query below will return results where the 'name' field AND the 'state' field match. |
− | + | <source lang="php"> | |
+ | $query = $db | ||
+ | ->getQuery(true) | ||
+ | ->select('COUNT(*)') | ||
+ | ->from($db->quoteName('#__my_table')) | ||
+ | ->where($db->quoteName('name') . " = " . $db->quote($value) | ||
+ | ->where($db->quoteName('state') . " = " . $db->quote($state)); | ||
+ | </source> | ||
+ | To use a WHERE clause as an OR, the query can be written like this | ||
+ | <source lang="php"> | ||
+ | $query = $db | ||
+ | ->getQuery(true) | ||
+ | ->select('COUNT(*)') | ||
+ | ->from($db->quoteName('#__my_table')) | ||
+ | ->where($db->quoteName('name') . " = " . $db->quote($name_one), 'OR') | ||
+ | ->where($db->quoteName('name') . " = " . $db->quote($name_two)); | ||
+ | </source> | ||
+ | it can also be written like this | ||
+ | <source lang="php"> | ||
+ | $query = $db | ||
+ | ->getQuery(true) | ||
+ | ->select('COUNT(*)') | ||
+ | ->from($db->quoteName('#__my_table')) | ||
+ | ->where($db->quoteName('name') . " = " . $db->quote($name_one) | ||
+ | ->orWhere($db->quoteName('name') . " = " . $db->quote($name_two)); | ||
+ | </source> | ||
− | === | + | ==Résultats de requête== |
+ | La classe <tt>JDatabase</tt> possède plusieurs méthodes pour travailler avec un jeu de résultat d'une requête. | ||
+ | |||
+ | If there are no matches to the query, the result will be null. | ||
+ | |||
+ | === Résultat à valeur simple === | ||
==== loadResult() ==== | ==== loadResult() ==== | ||
− | + | Utilisez '''loadResult()''' quand vous souhaitez juste une seule valeur de retour de votre requête de base de données. | |
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
Line 174: | Line 210: | ||
! id !! nom !! email !! nom d'utilisateur | ! id !! nom !! email !! nom d'utilisateur | ||
|- | |- | ||
− | | 1 || style="background:yellow" | John Smith || | + | | 1 || style="background:yellow" | John Smith || johnsmith@domaine.exemple || johnsmith |
|- | |- | ||
− | | 2 || Magda Hellman || magda_h@ | + | | 2 || Magda Hellman || magda_h@domaine.exemple || magdah |
|- | |- | ||
− | | 3 || Yvonne de Gaulle || ydg@ | + | | 3 || Yvonne de Gaulle || ydg@domaine.exemple || ydegaulle |
|} | |} | ||
− | + | C'est souvent le résultat d'une requête de "comptage" pour obtenir un nombre d'enregistrements: | |
<source lang="php"> | <source lang="php"> | ||
$db = JFactory::getDbo(); | $db = JFactory::getDbo(); | ||
− | $query = $db->getQuery(true) | + | $query = $db |
− | + | ->getQuery(true) | |
− | + | ->select('COUNT(*)') | |
− | + | ->from($db->quoteName('#__my_table')) | |
+ | ->where($db->quoteName('name') . " = " . $db->quote($value)); | ||
// Reset the query using our newly populated query object. | // Reset the query using our newly populated query object. | ||
Line 194: | Line 231: | ||
$count = $db->loadResult(); | $count = $db->loadResult(); | ||
</source> | </source> | ||
− | + | ou quand vous souhaitez juste un seul champ d'une seule ligne de la table (ou un seul champ à partir de la première ligne retournée). | |
<source lang='php'> | <source lang='php'> | ||
$db = JFactory::getDbo(); | $db = JFactory::getDbo(); | ||
− | $query = $db->getQuery(true) | + | $query = $db |
− | + | ->getQuery(true) | |
− | + | ->select('field_name') | |
− | + | ->from($db->quoteName('#__my_table')) | |
+ | ->where($db->quoteName('some_name') . " = " . $db->quote($some_value)); | ||
$db->setQuery($query); | $db->setQuery($query); | ||
Line 206: | Line 244: | ||
</source> | </source> | ||
− | === | + | === Résultats à une simple ligne === |
− | + | Chacune de ces fonctions de résultats va retourner un seul enregistrement de la base de données même s'il peut y avoir plusieurs enregistrements correspondant au critère donné. Pour obtenir plus d'enregistrements vous devez encore appeler la fonction. | |
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
Line 213: | Line 251: | ||
! id !! nom !! email !! nom d'utilisateur | ! id !! nom !! email !! nom d'utilisateur | ||
|- style="background:yellow" | |- style="background:yellow" | ||
− | | 1 || John Smith || | + | | 1 || John Smith || johnsmith@domaine.exemple || johnsmith |
|- | |- | ||
− | | 2 || Magda Hellman || magda_h@ | + | | 2 || Magda Hellman || magda_h@domaine.exemple || magdah |
|- | |- | ||
− | | 3 || Yvonne de Gaulle || ydg@ | + | | 3 || Yvonne de Gaulle || ydg@domaine.exemple || ydegaulle |
|} | |} | ||
==== loadRow() ==== | ==== loadRow() ==== | ||
− | <tt>loadRow()</tt> | + | <tt>loadRow()</tt> retourne un tableau indexé d'un seul enregistrement dans la table: |
<source lang='php'> | <source lang='php'> | ||
Line 229: | Line 267: | ||
print_r($row); | print_r($row); | ||
</source> | </source> | ||
− | + | donnera : | |
<pre>Array ( [0] => 1, [1] => John Smith, [2] => johnsmith@domain.example, [3] => johnsmith ) </pre> | <pre>Array ( [0] => 1, [1] => John Smith, [2] => johnsmith@domain.example, [3] => johnsmith ) </pre> | ||
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['index'] // e.g. $row['2']</pre> | |
Remarques : | Remarques : | ||
− | # | + | # Les indices du tableau sont des nombres débutant à zéro. |
− | # | + | # Bien que vous pouvez répéter l'appel pour obtenir d'autres lignes, une des fonctions retournant plusieurs lignes peut être plus utile. |
==== loadAssoc() ==== | ==== loadAssoc() ==== | ||
− | <tt>loadAssoc()</tt> | + | <tt>loadAssoc()</tt> retourne un tableau associatif d'un seul enregistrement dans la table: |
<source lang='php'> | <source lang='php'> | ||
Line 248: | Line 286: | ||
</source> | </source> | ||
− | + | donnera: | |
<pre>Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith )</pre> | <pre>Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith )</pre> | ||
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['name'] // e.g. $row['email']</pre> | |
− | + | # Bien que vous pouvez répéter l'appel pour obtenir d'autres lignes, une des fonctions retournant plusieurs lignes peut être plus utile. | |
− | # | ||
==== loadObject() ==== | ==== loadObject() ==== | ||
− | loadObject | + | loadObject retourne un objet PHP d'un seul enregistrement dans la table: |
<source lang='php'> | <source lang='php'> | ||
Line 266: | Line 303: | ||
</source> | </source> | ||
− | + | donnera: | |
<pre>stdClass Object ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith )</pre> | <pre>stdClass Object ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith )</pre> | ||
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$result->index // e.g. $result->email</pre> | |
− | + | # Bien que vous pouvez répéter l'appel pour obtenir d'autres lignes, une des fonctions retournant plusieurs lignes peut être plus utile. | |
− | # | ||
− | === | + | === Résultats à une simple colonne === |
− | + | Chacune de ces fonctions de résultats va retourner une seule colonne de la base de données. | |
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
Line 281: | Line 317: | ||
! id !! nom !! email !! nom d'utilisateur | ! id !! nom !! email !! nom d'utilisateur | ||
|- | |- | ||
− | | 1 || style="background:yellow" | John Smith || | + | | 1 || style="background:yellow" | John Smith || johnsmith@domaine.exemple || johnsmith |
|- | |- | ||
− | | 2 || style="background:yellow" | Magda Hellman || magda_h@ | + | | 2 || style="background:yellow" | Magda Hellman || magda_h@domaine.exemple || magdah |
|- | |- | ||
− | | 3 || style="background:yellow" | Yvonne de Gaulle || ydg@ | + | | 3 || style="background:yellow" | Yvonne de Gaulle || ydg@domaine.exemple || ydegaulle |
|} | |} | ||
==== loadColumn() ==== | ==== loadColumn() ==== | ||
− | <tt>loadColumn()</tt> | + | <tt>loadColumn()</tt> retourne un tableau indexé d'un seul enregistrement dans la table: |
<source lang='php'> | <source lang='php'> | ||
Line 300: | Line 336: | ||
</source> | </source> | ||
− | + | donnera : | |
<pre>Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle )</pre> | <pre>Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle )</pre> | ||
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$column['index'] // e.g. $column['2']</pre> | |
− | + | A savoir: | |
− | # | + | # Les indices du tableau sont des nombres débutant à zéro. |
− | # <tt>loadColumn()</tt> | + | # <tt>loadColumn()</tt> est équivalent à <tt>loadColumn(0)</tt>. |
==== loadColumn($index) ==== | ==== loadColumn($index) ==== | ||
− | loadColumn($index) | + | <tt>loadColumn($index)</tt> retourne un tableau indexé d'une seule colonne dans la table: |
<source lang='php'> | <source lang='php'> | ||
Line 321: | Line 357: | ||
</source> | </source> | ||
− | + | donnera: | |
<pre>Array ( [0] => johnsmith@domain.example, [1] => magda_h@domain.example, [2] => ydg@domain.example )</pre> | <pre>Array ( [0] => johnsmith@domain.example, [1] => magda_h@domain.example, [2] => ydg@domain.example )</pre> | ||
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$column['index'] // e.g. $column['2']</pre> | |
− | loadColumn($index) | + | <tt>loadColumn($index)</tt> vous permet d'itérer à travers une série de colonnes dans les résultats |
<source lang='php'> | <source lang='php'> | ||
Line 337: | Line 373: | ||
</source> | </source> | ||
− | + | donnera : | |
<pre>Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle ), | <pre>Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle ), | ||
Array ( [0] => johnsmith@domain.example, [1] => magda_h@domain.example, [2] => ydg@domain.example ), | Array ( [0] => johnsmith@domain.example, [1] => magda_h@domain.example, [2] => ydg@domain.example ), | ||
Line 343: | Line 379: | ||
</pre> | </pre> | ||
− | + | A savoir: | |
− | # | + | # Les indices du tableau sont des nombres débutant à zéro. |
− | === Multi- | + | === Résultats Multi-Ligne === |
− | + | Chacune de ces fonctions de résultats va retourner plusieurs enregistrements de la base de données. | |
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
Line 361: | Line 397: | ||
==== loadRowList() ==== | ==== loadRowList() ==== | ||
− | <tt>loadRowList()</tt> | + | <tt>loadRowList()</tt> retourne un tableau indexé de tableaux indexés à partir des enregistrements de la table retourné par la requête: |
<source lang='php'> | <source lang='php'> | ||
Line 370: | Line 406: | ||
</source> | </source> | ||
− | + | donnera (avec les retours à la ligne pour la lisibilité): | |
<pre>Array ( | <pre>Array ( | ||
Line 378: | Line 414: | ||
)</pre> | )</pre> | ||
− | + | Vous pouvez accéder individuellement aux lignes en faisant:<pre>$row['index'] // e.g. $row['2']</pre> | |
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['index']['index'] // e.g. $row['2']['3']</pre> | |
− | + | A savoir: | |
− | # | + | # Les indices du tableau sont des nombres débutant à zéro. |
==== loadAssocList() ==== | ==== loadAssocList() ==== | ||
− | <tt>loadAssocList()</tt> | + | <tt>loadAssocList()</tt> retourne un tableau indexé de tableaux associatifs à partir des enregistrements de la table retournés par la requête: |
<source lang='php'> | <source lang='php'> | ||
Line 394: | Line 430: | ||
</source> | </source> | ||
− | + | donnera (avec les retours à la ligne pour la lisibilité): | |
<pre>Array ( | <pre>Array ( | ||
[0] => Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), | [0] => Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), | ||
Line 401: | Line 437: | ||
) </pre> | ) </pre> | ||
− | + | Vous pouvez accéder individuellement aux lignes en faisant:<pre>$row['index'] // e.g. $row['2']</pre> | |
− | + | Vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['index']['column_name'] // e.g. $row['2']['email']</pre> | |
==== loadAssocList($key) ==== | ==== loadAssocList($key) ==== | ||
− | <tt>loadAssocList(' | + | <tt>loadAssocList('clé')</tt> retourne un tableau associatif - indexé sur 'clé' - des tableaux associatifs à partir des enregistrements de la table retournés par la requête: |
<source lang='php'> | <source lang='php'> | ||
Line 414: | Line 450: | ||
</source> | </source> | ||
− | + | donnera (avec les retours à la ligne pour la lisibilité): | |
<pre>Array ( | <pre>Array ( | ||
[johnsmith] => Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), | [johnsmith] => Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), | ||
Line 421: | Line 457: | ||
)</pre> | )</pre> | ||
− | + | Vous pouvez accéder individuellement aux lignes en faisant:<pre>$row['key_value'] // e.g. $row['johnsmith']</pre> | |
− | + | et vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['key_value']['column_name'] // e.g. $row['johnsmith']['email']</pre> | |
− | + | A savoir: clé doit être un nom de colonne valide de la table; il ne doit pas être un index ou une clé primaire. Mais s'il n'a pas de valeur unique vous ne pourrez pas extraire les résultats fidèlement. | |
==== loadAssocList($key, $column) ==== | ==== loadAssocList($key, $column) ==== | ||
− | <tt>loadAssocList('key', 'column')</tt> | + | <tt>loadAssocList('key', 'column')</tt> retourne un tableau associatif, indexé sur 'key', de valeurs de la colonne nommée 'column' retournés par la requête: |
<source lang='php'> | <source lang='php'> | ||
Line 436: | Line 472: | ||
</source> | </source> | ||
− | + | donnera (avec les retours à la ligne pour la lisibilité): | |
<pre>Array ( | <pre>Array ( | ||
[1] => John Smith, | [1] => John Smith, | ||
Line 443: | Line 479: | ||
)</pre> | )</pre> | ||
− | + | A savoir: Key doit être un nom de colonne valide de la table; il ne doit pas être un index ou une clé primaire. Mais s'il n'a pas de valeur unique vous ne pourrez pas extraire les résultats fidèlement. | |
==== loadObjectList() ==== | ==== loadObjectList() ==== | ||
− | <tt>loadObjectList()</tt> | + | <tt>loadObjectList()</tt> retourne un tableau indexé d'objets PHP à partir des enregistrements de la table retournés par la requête: |
<source lang='php'> | <source lang='php'> | ||
Line 455: | Line 491: | ||
</source> | </source> | ||
− | + | donnera (avec les retours à la ligne pour la lisibilité): | |
<pre>Array ( | <pre>Array ( | ||
[0] => stdClass Object ( [id] => 1, [name] => John Smith, | [0] => stdClass Object ( [id] => 1, [name] => John Smith, | ||
Line 465: | Line 501: | ||
)</pre> | )</pre> | ||
− | + | Vous pouvez accéder individuellement aux lignes en faisant:<pre>$row['index'] // e.g. $row['2']</pre> | |
− | + | et vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['index']->name // e.g. $row['2']->email</pre> | |
==== loadObjectList($key) ==== | ==== loadObjectList($key) ==== | ||
− | <tt>loadObjectList('key')</tt> | + | <tt>loadObjectList('key')</tt> retourne un tableau associatif - indexé sur 'key' - d'objets à partir des enregistrements de la table retournés par la requête: |
<source lang='php'> | <source lang='php'> | ||
Line 478: | Line 514: | ||
</source> | </source> | ||
− | + | donnera (avec les retours à la ligne pour la lisibilité): | |
<pre>Array ( | <pre>Array ( | ||
[johnsmith] => stdClass Object ( [id] => 1, [name] => John Smith, | [johnsmith] => stdClass Object ( [id] => 1, [name] => John Smith, | ||
Line 488: | Line 524: | ||
)</pre> | )</pre> | ||
− | + | Vous pouvez accéder individuellement aux lignes en faisant:<pre>$row['key_value'] // e.g. $row['johnsmith']</pre> | |
− | + | et vous pouvez accéder individuellement aux valeurs en faisant:<pre>$row['key_value']->column_name // e.g. $row['johnsmith']->email</pre> | |
− | + | A savoir: Key doit être un nom de colonne valide de la table; il ne doit pas être un index ou une clé primaire. Mais s'il n'a pas de valeur unique vous ne pourrez pas extraire les résultats fidèlement. | |
− | === | + | === Méthodes de jeu de résultat divers === |
==== getNumRows() ==== | ==== getNumRows() ==== | ||
− | <tt>getNumRows()</tt> | + | <tt>getNumRows()</tt> retournera le nombre de lignes résultantes trouvées par la dernière requête SELECT ou SHOW et en attente d'être lue. Pour obtenir un résultat à partir de getNumRows(), vous devez l'exécuter après la requête et avant d'extraire tout résultat. Pour extraire le nombre de lignes affectées par une requête INSERT, UPDATE, REPLACE ou DELETE, utilisez getAffectedRows(). |
<source lang='php'> | <source lang='php'> | ||
Line 506: | Line 542: | ||
</source> | </source> | ||
− | + | retournera : <pre>3</pre> | |
− | + | A savoir: getNumRows() est seulement valide pour des déclarations comme SELECT ou SHOW qui retourne un véritable jeu de résultats. Si vous exécutez getNumRows() après loadRowList() - ou n'importe quelle méthode d'extraction - vous obtiendrez un avertissement PHP. | |
<pre>Warning: mysql_num_rows(): 80 is not a valid MySQL result resource | <pre>Warning: mysql_num_rows(): 80 is not a valid MySQL result resource | ||
in libraries\joomla\database\database\mysql.php on line 344</pre> | in libraries\joomla\database\database\mysql.php on line 344</pre> | ||
+ | |||
+ | == Sample Module Code == | ||
+ | |||
+ | Below is the code for a simple Joomla module which you can install and run to demonstrate use of the JDatabase functionality, and which you can adapt to experiment with some of the concepts described above. If you are unsure about development and installing a Joomla module then following the tutorial at [[S:MyLanguage/J3.x:Creating a simple module/Introduction| Creating a simple module ]] will help. | ||
+ | |||
+ | '''Important note: In any Joomla extensions which you develop that you should avoid accessing the core Joomla tables directly like this and should instead use the Joomla APIs if at all possible, because the database structures may change without warning.''' | ||
+ | |||
+ | In a folder mod_db_select create the following 2 files: | ||
+ | |||
+ | <tt>mod_db_select.xml</tt> | ||
+ | <source lang="xml"> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <extension type="module" version="3.1" client="site" method="upgrade"> | ||
+ | <name>Database select query demo</name> | ||
+ | <version>1.0.1</version> | ||
+ | <description>Code demonstrating use of Joomla Database class to perform SQL SELECT queries</description> | ||
+ | <files> | ||
+ | <filename module="mod_db_select">mod_db_select.php</filename> | ||
+ | </files> | ||
+ | </extension> | ||
+ | </source> | ||
+ | |||
+ | <tt>mod_db_select.php</tt> | ||
+ | <source lang="php"> | ||
+ | <?php | ||
+ | defined('_JEXEC') or die('Restricted Access'); | ||
+ | |||
+ | use Joomla\CMS\Factory; | ||
+ | |||
+ | $db = Factory::getDbo(); | ||
+ | |||
+ | $me = Factory::getUser(); | ||
+ | |||
+ | $query = $db->getQuery(true); | ||
+ | |||
+ | $query->select($db->quoteName(array('name', 'email'))) | ||
+ | ->from($db->quoteName('#__users')) | ||
+ | ->where($db->quoteName('id') . ' != ' . $db->quote($me->id)) | ||
+ | ->order($db->quoteName('name') . ' ASC'); | ||
+ | |||
+ | $db->setQuery($query); | ||
+ | |||
+ | echo $db->replacePrefix((string) $query); | ||
+ | |||
+ | $results = $db->loadAssocList(); | ||
+ | |||
+ | foreach ($results as $row) { | ||
+ | echo "<p>" . $row['name'] . ", " . $row['email'] . "<br></p>"; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | The code above selects and outputs the username and email of the records in the Joomla <tt>users</tt> table, apart from those of the currently logged-on user. The method <tt>Factory::getUser()</tt> returns the <tt>user</tt> object of the currently logged-on user, or if not logged on, then a blank <tt>user</tt> object, whose <tt>id</tt> field is set to zero. | ||
+ | |||
+ | The <tt>$db->replacePrefix((string) $query)</tt> expression returns the actual SQL statement, and outputting this can be useful in debugging. | ||
+ | |||
+ | Zip up the mod_db_select directory to create <tt>mod_db_select.zip</tt>. | ||
+ | |||
+ | Within your Joomla administrator go to Install Extensions and via the Upload Package File tab select this zip file to install this sample log module. | ||
+ | |||
+ | Make this module visible by editing it (click on it within the Modules page) then: | ||
+ | # making its status Published | ||
+ | # selecting a position on the page for it to be shown | ||
+ | # on the menu assignment tab specify the pages it should appear on | ||
+ | |||
+ | When you visit a site web page then you should see the module in your selected position, and it should output the SQL SELECT statement and the sequence of name, email values from the Joomla users table. | ||
+ | |||
+ | == Voir aussi == | ||
+ | *[[S:MyLanguage/Inserting, Updating and Removing data using JDatabase|Insertion, mise à Jour et suppression de données à l'aide de JDatabase]] | ||
+ | *[[S:MyLanguage/Using the union methods in database queries|Utiliser les méthodes d'union dans les requêtes de base de données]] (Joomla! 3.3+) | ||
+ | *[https://api.joomla.org/cms-3/classes/JDatabaseQuery.html Joomla CMS 3.8 API] | ||
<noinclude> | <noinclude> | ||
− | [[Category:Database]] | + | [[Category:Database{{#translation:}}]] |
− | [[Category:JFactory]] | + | [[Category:JFactory{{#translation:}}]] |
− | [[Category:Extension development]] | + | [[Category:Extension development{{#translation:}}]] |
− | [[Category:Development Recommended Reading]] | + | [[Category:Development Recommended Reading{{#translation:}}]] |
− | [[Category:Tutorials]] | + | [[Category:Tutorials{{#translation:}}]] |
</noinclude> | </noinclude> |
Latest revision as of 18:05, 25 February 2021
Remarquez que de nombreux exemples cités utilisent $db->query()
au lieu de $db->execute()
. C'était une méthode ancienne dans Joomla! 1.5 et 2.5 qui va émettre un message d'obsolescence à partir de Joomla 3.0+.
Ce didacticiel est divisé en deux parties indépendantes :
- L'insertion, la mise à jour et la suppression de données de la base de données.
- La sélection de données à partir d'une ou plusieurs tables et la récupération sous différentes formes.
Cette section de la documentation se focalise sur la sélection de données à partir d'une table de la base de données et la récupère dans différents formats. Pour voir l'autre partie cliquez ici
Introduction
Joomla! fournit une couche d'abstraction sophistiquée de base de données pour en simplifier l'utilisation pour les développeurs tierces. Les nouvelles versions de l'API de la Plateforme Joomla! fournissent des fonctionnalités supplémentaires qui permettent d'étendre encore plus la couche de base de données et d'inclure des fonctionnalités telles que des connecteurs pour une plus grande variété de serveurs de base de données ou encore le chaînage de requêtes pour améliorer la lisibilité du code de connexion et simplifier le codage SQL.
Joomla peut utiliser différentes sortes de systèmes de base de données SQL et s'exécuter dans des environnements variés avec différents préfixes de table. En plus de ces fonctions, la classe (JDatabase) crée automatiquement la connexion à la base de données. Il suffit de deux lignes de code lors de l'instanciation de l'objet pour obtenir un résultat à partir de la base de données dans différents formats. L'utilisation de la couche de base de données Joomla assure un maximum de compatibilité et de flexibilité pour vos extensions.
La Requête
Faire une requête dans la base de données Joomla a changé avec l'introduction de Joomla 1.6. Le moyen recommandé pour construire des requêtes de base de données se fait via le "chaînage de requêtes" (même si les requêtes en chaînes de caractères sont encore supportées).
Le chaînage de requête fait référence à une méthode se connectant à un nombre de méthodes, les unes après les autres, où chaque méthode retourne un objet supportant la prochaine méthode, améliorant ainsi la lisibilité et la simplification du code.
Pour obtenir une nouvelle instance de la classe JDatabaseQuery, nous utilisons la méthode getQuery de la classe JDatabaseDriver:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
JDatabaseDriver::getQuery prend un argument optionnel, $new, qui peut être true (vrai) ou false (faux) (la valeur par défaut est false).
Pour interroger notre source de données, nous pouvons appeler un nombre de méthodes de la classe JDatabaseQuery; ces méthodes encapsulent le langage de requête de la source de données (dans la plupart des cas SQL), en occultant la syntaxe de requête spécifique au développeur et en augmentant la portabilité du code source du développeur.
Les méthodes les plus fréquemment utilisées incluent; select, from, join, where et order. Il y a aussi des méthodes comme insert, update et delete pour modifier des enregistrements dans la base de données. En chaînant ces appels de méthodes à d'autres, vous pouvez créer presque n'importe quelle requête à votre base de données sans compromettre la portabilité de votre code..
Sélectionner des enregistrements d'une seule table
Ci-dessous se trouve un exemple de création de requête de base de données utilisant la classe JDatabaseQuery. En utilisant les méthodes select, from, where et order, nous pouvons créer des requêtes flexibles, facilement lisibles et portable:
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all records from the user profile table where key begins with "custom.".
// Order it by the ordering field.
$query->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering')));
$query->from($db->quoteName('#__user_profiles'));
$query->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('custom.%'));
$query->order('ordering ASC');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadObjectList();
(Here the quoteName() function adds appropriate quotes around the column names to avoid conflicts with any database reserved word, now or in the future.)
La requête peut également être chaînée pour la simplifier davantage :
$query
->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering')))
->from($db->quoteName('#__user_profiles'))
->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('custom.%'))
->order('ordering ASC');
Les appels de méthode de chaînage améliorent la lisibilité du code et réduisent le gonflement du code à mesure que les requêtes deviennent plus longues et plus complexes.
Le groupement peut également être réalisé simplement. La requête suivante compterait le nombre d'articles dans chaque catégorie.
$query
->select(array('catid', 'COUNT(*)'))
->from($db->quoteName('#__content'))
->group($db->quoteName('catid'));
Une limite peut être définie pour une requête en utilisant setLimit. Par exemple, dans la requête suivante, jusqu'à 10 enregistrements seront retournés.
$query
->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering')))
->from($db->quoteName('#__user_profiles'))
->setLimit('10');
Sélectionner des enregistrements de plusieurs tables
En utilisant les méthodes de jointure de JDatabaseQuery, on peut sélectionner des enregistrements de multiples tables reliées. La méthode générique "join" prend deux arguments; le "type" de jointure (inner, outer, left, right) et la condition de jointure. Dans l'exemple suivant vous remarquerez que l'on peut utiliser tous les mots-clés qu'on utiliserait normalement si on écrivait une requête SQL native, incluant le mot-clé AS pour donner un surnom aux tables et le mot-clé ON pour créer des relations entre les tables. Remarquez aussi que le surnom de la table est utilisé dans toutes les méthodes qui font référence aux colonnes de la table (c-a-d select, where, order).
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all articles for users who have a username which starts with 'a'.
// Order it by the created date.
// Note by putting 'a' as a second parameter will generate `#__content` AS `a`
$query
->select(array('a.*', 'b.username', 'b.name'))
->from($db->quoteName('#__content', 'a'))
->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
->order($db->quoteName('a.created') . ' DESC');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadObjectList();
La méthode de jointure ci-dessus nous permet d'interroger les deux tables "content" et "users", en récupérant les articles avec leur auteur. Il y a aussi des méthodes pratiques pour les jointures:
Nous pouvons utiliser plusieurs jointures pour interroger plus de deux tables :
$query
->select(array('a.*', 'b.username', 'b.name', 'c.*', 'd.*'))
->from($db->quoteName('#__content', 'a'))
->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
->join('LEFT', $db->quoteName('#__user_profiles', 'c') . ' ON ' . $db->quoteName('b.id') . ' = ' . $db->quoteName('c.user_id'))
->join('RIGHT', $db->quoteName('#__categories', 'd') . ' ON ' . $db->quoteName('a.catid') . ' = ' . $db->quoteName('d.id'))
->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
->order($db->quoteName('a.created') . ' DESC');
Remarquez comment le chaînage rend le code source plus lisible pour ces longues requêtes.
Dans certains cas, vous aurez aussi besoin d'utiliser la clause AS lors de la sélection d'éléments pour éviter des conflits de nom de colonne. Dans ce cas, plusieurs déclarations "select" peuvent être chaînées en conjonction de l'utilisation de $db->quoteName dans le second paramètre.
$query
->select('a.*')
->select($db->quoteName('b.username', 'username'))
->select($db->quoteName('b.name', 'name'))
->from($db->quoteName('#__content', 'a'))
->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
->order($db->quoteName('a.created') . ' DESC');
Un second tableau peut aussi être utilisé comme deuxième paramètre de la déclaration de "select" pour alimenter les valeurs de la clause AS. Souvenez-vous d'inclure des "nulls" dans le second tableau aux colonnes correspondantes du premier tableau pour lesquelles vous ne voulez pas utiliser la clause AS:
$query
->select(array('a.*'))
->select($db->quoteName(array('b.username', 'b.name'), array('username', 'name')))
->from($db->quoteName('#__content', 'a'))
->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
->order($db->quoteName('a.created') . ' DESC');
Using OR in queries
When using multiple WHERE clauses in your query, they will be treated as an AND.
So, for example, the query below will return results where the 'name' field AND the 'state' field match.
$query = $db
->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__my_table'))
->where($db->quoteName('name') . " = " . $db->quote($value)
->where($db->quoteName('state') . " = " . $db->quote($state));
To use a WHERE clause as an OR, the query can be written like this
$query = $db
->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__my_table'))
->where($db->quoteName('name') . " = " . $db->quote($name_one), 'OR')
->where($db->quoteName('name') . " = " . $db->quote($name_two));
it can also be written like this
$query = $db
->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__my_table'))
->where($db->quoteName('name') . " = " . $db->quote($name_one)
->orWhere($db->quoteName('name') . " = " . $db->quote($name_two));
Résultats de requête
La classe JDatabase possède plusieurs méthodes pour travailler avec un jeu de résultat d'une requête.
If there are no matches to the query, the result will be null.
Résultat à valeur simple
loadResult()
Utilisez loadResult() quand vous souhaitez juste une seule valeur de retour de votre requête de base de données.
id | nom | nom d'utilisateur | |
---|---|---|---|
1 | John Smith | johnsmith@domaine.exemple | johnsmith |
2 | Magda Hellman | magda_h@domaine.exemple | magdah |
3 | Yvonne de Gaulle | ydg@domaine.exemple | ydegaulle |
C'est souvent le résultat d'une requête de "comptage" pour obtenir un nombre d'enregistrements:
$db = JFactory::getDbo();
$query = $db
->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__my_table'))
->where($db->quoteName('name') . " = " . $db->quote($value));
// Reset the query using our newly populated query object.
$db->setQuery($query);
$count = $db->loadResult();
ou quand vous souhaitez juste un seul champ d'une seule ligne de la table (ou un seul champ à partir de la première ligne retournée).
$db = JFactory::getDbo();
$query = $db
->getQuery(true)
->select('field_name')
->from($db->quoteName('#__my_table'))
->where($db->quoteName('some_name') . " = " . $db->quote($some_value));
$db->setQuery($query);
$result = $db->loadResult();
Résultats à une simple ligne
Chacune de ces fonctions de résultats va retourner un seul enregistrement de la base de données même s'il peut y avoir plusieurs enregistrements correspondant au critère donné. Pour obtenir plus d'enregistrements vous devez encore appeler la fonction.
id | nom | nom d'utilisateur | |
---|---|---|---|
1 | John Smith | johnsmith@domaine.exemple | johnsmith |
2 | Magda Hellman | magda_h@domaine.exemple | magdah |
3 | Yvonne de Gaulle | ydg@domaine.exemple | ydegaulle |
loadRow()
loadRow() retourne un tableau indexé d'un seul enregistrement dans la table:
. . .
$db->setQuery($query);
$row = $db->loadRow();
print_r($row);
donnera :
Array ( [0] => 1, [1] => John Smith, [2] => johnsmith@domain.example, [3] => johnsmith )
Vous pouvez accéder individuellement aux valeurs en faisant:
$row['index'] // e.g. $row['2']
Remarques :
- Les indices du tableau sont des nombres débutant à zéro.
- Bien que vous pouvez répéter l'appel pour obtenir d'autres lignes, une des fonctions retournant plusieurs lignes peut être plus utile.
loadAssoc()
loadAssoc() retourne un tableau associatif d'un seul enregistrement dans la table:
. . .
$db->setQuery($query);
$row = $db->loadAssoc();
print_r($row);
donnera:
Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith )
Vous pouvez accéder individuellement aux valeurs en faisant:
$row['name'] // e.g. $row['email']
- Bien que vous pouvez répéter l'appel pour obtenir d'autres lignes, une des fonctions retournant plusieurs lignes peut être plus utile.
loadObject()
loadObject retourne un objet PHP d'un seul enregistrement dans la table:
. . .
$db->setQuery($query);
$result = $db->loadObject();
print_r($result);
donnera:
stdClass Object ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith )
Vous pouvez accéder individuellement aux valeurs en faisant:
$result->index // e.g. $result->email
- Bien que vous pouvez répéter l'appel pour obtenir d'autres lignes, une des fonctions retournant plusieurs lignes peut être plus utile.
Résultats à une simple colonne
Chacune de ces fonctions de résultats va retourner une seule colonne de la base de données.
id | nom | nom d'utilisateur | |
---|---|---|---|
1 | John Smith | johnsmith@domaine.exemple | johnsmith |
2 | Magda Hellman | magda_h@domaine.exemple | magdah |
3 | Yvonne de Gaulle | ydg@domaine.exemple | ydegaulle |
loadColumn()
loadColumn() retourne un tableau indexé d'un seul enregistrement dans la table:
$query->select('name'));
->from . . .";
. . .
$db->setQuery($query);
$column= $db->loadColumn();
print_r($column);
donnera :
Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle )
Vous pouvez accéder individuellement aux valeurs en faisant:
$column['index'] // e.g. $column['2']
A savoir:
- Les indices du tableau sont des nombres débutant à zéro.
- loadColumn() est équivalent à loadColumn(0).
loadColumn($index)
loadColumn($index) retourne un tableau indexé d'une seule colonne dans la table:
$query->select(array('name', 'email', 'username'));
->from . . .";
. . .
$db->setQuery($query);
$column= $db->loadColumn(1);
print_r($column);
donnera:
Array ( [0] => johnsmith@domain.example, [1] => magda_h@domain.example, [2] => ydg@domain.example )
Vous pouvez accéder individuellement aux valeurs en faisant:
$column['index'] // e.g. $column['2']
loadColumn($index) vous permet d'itérer à travers une série de colonnes dans les résultats
. . .
$db->setQuery($query);
for ( $i = 0; $i <= 2; $i++ ) {
$column= $db->loadColumn($i);
print_r($column);
}
donnera :
Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle ), Array ( [0] => johnsmith@domain.example, [1] => magda_h@domain.example, [2] => ydg@domain.example ), Array ( [0] => johnsmith, [1] => magdah, [2] => ydegaulle )
A savoir:
- Les indices du tableau sont des nombres débutant à zéro.
Résultats Multi-Ligne
Chacune de ces fonctions de résultats va retourner plusieurs enregistrements de la base de données.
id | name | nom d'utilisateur | |
---|---|---|---|
1 | John Smith | johnsmith@domain.example | johnsmith |
2 | Magda Hellman | magda_h@domain.example | magdah |
3 | Yvonne de Gaulle | ydg@domain.example | ydegaulle |
loadRowList()
loadRowList() retourne un tableau indexé de tableaux indexés à partir des enregistrements de la table retourné par la requête:
. . .
$db->setQuery($query);
$row = $db->loadRowList();
print_r($row);
donnera (avec les retours à la ligne pour la lisibilité):
Array ( [0] => Array ( [0] => 1, [1] => John Smith, [2] => johnsmith@domain.example, [3] => johnsmith ), [1] => Array ( [0] => 2, [1] => Magda Hellman, [2] => magda_h@domain.example, [3] => magdah ), [2] => Array ( [0] => 3, [1] => Yvonne de Gaulle, [2] => ydg@domain.example, [3] => ydegaulle ) )
Vous pouvez accéder individuellement aux lignes en faisant:
$row['index'] // e.g. $row['2']
Vous pouvez accéder individuellement aux valeurs en faisant:
$row['index']['index'] // e.g. $row['2']['3']
A savoir:
- Les indices du tableau sont des nombres débutant à zéro.
loadAssocList()
loadAssocList() retourne un tableau indexé de tableaux associatifs à partir des enregistrements de la table retournés par la requête:
. . .
$db->setQuery($query);
$row = $db->loadAssocList();
print_r($row);
donnera (avec les retours à la ligne pour la lisibilité):
Array ( [0] => Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), [1] => Array ( [id] => 2, [name] => Magda Hellman, [email] => magda_h@domain.example, [username] => magdah ), [2] => Array ( [id] => 3, [name] => Yvonne de Gaulle, [email] => ydg@domain.example, [username] => ydegaulle ) )
Vous pouvez accéder individuellement aux lignes en faisant:
$row['index'] // e.g. $row['2']
Vous pouvez accéder individuellement aux valeurs en faisant:
$row['index']['column_name'] // e.g. $row['2']['email']
loadAssocList($key)
loadAssocList('clé') retourne un tableau associatif - indexé sur 'clé' - des tableaux associatifs à partir des enregistrements de la table retournés par la requête:
. . .
$db->setQuery($query);
$row = $db->loadAssocList('username');
print_r($row);
donnera (avec les retours à la ligne pour la lisibilité):
Array ( [johnsmith] => Array ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), [magdah] => Array ( [id] => 2, [name] => Magda Hellman, [email] => magda_h@domain.example, [username] => magdah ), [ydegaulle] => Array ( [id] => 3, [name] => Yvonne de Gaulle, [email] => ydg@domain.example, [username] => ydegaulle ) )
Vous pouvez accéder individuellement aux lignes en faisant:
$row['key_value'] // e.g. $row['johnsmith']
et vous pouvez accéder individuellement aux valeurs en faisant:
$row['key_value']['column_name'] // e.g. $row['johnsmith']['email']
A savoir: clé doit être un nom de colonne valide de la table; il ne doit pas être un index ou une clé primaire. Mais s'il n'a pas de valeur unique vous ne pourrez pas extraire les résultats fidèlement.
loadAssocList($key, $column)
loadAssocList('key', 'column') retourne un tableau associatif, indexé sur 'key', de valeurs de la colonne nommée 'column' retournés par la requête:
. . .
$db->setQuery($query);
$row = $db->loadAssocList('id', 'username');
print_r($row);
donnera (avec les retours à la ligne pour la lisibilité):
Array ( [1] => John Smith, [2] => Magda Hellman, [3] => Yvonne de Gaulle, )
A savoir: Key doit être un nom de colonne valide de la table; il ne doit pas être un index ou une clé primaire. Mais s'il n'a pas de valeur unique vous ne pourrez pas extraire les résultats fidèlement.
loadObjectList()
loadObjectList() retourne un tableau indexé d'objets PHP à partir des enregistrements de la table retournés par la requête:
. . .
$db->setQuery($query);
$row = $db->loadObjectList();
print_r($row);
donnera (avec les retours à la ligne pour la lisibilité):
Array ( [0] => stdClass Object ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), [1] => stdClass Object ( [id] => 2, [name] => Magda Hellman, [email] => magda_h@domain.example, [username] => magdah ), [2] => stdClass Object ( [id] => 3, [name] => Yvonne de Gaulle, [email] => ydg@domain.example, [username] => ydegaulle ) )
Vous pouvez accéder individuellement aux lignes en faisant:
$row['index'] // e.g. $row['2']
et vous pouvez accéder individuellement aux valeurs en faisant:
$row['index']->name // e.g. $row['2']->email
loadObjectList($key)
loadObjectList('key') retourne un tableau associatif - indexé sur 'key' - d'objets à partir des enregistrements de la table retournés par la requête:
. . .
$db->setQuery($query);
$row = $db->loadObjectList('username');
print_r($row);
donnera (avec les retours à la ligne pour la lisibilité):
Array ( [johnsmith] => stdClass Object ( [id] => 1, [name] => John Smith, [email] => johnsmith@domain.example, [username] => johnsmith ), [magdah] => stdClass Object ( [id] => 2, [name] => Magda Hellman, [email] => magda_h@domain.example, [username] => magdah ), [ydegaulle] => stdClass Object ( [id] => 3, [name] => Yvonne de Gaulle, [email] => ydg@domain.example, [username] => ydegaulle ) )
Vous pouvez accéder individuellement aux lignes en faisant:
$row['key_value'] // e.g. $row['johnsmith']
et vous pouvez accéder individuellement aux valeurs en faisant:
$row['key_value']->column_name // e.g. $row['johnsmith']->email
A savoir: Key doit être un nom de colonne valide de la table; il ne doit pas être un index ou une clé primaire. Mais s'il n'a pas de valeur unique vous ne pourrez pas extraire les résultats fidèlement.
Méthodes de jeu de résultat divers
getNumRows()
getNumRows() retournera le nombre de lignes résultantes trouvées par la dernière requête SELECT ou SHOW et en attente d'être lue. Pour obtenir un résultat à partir de getNumRows(), vous devez l'exécuter après la requête et avant d'extraire tout résultat. Pour extraire le nombre de lignes affectées par une requête INSERT, UPDATE, REPLACE ou DELETE, utilisez getAffectedRows().
. . .
$db->setQuery($query);
$db->execute();
$num_rows = $db->getNumRows();
print_r($num_rows);
$result = $db->loadRowList();
retournera :
3
A savoir: getNumRows() est seulement valide pour des déclarations comme SELECT ou SHOW qui retourne un véritable jeu de résultats. Si vous exécutez getNumRows() après loadRowList() - ou n'importe quelle méthode d'extraction - vous obtiendrez un avertissement PHP.
Warning: mysql_num_rows(): 80 is not a valid MySQL result resource in libraries\joomla\database\database\mysql.php on line 344
Sample Module Code
Below is the code for a simple Joomla module which you can install and run to demonstrate use of the JDatabase functionality, and which you can adapt to experiment with some of the concepts described above. If you are unsure about development and installing a Joomla module then following the tutorial at Creating a simple module will help.
Important note: In any Joomla extensions which you develop that you should avoid accessing the core Joomla tables directly like this and should instead use the Joomla APIs if at all possible, because the database structures may change without warning.
In a folder mod_db_select create the following 2 files:
mod_db_select.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
<name>Database select query demo</name>
<version>1.0.1</version>
<description>Code demonstrating use of Joomla Database class to perform SQL SELECT queries</description>
<files>
<filename module="mod_db_select">mod_db_select.php</filename>
</files>
</extension>
mod_db_select.php
<?php
defined('_JEXEC') or die('Restricted Access');
use Joomla\CMS\Factory;
$db = Factory::getDbo();
$me = Factory::getUser();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('name', 'email')))
->from($db->quoteName('#__users'))
->where($db->quoteName('id') . ' != ' . $db->quote($me->id))
->order($db->quoteName('name') . ' ASC');
$db->setQuery($query);
echo $db->replacePrefix((string) $query);
$results = $db->loadAssocList();
foreach ($results as $row) {
echo "<p>" . $row['name'] . ", " . $row['email'] . "<br></p>";
}
The code above selects and outputs the username and email of the records in the Joomla users table, apart from those of the currently logged-on user. The method Factory::getUser() returns the user object of the currently logged-on user, or if not logged on, then a blank user object, whose id field is set to zero.
The $db->replacePrefix((string) $query) expression returns the actual SQL statement, and outputting this can be useful in debugging.
Zip up the mod_db_select directory to create mod_db_select.zip.
Within your Joomla administrator go to Install Extensions and via the Upload Package File tab select this zip file to install this sample log module.
Make this module visible by editing it (click on it within the Modules page) then:
- making its status Published
- selecting a position on the page for it to be shown
- on the menu assignment tab specify the pages it should appear on
When you visit a site web page then you should see the module in your selected position, and it should output the SQL SELECT statement and the sequence of name, email values from the Joomla users table.