Documentation v1.0.0
WDB
Documentation  v 1.0.0

A Généralités

Avertissements:

Cette documentation est susceptible de contenir des erreurs orthographiques, grammaticales, didactiques ou fonctionnelles. Nous nous en excusons donc d'avance et prions si possible, de notifier les erreurs significatives sur la page de WDB à github

A. 1 - À propos de WDB

WDB est un ORM pour PHP (object-relational mapping). Cela veut dire qu'il permet de manipuler une base de données selon une approche orientée objet, simplifiant largement la tâche du programmeur, tout en apportant un gain de temps non négligeable dans le codage et la maintenance ultérieure. Le codage d'un SQL pur et dur ne peut être comparé à l'élégance d'utilisation d'un ORM. WDB rend votre code plus lisible, et donc facilement maintenable. Avec sa simplicité même une personne ne connaissant pas grand-chose au SQL pourrait s'en sortir sans grand problème. Mais ce n'est pas tout.

Comme les systèmes de gestion des bases de données (SGBDs) ne parlent pas toujours le même langage en toutes circonstances, WDB comme beaucoup d'autres ORMs, permet de manipuler plusieurs types de bases de données sans vous préoccuper des spécificités propres à chacun, ni des questions liées aux problèmes d'injection SQL. Pour cela WDB utilise PDO la célèbre classe PHP permettant la manipulation des bases de données.

WDB est publié sous licence MIT, ce qui vous permet en tant que personne ou entreprise de l'utiliser librement et sans aucune limite.

A. 2 - Les limites de WDB

Ceci dit, WDB n'a aucune prétention. Il n'est ni le premier, ni le dernier ORM pour PHP. Il y en a en ligne de toutes les catégories, certains vraiment magnifiques et très stables. Nous avons essayé de donner à WDB la plus grande stabilité possible pour une première version, sachant de toute manière qu'il reste encore beaucoup à faire, que ce soit sur le point de la stabilité ou des fonctionnalités. Donc, en utilisant WDB il faudrait être conscient de ceci:

Cependant, nous croyons et espérons vivement que l'utilisation de WDB vous laissera une agréable impression!...

A. 3 - Prérequis pour l'utilisation

- PHP 5.3 ou supérieur.

- PDO doit être installé.

- Une base de données supportée doit être installée.

- Des données d'accès à la DB ( évidemment !).

- Le pilote PDO de votre base de données doit être activé..

A. 4 - SGBDs supportés et pilotes associés

WDB supporte les types de base de données suivants, ainsi que leurs pilotes associés. Cliquez au besoin sur le nom d'un pilote pour aller à la documentation PDO correspondante.

A. 5 - L'installation

A . 5 . 1 - Première étape

Comme ceci a été dit auparavant, vous devez vous assurer que le pilote PDO de votre type de base de données est activé dans le fichier php.ini. Ce sera généralement le cas pour le pilote de SQlite si vous utilisez une version récente de PHP. Si vous utilisez MYSQL, son pilote PDO est souvent activé dans la plupart des hébergements. Mais si vous n'êtes pas certain, vous pouvez lister avec la fonction PHP PDO::getAvailableDrivers() toutes les extensions PDO qui sont installées.

S'il s'avère que votre pilote n'est pas activé, vous pouvez le faire vous-même si vous avez accès au fichier php.ini. Pour cela il faudrait juste ouvrir ce fichier dans un éditeur de texte (pas un éditeur bureautique comme Word, ni WordPad, ni OpenOffice, mais plutôt Bloc-notes ou Gedit) et enlever le point-virgule (;) devant le nom du pilote correspondant à votre base de données et enregistrer le fichier.

A . 5 . 2 - Installation avec Composer

Selon votre OS, exécutez une des commandes suivante:
composer require ncb01/wdb
php composer.phar require ncb01/wdb

Vous n'avez ensuite qu'à inclure le fichier vendor/autoload.php dans votre script PHP et c'est fini.

require "vendor/autoload.php";
/* Dans la suite la connexion à la DB */
 ... 

A . 5 . 3 - Inclusion directe

Si vous voulez inclure WDB de façon directe dans votre script, téléchargez donc WDB si ce n'est encore chose faite, dézippez-le et placez le répertoire wdb à l'endroit désiré de votre site web. Incluez ensuite l'un des deux fichiers suivants dans votre script: src/WDB.php ou vendor/autoload.php. Attention au nom du fichier , qui est bien  WDB.php et non   wdb.php

require "chemin_vers_dossier-wdb/src/WDB.php";
/* Dans la suite la connexion */
 ... 

BConnexion

Notons avant toute chose que la classe WDB et toutes les classes sous-jacentes sont définies dans l'espace de nommage \NCB01\WDB.

Pour travailler avec WDB, il est nécessaire de créer une instance de la classe. Ceci peut être fait de l'une des 3 manières suivantes:

/* connexion avec un array de paramètres */
$db = new \ncb01\wdb\wdb($settings);
/* connexion avec un objet PDO */
$db = new \ncb01\wdb\wdb($pdo, $dbtype [, $options]);
/* connexion avec un DSN */
$db = new \ncb01\wdb\wdb($dsn, $user, $password, $dbtype [, $options]);

Ce type d'appel avec espace de nommage est un peu long et fastudieux. Pour faire simple, nous supposons dès maintenant et dans la suite, que nous avons inclus WDB dans notre script de l'une des deux manières suivantes:

require "chemin_vers_dossier-wdb/WDB.php";
use NCB01\WDB\WDB;
require "chemin_vers_dossier-wdb/vendor/autoload.php";
use NCB01\WDB\WDB;

Avec la seconde instruction ( use NCB01\WDB\WDB ), nous demandons à PHP de pouvoir utiliser la classe WDB en omettant l'espace de nommage. De cette façon, les trois manières pour obtenir une instance de WDB deviennent:

/* connexion avec un array de paramètres */
$db = new wdb($settings);
/* connexion avec un objet PDO */
$db = new wdb($pdo, $dbtype [, $options]);
/* connexion avec un DSN */
$db = new wdb($dsn, $user, $password, $dbtype [, $options]);

B . 1 - Connexion avec un objet PDO

Dans ce cas-ci, l'instanciation de l'objet wdb suit le schéma suivant:

$db = new wdb($pdo, $dbtype [, $options]);

$pdo est un objet PDO que vous avez créé, $dbtype (à voir plus loin) est une constante représentant le type de DB que vous utilisez, et $options est un array d'options (à voir aussi plus loin). Par exemple, une connexion à MYSQL pourrait ressembler à ceci:

# vous créez une instance PDO quelque part ...
$pdo = new PDO(...);

#  ... Et vous utilisez cet objet pour créer WDB.
#  WDB::MYSQL est la constante pour identifier MYSQL et Maria DB
$db = new wdb($pdo, wdb::MYSQL);

Exemple d'utilisation avec SQLite:

# Nous créons un objet PDO quelque part.
$pdo = new PD("sqlite::memory:");

/*  Nous créons WDB avec notre objet PDO. */
$db = new WDB($pdo, wdb::SQLITE);
. . .

Veuillez bien noter que l'instanciation de WDB avec un objet PDO pourrait affecter la valeur de l'attribut PDO::ATTR_ERRMODE de ce dernier. Il est fortement recommandé de ne pas manipuler le même objet pdo en même temps que WDB. Si malgré tout vous voulez le faire, faites-le au mieux quand vous avez fini d'utiliser WDB. Et dans ce cas, il faudrait songer à rétablir la valeur de l'attribut PDO::ATTR_ERRMODE de votre objet PDO.

B . 2 - Connexion avec un array de paramètres

On passe au constructeur WDB un Array de paramètres:

B . 2 . 1 - Connexion à SQLite

/*  Pour se connecter à SQLite on précisera  le type de la base de
 *  données ainsi que le chemin complet du fichier de la DB
 *
 *  Note: si le chemin du fichier est omis, la DB est créée en mémoire.
 */
$db = new wdb(array(
  "type"    =>  wdb::SQLITE,
  "path"    =>  "chemin_vers_fichier_db",   # optionnel,
  "options" =>  array(...),                 # optionnel, voir plus loin
));

B . 2 . 2 - Connexion à Firebird

$db = new wdb(array(
  "type"    =>  wdb::FIREBIRD,
  "user"    =>  "nom_utilisateur",
  "pswd"    =>  "mot_de_passe",
  "path"    =>  "chemin_vers_fichier_db",
  "charset" =>  "charset_name",   # optionnel
  "role"    =>  "SQL role_name",  # optionnel
  "dialect" =>  db_dialect,       # optionnel, vaut 1 ou 3 (valeur par défaut)
  "options" =>  array(...)        # optionnel, voir plus loin
));

B . 2 . 3 - Connexion avec les autres SGBDs

Le schéma general d'instanciation de l'objet WDB est le suivant:

$db = new wdb( $settings )

$settings sera un array PHP contenant les propriétés nécessaires à la connexion. Beaucoup de ces propriétés sont les mêmes pour tous les SGBDs, comme par exemple: le nom de la base, le nom du serveur de DB, le port (souvent optionnel), le nom de l'utilisateur ainsi que le mot de passe de celui-ci. Tous ces éléments seront donc dans $settings, sans oublier le type de SGBD. Cependant, compte ténu de vos besoins et du type de SGBD, d'autres éléments obligatoires ou non viendront peut-être s'ajouter à ceux cités ici. Les clés utilisées pour identifier tel ou tel élément sont illustrées dans l'exemple suivant:

$db = new wdb(array(
  "server"  =>  "nom_du_serveur",
  "port"    =>  "port_de_connexion",  # optionnel
  "dbname"  =>  "nom_de_la_db",
  "type"    =>  wdb::MYSQL,           # voir toutes les constantes plus loin.
  "user"    =>  "nom_utilisateur",
  "pswd"    =>  "mot_de_passe",
  "charset" =>  "jeu_de_caractères",  # optionnel 
  "options" =>  array(...),           # optionnel, voir plus loin
));

Quelques-unes de ces clés peuvent prendre plusieurs noms. Par exemple, on pourra utiliser host ou server au choix, tout comme password ou pswd Les noms dans chacun des groupes suivants sont interchangeables: (server, host) - (db, dbname, database) - (psw, pswd, password) - (file, path, dbpath, dbfile, filepath). Ce dernier groupe sert à désigner le chemin du fichier de base de données pour SQLite ou Firebird

Tous ces éléments ne servent qu'à créer le DSN en interne. Ceci veut dire qu'en dehors des éléments cités ici, tout autre élément pouvant intervenir dans la création du DSN peut apparaître dans l'array $settings

B . 2 . 3 . 1 - Connexion à SQL Server et Sybase

La connexion à SQL Server et à Sybase répond au schéma général, à un détail près. Uniquement pour la connexion à ces deux DBMS, le préfixe DSN est requis. Le type de DB est wdb::SQLSERVER pour SQL Server et wdb::SYBASE pour Sybase. Lorsqu'on utilise SQL Server avec le pilote pdo_sqlsrv le préfixe DSN est sqlsrv: . Lorsqu'on utilise le pilote pdo_dblib le préfixe DSN dépend des bibliothèques sous-jacentes. il peut être sybase: , mssql: ou dblib:

/*  CONNEXION À SQL Server avec pdo_sqlsrv.
 *
 *  En dehors des données globales utilisées par tous les pilotes, pdo_sqlsrv
 *  admet des paramètres extra qui peuvent être ajoutés au besoin. La liste et la
 *  description de ces paramètres sont à trouver dans la doc officielle du pilote.
 */
$db = new wdb(array(
  "prefix"  =>  "sqlsrv:",              # le préfixe est obligatoire
  "server"  =>  "nom_du_serveur",
  "port"    =>  "port_de_connexion",    # optionnel
  "dbname"  =>  "nom_de_la_db",
  "type"    =>  wdb::SQLSERVER,         # constante désignant SQL Server
  "user"    =>  "nom_utilisateur",
  "pswd"    =>  "mot_de_passe",
  "options" =>  array(...),             # optionnel, voir plus loin,

  # Ceci n'est pas obligé. Mais si on veut
  # On peut ajouter des paramètres extra, spécifiques à SQL Server
  "LoginTimeout" =>  120,
  "TransactionIsolation" =>  PDO::SQLSRV_TXN_READ_UNCOMMITTED,
));
/*  CONNEXION à SQL Server avec pdo_dblib
 *
 *  La connexion à Sybase serait identique, sauf pour le préfixe qui
 *  serait "sybase:" et le type qui serait wdb::SYBASE
 */
$db = new wdb(array(
	"prefix"  =>  "mssql:",               # le préfixe est obligatoire
	"server"  =>  "nom_du_serveur",
	"port"    =>  "port_de_connexion",    # optionnel
	"dbname"  =>  "nom_de_la_db",
	"type"    =>  wdb::SQLSERVER,         # constante désignant SQL Server
	"user"    =>  "nom_utilisateur",
	"pswd"    =>  "mot_de_passe",
	'options' =>  array(...),             # optionnel, voir plus loin
));

B . 2 . 3 - Constantes des types de SGBDs

WDB définit une constante pour chaque type de DB supporté. C'est la constante à passer au constructeur WDB quand nous voulons créer une instance. Dans la liste suivante les noms des bases de données sont en bleu, et les constantes correspondantes en rouge pâle. Notons-le bien, les constantes sont toutes en majuscules et sensibles à la casse !!!. Voici la liste complète:

  • Maria DB , MySQL == wdb ::MYSQL
  • SQLite == wdb ::SQLITE
  • PostGreSQL == wdb ::POSTGRESQL
  • Oracle == wdb ::ORACLE
  • Sybase == wdb ::SYBASE
  • SQL Server == wdb ::SQLSERVER
  • Cubrid == wdb ::CUBRID
  • Informix == wdb ::INFORMIX
  • Firebird == wdb ::FIREBIRD
  • DB2 == wdb ::DB2

question Et si on utilisait les noms des SGBDs au lieu des constantes? Pas de problème, WDB transforme automatiquement ceux-ci en leur constante équivalente. De plus, les noms sont insensibles à la casse. Ce qui n'est pas le cas des constantes. Cependant, nous conseillons d'utiliser si possible les constantes, qui sont beaucoup plus rapides. Voici un exemple des noms utilisables pour les différents SGBDs:

Ces noms ne sont qu'une illustration. Dans la réalité, WDB utilise pour la détection les 3 premiers caractères du nom réel lorsqu'il n'y a pas de confusion possible, et 4-5 caractères dans le cas contraire. Il y a évidemment aussi (lorsque le nom réel est très long) quelques noms raccourcis pour aider à la lisibilité: frbd, ifmx, pgsql, sqlsrv .

Ainsi, utiliser "sql" provoquerait une erreur, car pouvant correspondre à sqlite ou sql server

/*  Les deux constructions suivantes fonctionnent donc à l'identique.
 */
$db = new wdb(array(
	'type'   => wdb::SQLSERVER,
	'server' => 'localhost',
	'dbname' => 'maDB',
	'user'   => 'nomUtilisateur',
	'pswd'   => 'motDePasse',
	'prefix' => 'sqlsrv:',
));

$db2 = new wdb(array(
	'type'   => 'SQL Server',
	'server' => 'localhost',
	'dbname' => 'maDB',
	'user'   => 'nomUtilisateur',
	'pswd'   => 'motDePasse',
	'prefix' => 'sqlsrv:',
));

B . 3 - Connexion avec un dsn personnalisé

La signature du constructeur dans ce cas est:

$db = new wdb($dsn, $user, $password, $dbtype [, $options]);

		

- $dsn : Votre DSN, sous forme de chaîne de caractères. Se référer à la documentation officielle de votre base de données pour le format à utiliser. Pour SQLite par exemple, cette chaîne pourrait être sous l'une des formes suivantes: "sqlite3::chemin_vers_fichier_db" ou "sqlite3::memory" etc...

- $user , $password : le nom utilisateur et le mot de passe de la DB. Vaudront FALSE, NULL ou "" tous les deux pour SQLite.

- $dbtype : le type de base de données, comme mentionné précédemment.

- $options : optionnel, devra être un array si fourni. Ce paramètre est décrit dans la suite.

B . 4 - Les options de connexion

Elles sont optionnelles et seront passées le cas échéant sous forme de array clés-valeurs. Elles peuvent s'avérer fort utiles et permettent de configurer certains aspects du serveur de DB ou de la connexion en cours, comme l'activation des connexions persistantes, ou le mode de reçupération des résultats par exemple. Ci-dessous une liste et description sommaire des options PDO les plus courantes.

PDO::ATTR_PERSISTENT

TRUE : Active les connexions persistantes     FALSE : Pas de connexions persistantes

PDO::ATTR_CASE

PDO::CASE_LOWER : force les noms de colonnes à être en minuscules.

PDO::CASE_NATURAL : laisse les noms de colonnes inchangés.

PDO::CASE_UPPER : force les noms de colonnes à être en majuscules.

PDO::ATTR_ORACLE_nuls

Conversion des valeurs NULL et chaînes vides. Contrairement à ce que le nom pourrait laisser entendre, l'option est disponible pour tous les pilotes, et pas juste pour Oracle

PDO::NULL_NATURAL : Pas de conversion.

PDO::NULL_EMPTY_STRING : Chaîne vide convertie en NULL.

PDO::NULL_TO_STRING : NULL est converti en chaîne vide.

PDO::ATTR_EMULATE_PREPARES

Active ou désactive la simulation des requêtes préparées. Certains pilotes ne supportent pas nativement les requêtes préparées ou en ont un support limité. Ce paramètre force PDO à émuler les requêtes préparées (TRUE) ou à utiliser l'interface native (FALSE) . Il tentera toujours une émulation si le pilote n'a pas de support natif. Une valeur booléenne est requise. Par défaut, WDB fixe cette option à TRUE . Si cela n'est pas désiré, il faudra explicitement donner la valeur FALSE à cette option.

TRUE : Simulation activée     FALSE : Pas de simulation

PDO::ATTR_DEFAULT_FETCH_MODE

Définit le mode de reçupération par défaut des résultats. Peut prendre différentes valeurs parmi lesquelles PDO::FETCH_ASSOC , PDO::FETCH_BOTH , PDO::FETCH_LAZY et PDO::FETCH_OBJ . Les différentes descriptions des modes sont disponibles dans la documentation PHP officielle de la méthode PDOStatement::fetch() .  Par défaut, WDB fixe cette option à PDO::FETCH_ASSOC  . Cela veut dire que les lignes des résultats sont renvoyées sous forme d'un array PHP, les noms des colonnes en sont les clés.

PDO::ATTR_STRINGIFY_FETCHES

Convertit ( quand il vaut TRUE ) les valeurs numériques en chaîne lors de la lecture des résultats. Prend une valeur booléenne TRUE ou FALSE

PDO::ATTR_AUTOCOMMIT

Disponible sur OCI, Firebird et MySQL - activation de l'autocommit pour chaque commande. Prend une valeur booléenne TRUE ou FALSE

PDO::MYSQL_ATTR_USE_BUFFERED_QUERY

Disponible sur MySQL - utilisation des requêtes bufférisées. Prend une valeur booléenne TRUE ou FALSE

PDO::ATTR_ERRMODE

Gestion des rapports d'erreurs.

PDO::ERRMODE_SILENT : assigne simplement les codes d'erreur

PDO::ERRMODE_WARNING: : émet une alerte E_WARNING.

PDO::ERRMODE_EXCEPTION : émet une exception - Valeur par défaut de WDB

/*  Exemple de connexion avec MySQL.
 *
 *  Activons les connexions persistantes, émulons la simulation des requêtes
 *  préparées et forçons les noms des colonnes à être en majuscules.
 */
$db = new wdb(array(
  'type'   => wdb::MYSQL,
  'server' => 'localhost',
  'dbname' => 'maDB',
  'user'   => 'nomUtilisateur',
  'pswd'   => 'motDePasse',
  'options'=>  array(
     PDO::ATTR_PERSISTENT  => TRUE,
     PDO::ATTR_EMULATE_PREPARES  => TRUE,
     PDO::ATTR_CASE  => PDO::CASE_UPPER
   )
));

C Manipulation des données


Il sera nécessaire, après avoir lu cette partie, ou peut-être même avant, de jeter un coup d'œil à la partie expliquant succinctement l'utilisation des conditions dans WDB. Il est aussi important de noter que la plupart des fonctions publiques non statiques de WDB renvoient l'objet WDB, permettant ainsi un chaînage des actions. Mais sur ce dernier point nous en reparlerons plus tard.

C. 1 - La sélection des données

Dans cette partie, nous verrons tour à tour les points suivants:

C . 1 . 1 - select chaîné

En supposant que $db est une instance de WDB, le schéma complet d'une sélection chaînée:
$db
 ->select($columns)  # seule fonction obligatoire
 ->from($tables)
 ->join($tables_to_join) # peut être appelée plusieurs fois ou remplacée
 ->where($where)
 ->groupby($group_columns)
 ->having($having_condition)
 ->orderby($order)
 ->limit($nbr, $offset);

Intervertir l'ordre des fonctions provoquerait une erreur. La fonction join() peut être remplacée par une de ses jumelles ljoin() pour LEFT JOIN, rjoin() pour RIGHT JOIN, ou fjoin() pour FULL JOIN. Chacune de ces méthodes pourrait être appelée plusieurs fois si nécessaire.

Les paramètres

$columns,  $group_columns

String:    "colonne1, colonne2, . . ., colonne_n AS Alias"
Array:    array("colonne1", "colonne2", . . ., "colonne_n" => "Alias")

$tables

String:    "table1, table2, . . ., table_n"
Array:    array("table1", "table2", . . ., "table_n")

$tables_to_join

String:    "JOIN tableX ON conditionX"
String:    "LEFT JOIN tableX ON conditionX   RIGHT JOIN tableY ON conditionY"
Array:    array("tableX" => "conditionX", "tableY" => "conditionY", . . .)

$where,  $having_condition

String:    "column1 = 2 OR ( column3 = column2 AND column1 = 5 )"
Array:     array (
                          "column1" => 2,
                          "AND" => array (
                                  "column3"  =>   "#column2",       ( voir l'utilisation du hashtag plus loin )
                                  "column1"  =>   5,
                          ),
                )

$group_columns

String:    "colonne1, colonne2, . . ., colonne_n"
Array:    array("colonne1", "colonne2", . . ., "colonne_n")

$order

String:    "column1 ASC, column2 DESC . . ."
Array:     array(
                      "column1" => "ASC",
                      "column2" => "DESC",
                )

$nbr , $offset   :   int

La méthode wdb->join() peut donc recevoir un paramètre String ou Array comme décrit ci-dessus. Alternativement et lorsqu'on doit joindre uniquement une table, elle peut aussi recevoir deux paramètres, comme suit:

$db->join($table_to_join, $condition);

C . 1 . 2 - select raccourci

En supposant que $db est une instance de WDB, le schéma d'une sélection raccourcie sera:
$db->select($tables, $columns[, $where]);
Il n'est pas possible ici de passer plus de paramètres que ceux-là, ni d'étendre ladite instruction en appelant à sa suite les fonctions vues précédemment.

Les paramètres

Ils sont les mêmes que les paramètres de mêmes noms décrits précédemment.

Il est important de noter qu'à l'endroit où la fonction wdb->select() attend un nom de table, un ou plusieurs noms de tables peuvent être donnés. Si cette liste de noms est donnée en tant que chaîne de caractères, les noms doivent être séparés les uns les autres par une virgule, et être syntaxiquement corrects du point de vue SQL . Les noms de tables doivent donc être mis entre guillemets quand cela est nécessaire. Cela reste nécessaire même si c'est un seul nom de table qui est fourni dans une chaîne. Si par contre les noms des tables sont listés dans une table, ces noms sont automatiquement mis entre guillemets par WDB. Cette remarque reste vraie pour les noms de colonnes.

C . 1 . 3 - Exemples

Supposons que nous avons une base de données pour étudiants et professeurs avec plusieurs tables dont seulement les 4 suivantes nous sont utiles pour le moment. Faire passer la souris sur le nom d'une colonne pour avoir une description simple de celle-ci.

La colonne photo de la table etudiant est de type BLOB et vaut NULL par défaut. Cette colonne ne sera pas utilisée dans nos exemples de la suite. Pour tous les exemples suivants, nous supposons que le chargement et l'instanciation de WDB sont déjà choses faites. $db est l'instance WDB.

/*  Exemple de sélection raccourcie.
 *
 *  Pour l'année scolaire 2020-2021 nous sélectionnons toutes les notes
 *  de l'étudiant dont l'ID est 10. Le nom de notre table n'est pas
 *  syntaxiquement correcte. Nous donnons alors le nom de la table dans
 *  un Array, de cette façon on n'a pas besoin de mettre les guillemets
 *  SQL.
 */
$db->select
(  array("note-etudiant") # le nom de la table
  "matière, note",        # liste des colonnes à sélectionner
   array                  # ceci est la condition. Nous en reparlons plus tard
   (  "and" => array
      (    "studid" => 10,
           "annee" => "2020-2021",
      )
   )
);

/*   On affiche les résultats.
 *
 *   La fonction wdb->fetch() renvoie un élément de résultat ou NULL si aucun
 *   résultat n'est plus disponible. Par défaut le type de donnée est Array.
 * 
 *   Si on veut tous les résultats d'un seul coup, on utilisera la fonction
 *   wdb->fetchAll()
 */
while($e = $db->fetch()) var_dump($e);

Dans l'exemple précédent, les noms de colonnes sont listés dans une chaîne de caractères. Il y aurait fallu les mettre entre guillemets si ceux-ci n'étaient pas des noms syntaxiquement corrects. Ceci n'était qu'une petite illustration d'un problème traité plus amplement dans le cadre des expressions

/*  Autre exemple de sélection raccourcie.
 *
 *  Sélection de toutes les lignes avec toutes leurs colonnes dans la
 *  table "etudiant". À éviter absolument dans une application réelle !!!
 */
$db->select('etudiant', '*');

/*  On affiche les résultats. */
while($e = $db->fetch()) var_dump($e);

On pourrait préciser le type de résultats voulu en passant la constante adéquate comme paramètre des fonctions wdb->fetch() et wdb->fetchAll() . Ces constantes sont décrites dans la doc PHP ici PDOStatement::fetch et ici PDOStatement::fetchAll

Dans une instruction SELECT la liste des colonnes peut être donnée sous forme de array ou de chaîne de caractères comme dans l'exemple suivant.

/*   Ceci est un autre exemple de sélection raccourcie.
 *
 *   Prenons maintenant toutes les filles, mais seulement leur nom,
 *   prénom et date de naissance, en supposant que pour les filles
 *   le sexe puisse être 'F' ou 'f'
 */
$db -> select
(   "etudiant", 
    "nom, prenom, ndate",  # liste des colonnes
    array(                 # array servant de condition
       'sexe' => 'f',
       'sexe' => 'F'
    )
);

Ce dernier exemple est donc pleinement équivalent à celui-ci:

$db -> select
(   "etudiant", 
    array("nom", "prenom", "ndate"),  # liste des colonnes
    array(
       'sexe' => 'f',
       'sexe' => 'F'
    )
);

Voici dans la suite un exemple de sélection chaînée. Nous sélectionnons les colonnes "studid", "sexe", "ndate", "classid" de l'étudiant dont le nom est "Akanato" et le prénom "Steffie". On prendra aussi le nom et prénom de son professeur principal.

$db -> select("etudiant.studid, etudiant.sexe, etudiant.ndate,".
       "etudiant.classid, prof.nom, prof.prenom")
    -> from("etudiant")
    -> ljoin("classe", "classe.classid = etudiant.classid")
    -> ljoin("prof", "prof.profid = classe.profid")
    -> where(array
       (  "AND" => array
           (  "etudiant.nom" => "Akanato",
              "etudiant.prenom" => "Steffie"
           )
       ));

# We display the results
var_dump($db-fetchAll());

On peut sélectionner comme en SQL, autre chose que des colonnes. En SQL une instruction du genre  SELECT 30*45, COS(45)  est faisable, et même banale. Avec WDB on le ferait avec un SELECT raccourci de cette façon:

$db->select(false, "30*45, COS(45)");
var_dump($db->fetch());

Avec PostGreSQL par exemple, ce code affiche quelque chose du genre

C:\Users\Kabali\Documents\Projets-Web\wdb\version-1.0.0\tests.php:137:
array (size=2)
  '?column?' => int 1350
  'cos' => string '0.52532198881773' (length=16)

Avant de décrire les autres méthodes permettant de sélectionner les données, nous allons rapidement voir quelques notions importantes liées à la sélection.

C . 1 . 4 - Les alias dans la sélection

Dans une sélection avec la fonction WDB->select() on peut utiliser les alias de colonnes et de tables. Le mot-clé AS peut être utilisé, mais n'est pas obligatoire. Lorsque la liste des éléments à sélectionner est mise dans une chaîne de caractères, tout se fera comme en SQL.

Voici par exemple comment on pourrait réécrire l'instruction précédente avec les alias:

$db->select(false, "30*45 as product, COS(45) as cos");
var_dump($db->fetch());

Nous allons maintenant utiliser des alias dans une sélection chaînée. Nous utilisons notre base de données d'exemple esquissée dans l'exemple 1.3

Dans le code qui suit, nous sélectionnons pour chaque étudiant les colonnes nom, prenom, ndate, sexe, le nom de la classe et le nom du prof principal. Nous donnons à la table etudiant le nom d'alias stud, et au nom de la classe (classe.nom) l'alias nom_classe et au nom du professeur (prof.nom) l'alias nom_prof. Nous recupérons les résultats sous forme d'objets PHP. La fonction ljoin() est l'instruction LEFT JOIN.

$db -> select("stud.nom, stud.prenom, stud.ndate, stud.sexe,
       classe.nom AS nom_classe, prof.nom AS nom_prof")
    -> from('etudiant stud')	# stud est l'alias de etudiant
    -> ljoin('classe', 'classe.classid = stud.classid')
    -> ljoin('prof', 'prof.profid = classe.classid');
	
/* On affiche les résultats un à un */
while($e = $db->fetch(\PDO::FETCH_OBJ)) var_dump($e);

Notons juste en passant qu'en dehors de la fonction wdb->ljoin() utilisée ici, il y a aussi les fonctions wdb->join (JOIN), wdb->rjoin (RIGHT JOIN) et wdb->fjoin (FULL JOIN) .

Et qu'en est-il des tables ou colonnes placées dans un array? Réécrivons notre dernière sélection en mettant la table "etudiant" et les differentes colonnes à sélectionner dans un array. Notons l'utilisation des alias dans ce contexte.

$db->select
(  array  # tableau des éléments à sélectionner
   (  "stud.nom", "stud.prenom",
      "stud.ndate", "stud.sexe",
      "classe.nom" => "nom_classe",  # nom_classe est l'alias de classe.nom
      "prof.nom" => "nom_prof"       # nom_prof est l'alias de prof.nom
   )
)
->from(array("etudiant" => "stud"))  # stud est l'alias de etudiant
->ljoin("classe", "classe.classid = stud.classid")
->ljoin("prof", "prof.profid = classe.classid");
	
/* On affiche les résultats un à un */
while($e = $db->fetch(\PDO::FETCH_OBJ)) var_dump($e);

Nous comprenons donc que lorsque la liste des tables ou des colonnes à sélectionner est donnée sous forme de array, l'utilisation des alias se fait comme suit: Le nom de la table ou de la colonne sert de clé et l'alias sert de valeur:

$db -> select
(  "table",
   array
   (  "colonne1" => "alias1",
      "colonne2" => "alias2",
      "colonne_sans_alias"
   )
);

Voici un bon exemple de ce qu'il ne faut surtout pas faire, mélanger les deux méthodes. C'est-à-dire lister les colonnes à sélectionner dans un array, chaque colonne et son alias étant contenus dans la même chaîne de caractères. Comme dans l'exemple suivant:

/*  Cet exemple échoue car les chaînes "colonne1 alias1" et
 *  "colonne2 AS alias2" sont interprétés comme noms de colonnes
 *  et sont automatiquement protégés avec des guillemets adéquats.
 */
$db -> select
(  "table",
   array
   (  "colonne1 alias1",
      "colonne2 AS alias2",
      "colonne_sans_alias"
   )
);code erroné

Arrivés à ce point, et aussi pour s'amuser un peu, on pourrait se demander comment retranscrire avec WDB notre instruction SQL  SELECT 30*45 AS product, COS(45) AS cos  en utilisant un array et non pas une chaîne de caractères? Car comme nous venons de le dire, si on faisait comme dans le code suivant cela provoquerait une erreur.

/*  Ceci ne fonctionnera pas car les chaînes "30*45 AS product" et
 *  "COS(45) as cos" sont interpretées comme des noms de colonnes
 */
$db->select(
   false,
   array(
      "30*45 AS product",
      "COS(45) as cos",
   )
);

De même, si on essayait de faire comme ci-dessous, cela ne fonctionnerait toujours pas, car les chaînes "30*45" et "COS(45)" sont interprétées comme des noms de colonnes (et donc automatiquement échappées) et non pas comme des expressions qu'elles sont.

/*  Ceci ne fonctionnera pas non plus */
$db->select(
   false,
   array(
      "30*45" => "product",
      "COS(45)" => "cos"
   )
);

Dans la section L'hashtag et les expressions, il est expliqué comment résoudre ce problème.

C . 1 . 5 - sélections diverses

Pour comprendre comment WDB se comporte dans certaines situations, il faudrait comprendre comment il analyse les arrays en général. Considérons la commande SQL suivante SELECT -4 AS m4, 3 AS trois. À ce stade, essayons deux manières simples de le faire avec WDB:

/*   Cette première approche fonctionne parfaitement.
 *   Tous les éléments à sélectionner sont fournis dans un String
 */
$db -> select
(  false,
   "-4 AS m4, 3 AS trois"
);
/*   Ici les éléments à sélectionner sont fournis sous forme de array.
 *   Cette seconde approche peut sembler évidente, mais ne fonctionne pas.
 */
$db -> select
(  false,
   array(
      -4 => "m4",
       3 => "trois"    # Le problème vient d'ici
   )
);

Ce dernier exemple échoue car les clés entières positives ou nulles sont ignorées pendant le processus d'analyse. Cela peut sembler déconcertant de prime abord. Cependant, voyons cet autre code:

$db -> select
(  false,
   array(-4, 3, 7)
);

Écrit de cette manière, on arrive à comprendre facilement que nous voulons sélectionner les nombres -4, 3 et 7 sans utiliser aucun alias. Du point de vue de PHP, le code précédent peut aussi s'écrire de la manière suivante:

$db -> select
(  false,
   array(
      0 => -4,
      1 =>  3,
      2 =>  7
   )
);

C'est la raison pour laquelle les clés entières >=0 sont ignorées par WDB. Les clés numériques non entières ou négatives ne posent aucun problème. Elles sont interprétées comme prévu. Les clés de type chaînes de caractères sont interprétées comme des noms de colonnes. Nous comprenons maintenant pourquoi notre exemple de tout à l'heure ne fonctionne pas comme on aurait pu le croire:

/* Le code suivant est interprété comme celui qui vient juste après */
$db -> select
(  false,
   array(
      -4 => "m4",
       3 => "trois"    # Le problème vient d'ici
   )
);

/* Le code précédent est vu par WDB comme suit: */
$db -> select
(  false,
   array(
      -4 => "m4",
      "trois"
   )
);

Ainsi, en voulant exécuter la commande  SELECT -4 AS m4, 3 AS trois , nous exécutons plutôt  SELECT -4 AS m4, trois . Dans la section L'hashtag et les expressions, il est expliqué comment résoudre ce problème.

C . 1 . 6 - Chargement par pseudo Active record

La technique est toute simple: il est question d'utiliser un objet pour manipuler les données d'une ligne unique dans une table spécifique de notre base de données. Nous appelons cela Pseudo Active Record car la manipulation s'apparente à la technique de l'Active Record, mais n'en est pas. Car WDB n'a absolument pas connaissance de la structure de votre base de données.

Pour utiliser cette technique il faut une table avec soit une colonne UNIQUE, soit un certain nombre de colonnes qui prises conjointement forment un ensemble UNIQUE. Dans la suite nous appellerons cette colonne ou cet ensemble de colonnes "CLÉ", quoi que dans la pratique, il n'est pas nécessairement besoin que cette colonne ou cet ensemble de colonnes soit une clé du point de vue SQL. Cette "clé" UNIQUE permet d'identifier une ligne de la table de façon unique.

C'est la classe WDBRow qui permet de manipuler les données par Pseudo Active Record. Pour obtenir un objet de cette classe et éventuellement charger les données d'une ligne de la BD, il nous faut évidemment connaitre le nom de la table, le nom de la clé et la valeur de la clé pour la ligne dont nous voulons charger les données.

Dans la pratique on obtiendra un objet WDBRow de l'une des deux manières suivantes:

$row = $db->row($tableName, $keyName);
$row = $db->row($tableName, $keyName, $keyValue);

Ces deux syntaxes sont claires lorsqu'on a affaire à une clé qui consiste en une seule colonne. Mais pour des clés composites (clés avec plusieurs colonnes), des explications supplémentaires sont données dans la suite.

Une fois l'objet WDBRow obtenu, on peut alors au besoin charger les données d'une ligne spécifique, affecter des nouvelles valeurs aux données et enregistrer celles-ci.

Dans l'exemple qui suit, supposons que nous avons la table users avec les colonnes userid (clé de type INTEGER), nom, prenom, email etc... Nous allons charger les données de l'utilisateur dont l' ID (userid) est 100.

$row = $db->row("users", "userid");   # instanciation
if( $row->load(100) ) echo "Chargement réussi !";
else die "Échec du chargement! Erreur: ".$row->error();

/*   Après un chargement réussi, $row est un objet contenant les
 *   noms de colonnes comme propriétés publiques. Dans la suite
 *   on peut changer la valeur de toutes les propriétés de l'objet
 *   (ie. colonnes de la ligne) et sauvegarder avec simplicité
 */
$row->nom = "nouveau nom";
$row->prenom = "nouveau prenom";
....
$row->update();

Si la valeur de la clé est donnée à l'instanciation, on aura plus besoin de préciser cette valeur au moment du chargement. Ainsi donc, le chargement de notre utilisateur (ID = 100) peut aussi se faire de la façon suivante:

$row = $db->row("users", "userid", 100);   # instanciation
if( $row->load() ) echo "Chargement réussi !";
else die "Échec du chargement! Message: ".$row->error();

Par défaut toutes les colonnes de la ligne et leurs valeurs sont chargées dans l'objet WDBRow, mais on peut préciser les noms des colonnes à charger comme 2e argument de WDBRow->load(). Voici la signature de cette fonction:

load( mixed $keyValue = null, mixed $columns = "*") : bool

Supposons maintenant que nous avons une table MyTable avec une clé composite formée par les colonnes ckey1 et ckey2. L'instanciation pourra alors se faire avec ou sans valeur pour les colonnes de la clé comme suit:

$row = $db->row($tableName, array("ckey1", "ckey2"));
$row = $db->row($tableName, array("ckey1" => $val1, "ckey2" => $val2));
/* On peut aussi renseigner la valeur de la clé comme suit: */
$row = $db->row($tableName, array("ckey1", "ckey2"));
$row->ckey1 = $val1; $row->ckey2 = $val2;

Le chargement des données d'une ligne peut se faire comme suit:

$row = $db->row($tableName, array("ckey1", "ckey2"));

if( $row->load( array("ckey1" => $val1, "ckey2" => $val2) ))
   echo "Chargement réussi !";
else die "Échec du chargement !";

/*  On peut changer la valeur des données dans
 *  la suite et enregistrer avec $row->update()
 */
. . .

Des informations supplémentaires sont fournies dans la partie Mise à jour des données - Pseudo Active record

C . 1 . 7 - Chargement des données avec wdb->get()

Lorsque qu'on dispose d'une table avec une clé UNIQUE, la fonction wdb->get() est un moyen simple et direct pour charger des données. Voici son utilisation:

$results = $db->get($table, $key, $valeurs[, $colonnes]);

Cette fonction est pratique et simple d'utilisation. Dans cette signature, $table est le nom de la table à partir de laquelle nous voulons charger les données. $key est le nom de la colonne CLÉ UNIQUE de la table. $valeurs est la ou les valeurs de la clé pour laquelle / lesquelles nous voulons charger les données. $colonnes est la liste des colonnes à renvoyer. Cette liste peut être fournie sous forme de String ou d'array. Par défaut toutes les colonnes sont sélectionnées.

Cette fonction renvoie directement les résultats, sauf si elle est utilisée avec des paramètres de requête. Il s'agit d'un array qui peut être vide ou contenir un ou plusieurs sets de données ( eux-mêmes sous forme d'array )..

/*   Dans cet exemple nous chargeons toutes les données
 *   de l'étudiant dont l'ID (studid) vaut 5
 */
$results = $db->get("etudiant", "studid", 5);

# Nous affichons les données de l'étudiant
if($results) var_dump($results[0]);

On peut faire la même chose, mais en sélectionnant seulement les colonnes "nom", "prenom", et "ndate" comme suit:

$results = $db->get("etudiant", "studid", 5, array("nom", "prenom", "ndate"));

# Nous affichons les données de l'étudiant
if($results) var_dump($results[0]);

On peut sélectionner les données pour plusieurs valeurs de la clé.

/*  On sélectionne les données des étudiants dont "studid" vaut 5, 6, ou 7  */
$results = $db->get("etudiant", "studid", array(5, 6, 7));

# Nous affichons les résultats
var_dump($results);

La bonne nouvelle dessus c'est que les clés composites sont aussi supportées. Imaginons une table "MaTable" qui possède une clé composite de 3 colonnes "iCol1", "iCol2" et "iCol3" . Chaque valeur de la clé composite sera alors un array de 3 valeurs, dont l'ordre est celui des colonnes de la clé. Voyons cela:

/*  Ici nous sélectionnons les données pour une seule valeur de la clé.
 *  Pour simplifier, nous supposons dans ces exemples que les trois colon-
 *  nes composant la clé sont de type entier.
 */
$results = $db->get
( "MaTable",
   array("iCol1", "iCol2", "iCol2"),  # Ceci est la clé composite
   array(5, 6, 7)    # ceci est une seule valeur de la clé
);

# Nous affichons le résultat
if($results) var_dump($results[0]);

/*  Ici nous sélectionnons les données pour 2 valeurs de la clé. */
$results = $db->get
( "MaTable",
   array("iCol1", "iCol2", "iCol2"),  # Ceci est la clé composite
   array
   (  array(5, 6, 7),   # ceci est une valeur de la clé
      array(2, 1, 3)    # ceci est une autre valeur de la clé
   )
);

# Nous affichons les résultats en une seule fois
var_dump($results);

Résultat de wdb->get()  : Si la fonction get est utilisée conjointement avec des paramètres de requête, elle ne renvoie pas le résultat de la requête, mais l'objet WDB car la requête n'est simplement pas exécutée. En effet, il faut que tous les paramètres de la requête aient reçu une valeur avant que la requête ne puisse être exécutée. Voir la session Paramètres de requête avec wdb->get

C . 2 - L'hashtag et les expressions

Nous n'avons certainement pas oublié notre fameuse instruction SQL  SELECT -4 AS m4, 3 AS trois qu'on ne pouvait traduire en une instruction WDB en utilisant uniquement les arrays. Il faut dire que celle-là n'était qu'un banal exemple, et que sans les expressions on risque d'avoir quand même quelques difficultés. Dans cette partie, nous abordons tour à tour les points suivants:

C . 2 . 1 - Comment WDB analyse les arrays

Nous l'avons souligné auparavant. Dans une sélection comme celle qui suit, les clés entières >=0 d'un array ne sont simplement pas interprétées. La chaîne "40 + 90" est considérée comme le nom d'une colonne et non comme une expression. Une personne non avisée risque d'être surprise par l'interprétation du code suivant:

$db -> select
(   false,
    array
    (   "col_1",       # interprété comme nom de colonne
        "40 + 90",     # interprété comme nom de colonne
         5 => "alias"  # On sélectionne la colonne "alias". 5 ne joue aucun rôle ici.
    )
);

Le code précédent est interprété comme suit:

$db -> select
(   false,
    array("col_1", "40 + 90", "alias")
);

Le code SQL généré par exemple sur MYSQL ressemble à quelque chose du genre:  SELECT `col_1`, `40 + 90`, `alias`  . La situation est à peu près la même quand il s'agit d'un array utilisé comme condition. Prenons l'instruction SQL suivante   SELECT col1 FROm MyTable WHERE col1 = (col2 + col3) .

/*  Une fois encore, l'instruction suivante ne fonctionne pas,
 *  car la condition n'est pas interprétée "simplement" comme
 *  on pourrait l'imaginer : WHERE col_1 = col_2 + col_3
 */
$db -> select
(   "MyTable",
    "col_1",
    array( "col_1" => "col_2 + col_3") # Ne marche pas.
);

Dans MYSQL par exemple, le code SQL généré par WDB ressemble à quelque chose du genre:

SELECT col_1 FROM MyTable WHERE (`col_1` = 'col_2 + col_3')

Cela veut dire que dans cette condition, "col1" à été interprété comme un nom de colonne, et "col2 + col3" a été interprété comme une chaîne de caractères.

Nous résumons sommairement:

   $db->select
   (  array
      (  "str1" => "str1.2", # str1 est nom de colonne, str1.2 est l'alias
         "str2",             # str2 est nom de colonne
         "str3" => 11,       # erreur
         5 => "str4",        # str4 est nom de colonne, 5 ne joue aucun rôle.
         -3 => "str5",       # -3 est la valeur à selectionner, str5 est l'alias
        20 => 40             # erreur
      )
   )->from
   (  array
      (  "str6" => "str6.2", # str6 est nom de table, str6.2 est l'alias
         "str7",             # str7 est nom de table
         "str8" => 11,       # erreur
         5 => "str9",        # str9 est nom de table, 5 ne joue aucun rôle.
         -3 => "str10",      # erreur
        20 => 40             # erreur
      )
   );

L'analyse d'une condition est un peu plus complexe que cela. Ce sujet est abordé en profondeur dans la partie Les conditions

C . 2 . 2 - L'hashtag pour une expression

Une expression est une chaîne de caractères qui est restituée plus ou moins telle quelle dans le code SQL final. Utilisée dans un tableau comme clé ou valeur, elle n'est donc pas interprétée selon les règles énoncées tout à l'heure.

L'hashtag (#) est ce qui introduit une expression. Autrement dit, c'est lui qui signale à WDB que la chaîne de caractères ne doit pas être interprétée comme de nature, mais comme une expression. Vous pouvez si nécessaire, remplacer l'hashtag par le ou les caractères qui vous conviennent. Une expression peut contenir des noms de colonnes, des nombres, des appels de fonctions, des chaînes de caractères et des opérateurs.

Reprenons notre ancien code SQL  SELECT -4 AS m4, 3 AS trois . Nous avons vu que les deux façons suivantes ne fonctionnaient pas:

/*   Ceci ne fonctionne pas */
$db -> select
(  false,
   array
   (  -4 => "m4",
       3 => "trois"  /* 3 n'est simplement pas interprété */
   )
);

/*   Ceci ne fonctionne pas non plus */
$db -> select
(  false,
   array
   (   -4  => "m4",
       "3" => "trois" /* "3" est interprété comme nom de colonne. */
   )
);

En utilisant convenablement l'hashtag, tout fonctionne parfaitement:

$db -> select
(  false,
   array
   (   -4  => "m4",
       "#3" => "trois"
   )
);

Reprenons un code SQL commenté précédemment. SELECT 30*45 AS product, COS(45) AS cos . Là encore, nous avons vu que les deux manières suivantes ne fonctionnaient pas.

/*  Ceci ne fonctionnera pas */
$db->select(
   false,
   array(
      "30*45 AS product",  /* interprété comme nom de colonne */
      "COS(45) as cos",    /* interprété comme nom de colonne */
   )
);

/*  Ceci ne fonctionnera pas non plus */
$db->select(
   false,
   array(
      "30*45" => "product", /* "30*45" est interprété comme nom de colonne */
      "COS(45)" => "cos"    /* "COS(45)" est interprété comme nom de colonne */
   )
);

Grâce à l'hashtag les deux sélections suivantes fonctionnent parfaitement:

/*  Cette instruction est OK */
$db->select(
   false,
   array(
      "#30*45 AS product",  /* interprété comme expression */
      "#COS(45) as cos",    /* interprété comme expression */
   )
);

/*  Cette instruction aussi est OK */
$db->select(
   false,
   array(
      "#30*45" => "product",  /* 30*45 est interprété comme expression */
      "#COS(45)" => "cos"     /* COS(45) est interprété comme expression */
   )
);

Avec la fonction wdb->select, la liste des noms de tables ainsi que la liste des éléments à sélectionner sont d'emblée des expressions si fournies sous forme de chaîne de caractères. Il n'est aucun besoin d'y ajouter l'hashtag.

/*  L'instruction suivante fonctionne parfaitement */
$db->select(
   false,
   "30*45 AS product, COS(45) as cos"
);

Même si WDB les analysent, il n'apporte en général de lui-même aucune modification aux expressions. Celles-ci doivent donc être syntaxiquement correctes pour le SGBD courant. Cela est vrai partout et en toute situation, que ce soit dans une liste de sélection ou dans une condition. Les chaînes de caractères et les identificateurs dans une expression doivent être entourés de guillemets adéquats.

/*  Dans cet exemple, nous supposons avoir une table "MaTable" avec
 *  deux colonnes entières "col 1" et "col 2". Nous voulons prendre
 *  toutes les lignes telles que "col 1" est égal à "col 2".
 *
 *  Sans grande surprise, l'instruction suivante ne fonctionne pas.
 *  Les raisons en sont données dans la suite.
 */
$db->update
(  "MaTable", 
   "*",
   array(
     "col 1 "  =>  "col 2"   # Provoque une erreur
   )
);

# L'instruction suivante ne fonctionne pas non plus.
$db->update
(  "MaTable", 
   "*",
   array(
     "col 1 "  =>  "#col 2"   # Provoque une erreur
   )
);

# Mais celle-ci fonctionne
$db->update
(  "MaTable", 
   "*",
   array( "col 1 "  =>  '# "col 2"')
);

La première instruction échoue car la valeur "col 2" est interprétée comme une chaîne de caractères et non comme un nom de colonne. La seconde instruction échoue car dans l'expression "#col 2", le nom de colonne col 2 n'est pas protégé par des guillemets. Dans la dernière instruction par contre, le nom de colonne dans l'expression de droite est correctement entouré de guillemets.

Comme cela a été indiqué, vous pouvez changer si nécessaire l'hashtag par un ou des caractères qui vous conviennent. Cela sera notamment nécessaire si une de vos chaînes de caractères commence par un hashtag, comme dans l'exemple suivant:

/*  Dans cet exemple, supposons que la colonne "col1" de la table
 *  "MyTable" est de type VARCHAR.
 *
 *  Nous voulons sélectionner toutes les lignes de la table pour 
 *  lesquelles la valeur de la colonne "col1" est égale à la chaîne
 *  "#MeToo et #BalanceTonPorc". Ceci ne fonctionne pas:
 */
$db->select(
   'MyTable',
   '*',
   array("col1" => "#MeToo et #BalanceTonPorc")
);

Ce code causera une erreur à l'exécution, car notre chaîne de caractères est interprétée comme une expression alors qu'elle n'en est pas une. Pour remédier à cela, on peut par exemple remplacer le caractère d'introduction des expressions comme suit:

/*  Vous pouvez mettre le ou les caractère(s) qui vous conviennent */
$db->exp_begin = "!@";

/*  Maintenant c'est le !@ qui introduira les expressions.
 *  On peut alors exécuter notre code, qui ne génère plus d'erreur.
 */
$db->select(
   'MyTable',
   '*',
   array("col1" => "#MeToo et #BalanceTonPorc")
);

C . 2 . 3 - Mise entre guillemets

Les chaînes dans les expressions ainsi que les identificateurs non conformes doivent être convenablement entourés de guillemets. Là-dessus la plupart des SGBDs (mais pas tous) utilisent les guillemets doubles ( " ) pour les identificateurs et les guillemets simples ( ' ) pour les chaînes de caractères. Pour cette raison WDB suit la convention suivante quant à l'utilisation des guillemets:

- les guillemets " " (doubles) et ` ` (MYSQL) pour les noms de colonnes et des tables.

- les guillemets ' ' (simples) pour les chaînes de caractères.

Cependant, mettre des éléments entre guillemets dans une chaine elle-même entre guillemet n'est pas toujours simple. Pour rendre cela plus facile, WDB a adopté une convention alternative:

- les crochets [ ] pour les noms de colonnes et de tables

- les accolades { } pour les chaînes de caractères.

Lorsque dans une expression, WDB rencontre une partie mise entre [ ] , " " ou ` `, WDB comprend qu'il s'agit d'un identificateur et protège ledit nom avec les guillemets adaptés au SGBD courant. Il en est de même pour les chaînes de caractères mises entre ' ' ou { }

/*  Les deux arrays suivants sont équivalents, qu'ils soient
 *  utilisés tous les deux comme conditions ou arrays de selection.
 */
$cond = array(
   "col2"     =>  "# 'chaîne SQL' ",
   "col3"     =>  '# "ma colonne" * 3 '
);

$cond2 = array(
   "col2"     =>  "# {chaîne SQL} ",
   "col3"     =>  "# [ma colonne] * 3 "
);

Cela a été dit auparavant: la liste des éléments à sélectionner passée à la fonction WDB::select() est considérée comme une expression, lorsqu'elle est une chaîne de caractères. Elle ne nécessite pas d'hastag au début. Les mêmes précautions doivent donc s'appliquer, à savoir la mise des identificateurs entre guillemets quand cela est nécessaire.

/*  Nous voulons sélectionner les données de 2 colonnes: 'colonne 1' et 'colonne 2'
*  de la table 'ma table'. QU'il n'y ait qu'une seule table ou plusieurs, les noms des
*  tables doivent aussi être protégés quand ces noms contiennent des caractères
*  susceptibles de provoquer des erreurs. Cela est vrai aussi pour les colonnes.
*/
$db -> select
(   ' "ma table" ',
    ' "colonne 1", "colonne 2" ',
    false
);

/*  Quand la liste des tables ou des colonnes est donnée sous forme d'array,
 *  les noms n'auront pas besoin d'être protégés, sauf s'ils sont multi-champs.
 */
$db -> select
(   array("ma table"),
    array("colonne 1", "colonne 2"),
    false
);

/*  Quand cela est nécessaire, les noms multi-champs peuvent
 *  aussi par exemple être protégés de la façon suivante:
 */
$db -> select
(   array("ma table"),
    array("[ma table].[colonne 1]", "[ma table].[colonne 2]"),
    false
);

C . 3 - Les conditions

Nous les avons utilisé jusqu'à maintenant puisqu'on ne pouvait pas faire sans. Les fonction wdb->select(), wdb->update(), wdb->get() et wdb->delete() utilisent les conditions. Cette partie a pour but d'expliquer succinctement leur fonctionnement, afin de bénéficier de toute leur puissance. Nous verrons tour à tour :

C . 3 . 1 - Les Strings et Arrays

Comme nous le savons déjà, une condition pourra être donnée sous la forme d'une chaîne de caractères ou un array. Si elle est donnée en tant que chaîne de caractères, elle doit être syntaxiquement correcte du point de vue SQL.

# Les deux conditions suivantes sont équivalentes
$cond1 = "column1 = 2 OR column2 = 'une chaîne'";
$cond2 = array (
  "column1" => 2,
  "column2" => "une chaîne"
);

/*  Les deux conditions suivantes sont aussi équivalentes.
 *  L'utilisation de OR et AND sera expliquée en détails
 *  dans la suite.
 */
$cond3 = "column1 = 2 OR ( column3 = column2 AND column1 = 5 )";
$cond4 = array
(  "column1" => 2,
   'AND' => array
   (   "column3" => "#column2",
       "column1" => 5
   )
);

L'utilisation des expressions permet de créer des conditions puissantes de manière très simples. Comme cela a été vu dans la section des expressions , dans une condition ou une liste de sélection de type array, chaque clé ainsi que chaque valeur du tableau peuvent être une expression. Une condition SQL du genre  col1 + col2 = 10   peut s'écrire de plusieurs manières:

/*  Les 3 variables suivantes, utilisées comme
 *  conditions sont toutes équivalentes
 */
$cond1 = "col1 + col2 = 10";
$cond2 = array(
   "#col1 + col2" => 10
);
$cond3 = array(
   "#col1 + col2" => "#10"
);

Nous l'avons déjà signalé auparavant, toute clé de type string qui n'est pas une expression est considérée comme un nom de colonne, et est donc automatiquement protégé par WDB. Toute valeur de type string possédant une clé valable (non entière, ou entière négative) est considérée comme une chaine SQL

$db->select
(  "MyTable",
   "*",
   array(
      "30*45" => "product",  /* 30*45 est interprété comme nom de colonne */
                             /* "product" est considéré comme une chaîne SQL */
      "COS(45)" => "cos"     /* COS(45) est interprété comme nom de colonne */
                             /* "cos" est interprété comme une chaîne SQL */
   )
);

Si on travaille sous MYSQL, l'instruction précédente génère donc le code SQL suivant:

SELECT * FROM MyTable WHERE (`30*45`='product' OR `COS(45)`='cos') 

Assez aberrant comme code, il faut le reconnaitre ! Enfin. . . Sauf évidemment si la table MyTable contient vraiment les colonnes `30*45` et `COS(45)`, et que les deux sont du type CHAR(n) ou VARCHAR.

C . 3 . 2 - Les autres valeurs

Une condition peut aussi valoir FALSE, NULL ou "" (chaîne vide). Fournir une de ces valeurs là où une condition est requise équivaudrait aussi, du point de vue de WDB à ne fournir aucune condition. Mais ce genre de valeur ne passera pas partout. Cela provoquera une erreur, dans les fonctions WDB -> update() et WDB -> delete() . Partout ailleurs cela équivaudrait à une condition toujours vraie.

Une condition peut aussi prendre une valeur numérique. Elle est alors évaluée à FALSE si le nombre vaut 0, et TRUE sinon.

<?php
/*  Les 4 appels suivants sont tous équivalents, et sélectionnent
 *  pour tous les étudiants de la table "etudiant" les colonnes
 *  "studid", "nom", et "prenom" .
 */
$db -> select("etudiant", "studid, nom, prenom");

$db -> select("etudiant", "studid, nom, prenom", false);

$db -> select("etudiant", "studid, nom, prenom", 1);

$db -> select("etudiant", "studid, nom, prenom", "");

/*  L'instruction suivante par contre ne sélectionne rien
 */
$db -> select("etudiant", "studid, nom, prenom", 0);
?>

C . 3 . 3 - Association clé-valeur

C'est la façon dont une valeur et sa clé sont jumelées. Nous le savons, une condition de type array est analysée et traitée afin d'obtenir une condition de type chaîne de caractères. C'est la condition effective. Celle-ci est obtenue par l'association de chaque clé avec sa valeur au moyen d'un opérateur donné, qui par défaut est l'opérateur = (égal) . La valeur PHP NULL est automatiquement mappée en un NULL SQL . Les explications esquissées ici seront complétées par celles apportées sous la rubrique Arrays sous-jacents et listes de valeurs .

/*  Formation de la condition finale. Chaque clé (colonne de table)
 *  est associée à la valeur correspondante, au moyen de l'opérateur = 
 *  pour former une une partie de la condition finale.
 */
$cond = array (
   "colonne_1"	=> 5,         # colonne_1 = 5
   "colonne_2"	=> "chaîne",  # colonne_2 = 'chaîne'
   "colonne_3"	=> null       # colonne_3 IS NULL
);

/*  Les différentes parties sont jointes ensemble au moyen de
 *  l'opérateur OR ( par défaut ) pour former la condition effective.
 */
$cond_eff = "(colonne_1 = 5) OR (colonne_2 = 'chaîne') OR (colonne_3 IS NULL)";

Nous en avons parlé auparavant, les clés entières positives ou nulles ne sont pas prises en compte dans la formation de la condition effective. Comme nous le verrons après, ce comportement rend possible l'utilisation des listes de valeurs. À partir de maintenant et dans la suite, nous entendrons par clé valable dans une condition, toute clé non entière, ou entière et strictement négative.

/*   Ceci n'est qu'un exemple bidon.
 *
 *   La condition effective n'est pas ce qu'on pourrait imaginer,
 *   c'est-à-dire   (0 = val1) OR (10 = val2) OR (-5 = val3)
 */

$cond = array (
   0	=> val1,   # 0 ne sert à rien
   10	=> val2,   # 10 ne sert à rien non plus
   -5	=> val3    # -5 est utilisé car négatif
);

/*  Voici comment WDB voit cette condition */
$cond = array (
   val1,
   val2,
   -5	=> val3
);

/*  Si bien que la condition effective sera comme on le voit ci-dessous.
 *  Ainsi donc, pour que cette condition (donnée sous forme d'array ou de 
 *  String) fonctionne, il faudrait que val1 et val2 soient des expressions
 *  booléennes SQL syntaxiquement valides
 */
$cond_eff = "val1 OR val2 OR -5 = val3"

C . 3 . 4 - Utilisation de OR et AND

OR est l'opérateur par défaut pour joindre les parties entre elles pour former la condition effective. Pour utiliser AND à la place, il suffit de le placer comme premier élément de la condition. Sa casse est sans importance. WDB le détecte et l'utilise à la place.

$cond = array (
	"AND",			# AND devient l'opérateur de jonction
   "colonne_1"	=> 5,		# colonne_1 = 5
   "colonne_2"	=> 8,		# colonne_2 = 8
   "colonne_3"	=> "chaîne"	# colonne_3 = 'chaîne'
);

/*  Les différentes parties sont jointes maintenant au
 *  moyen de l'opérateur AND pour former la condition effective.
 */
$cond_eff = "(colonne_1 = 5) AND (colonne_2 = 8) AND (colonne_3 = 'chaîne')";

Alternativement, on pourra utiliser l'un des opérateurs 'AND' ou 'OR' comme clé d'un sous-tableau pour que cet opérateur soit utilisé comme opérateur de jonction dans ce sous-array. La condition suivante est donc équivalente à la précédente:

$cond = array
(  "AND" => array
    (  "colonne_1"  => 5,       # colonne_1 = 5
       "colonne_2"  => 8,       # colonne_2 = 8
       "colonne_3"  => "chaîne" # colonne_3 = 'chaîne'
    )
);

C . 3 . 5 - Arrays sous-jacents et listes de valeurs

Une clé peut pointer sur une valeur unique, mais aussi sur un array. La façon dont la clé va se combiner à cet array est expliquée par un exemple :

$cond = array (
	"AND",
  "colonne_1"	=> 5,		# colonne_1 = 5
  "colonne_2"	=> 8,		# colonne_2 = 8
  "colonne_3"	=> array(	# cet array est une liste de valeurs
	1,	# colonne_3 = 1
	10,	# colonne_3 = 10
  )
);

/*  La condition finale donne ceci */
$cond_eff = '(colonne_1 = 5) AND (colonne_2 = 8) AND
             (colonne_3 = 1 OR colonne_3 = 10)';

Les listes de valeurs et autres arrays sous-jacents peuvent aussi recevoir l'opérateur AND comme premier élément, afin que celui-ci soit utilisé comme opérateur de jonction.

$cond = array (
	"AND",
  "colonne_1"	=> 5,
  "colonne_2"	=> 8,
  "colonne_3"	=> array("AND", 1, 10)
);

/*  La condition finale donne ceci */
$cond_eff = '(colonne_1 = 5) AND (colonne_2 = 8) AND
             (colonne_3 = 1 AND colonne_3 = 10)';

Les arrays peuvent être imbriqués les uns dans les autres autant que nécessaire. Ils ne doivent pas nécessairement être une liste de valeurs. Voici comment se déroule l'opération:

$cond = array (
       "AND",
  "colonne_1"	=> 5,      # colonne_1 = 5
  "colonne_2"	=> 8,      # colonne_2 = 8
  "colonne_3"	=> array
   (   1,                  # colonne_3 = 1
       10,                 # colonne_3 = 10,
       "colonne_4" => 5    # colonne_4 = 5
   )
);

/*  La condition finale donne ceci */
$cond_eff = '(colonne_1 = 5) AND (colonne_2 = 8) AND
             (colonne_3 = 1 OR colonne_3 = 10 OR colonne_4 = 5)';

Un sous-array ne doit pas nécessairement avoir une clé. Il faut alors que chaque valeur de ce sous-array puisse avoir une clé ou alors, qu'il y ait une clé plus haut placée dans la hiérarchie pour servir de remplacement au cas où une valeur manquerait de clé.

$cond = array (
	"AND",
  "colonne_1"	=> 5,
  "colonne_2"	=> 8,
  array
   (    "colonne_3" => 1,
        "colonne_4" => 10,
        "colonne_5" => 5
   )
);

/*  La condition finale donne ceci */
$cond_eff = '(colonne_1 = 5) AND (colonne_2 = 8) AND
             (colonne_3 = 1 OR colonne_4 = 10 OR colonne_5 = 5)';

Si une sous-array n'a pas besoin d'être indexée avec une clé, on peut préciser l'opérateur de jointure à l'extérieur de celui-ci, comme cela est montré dans l'exemple suivant:

/* Les deux conditions suivantes sont équivalentes */
$cond_1 = array
(   "colonne_1"	=> 5,
    "colonne_2"	=> 8,
    "AND" => array
     (    "colonne_3" => 1,
          "colonne_4" => 10
     )
);
$cond_2 = array
(   "colonne_1"	=> 5,
    "colonne_2"	=> 8,
    array
     (    "AND",
          "colonne_3" => 1,
          "colonne_4" => 10
     )
);

Une condition de type array peut contenir des expressions en tant que clé ou valeur.

$cond = array
(       "AND",
   "#colonne_1 + 2" => "#5",    // colonne_1 + 2 = 5
   "colonne_2"	    => 8,       // colonne_2 = 8
   "colonne_3"	    => "#colonne_1-10",  // colonne_3 = colonne_1 - 10
   "colonne_4"  => array
   (   1,    # colonne_4 = 1
      10,    # colonne_4 = 10
   )
);

E . 3 . 6 - Les opérateurs de comparaison

Ce que nous avons fait jusque-là c'est combiner une clé avec sa valeur au moyen de l'opérateur égal ( = ), qui est l'opérateur de comparaison par défaut. Nous savons bien qu'il en faut plus que cela pour construire des conditions. Un opérateur pourra être placé au choix, quand cela est possible, à droite de la clé ou à gauche de la valeur.

$cond = array (  
	"AND",
  "colonne_1 >"	=> "5",		// `colonne_1` > '5'
  "colonne_2"	=> "<> 8",	// `colonne_2` <> '8'
  "colonne_3 <"	=> array(
	1,	// `colonne_3` < 1
	10,	// `colonne_3` < 10
  )
);

/*  Sous MYSQL par exemple, la condition finale donne ceci: */
$cond_eff = '(`colonne_1` > '5') AND (`colonne_2` <> '8') AND
             (`colonne_3` < 1 OR `colonne_3` < 10)';

Tous les opérateurs de comparaison

opérateur rôle opérateur rôle
= égalité [] appartenance à un intervalle fermé
== égalité intrinsèque [[ appartenance à un intervalle fermé à gauche et ouvert à droite
> supérieur ]] appartenance à un intervalle ouvert à gauche et fermé à droite
< inférieur ][ appartenance à un intervalle ouvert
>= supérieur ou égal ![] non appartenance à un intervalle fermé
<= inférieur ou égal ![[ non appartenance à un intervalle fermé à gauche et ouvert à droite
<>   != différent !]] non appartenance à un intervalle ouvert à gauche et fermé à droite
!== différence intrinsèque !][ non appartenance à un intervalle ouvert
~   LK LIKE BTW BETWEEN
!~ NOT LIKE !BTW NOT BETWEEN
IN IN !IN NOT IN

Les opérateurs IN et !IN ne peuvent être appliqués que sur une liste de valeurs. Les opérateurs pour intervalles ainsi que BTW et !BTW s'appliquent uniquement sur une liste de 2 valeurs. Les opérateurs == et !== ont la distinction de pouvoir comparer deux NULL entre eux, ce que ne peuvent faire = et <>

L'exemple suivant doit vous permettre d'appréhender l'utilisation des opérateurs.

$cond = array(
  "col_1 >"   => 5,           # l'opérateur peut être à gauche à la fin
  "col_2"     => "<= 10",     # ou à droite au début, si c'est faisable
  "col_3 ~"   => "mot",       # col_3 LIKE 'mot'

  "col_4 =="  => "#col_3",    # compare col_4 et col_3, même si les deux sont NULL
  "col_5 IN"  => [2, 4, 6],   # col_5 IN (2, 4, 6)
  "col_3 !IN" => ["ok","no"], # col_3 NOT IN ('ok', 'no')

  "col_1 BTW" => [4, 10],     # col_1 BETWEEN 4 AND 10
  "col_2 []"  => [1, 5],      # col_2 >= 1 AND col_2 <= 5
  "col_2 ]["  => [1, 5],      # col_2 > 1 AND col_2 < 5

  "col_2 [["  => [1, 5],      # col_2 >= 1 AND col_2 < 5
  "col_2 ]]"  => [1, 5],      # col_2 > 1 AND col_2 =< 5
);

Si le hashtag # doit être utilisé en conjonction avec un opérateur de comparaison, l'opérateur viendra en premier, le hashtag en second, comme illustré dans l'exemple suivant:

$cond = array (
   "col_4"  => "< #col_3",      /* col_4 < col_4 */
   "col_1"  => "> # 3*col_5"    /* col_1 > 3 * col_5 */
);

😕 Quand l'opérateur est placé avec la clé il ne doit venir aucun caractère blanc après lui. De même lorsqu'il est placé au début de la valeur, il ne doit venir aucun caractère blanc avant lui. Si cette situation se produit, l'opérateur n'est simplement pas considéré comme tel.

$cond = array(
   "col1 <"   =>  5,   # OK
   "col2 > "  => 10,   # non
   "col3"     =>  "= string",   # OK
   "col4"     =>  " = string2", # non
);

Dans ce dernier exemple, la chaîne "col2 > " sera considérée comme un nom de colonne, et sera donc protégée comme telle. De même, la chaîne  " = string2" est considérée comme une chaîne SQL. Dans les deux cas c'est l'opérateur = qui sera utilisé.

Les caractères blancs entre le nom de la clé et l'opérateur, tout comme ceux entre l'opérateur et la valeur ne comptent pas. Si ces caractères blancs doivent être pris en compte on peut par exemple faire ceci

$cond = array(
   "[col1  ] <" =>  5,              /* `col1  ` < 5 */
   "col2"      =>  ">#{  string }"  /* `col2` > '  string ' */
);
// ou bien
$cond = array(
   "[col1  ] <" =>  5,          /* `col1  ` < 5 */
   "col2 >"    =>  "  string "  /* `col2` > '  string ' */
);

Les opérateurs de comparaisons sont nombreux et une de vos chaines peut facilement en avoir au début. Pour éviter que ce genre de situation ne crée des problèmes, vous pouvez par exemple bloquer la détection des opérateurs dans les valeurs (à droite) et utiliser uniquement les opérateurs dans les clés des tableaux (à gauche).

# On ignore les opérateurs de droite
$db->value_operators = false;
$cond = array(
   "col2" => "[] est un opérateur",
   "col1" => "> est un autre opérateur"
);
$db->select("mytable", "*", $cond);

De cette façon, les opérateurs qui pourraient se trouver dans nos chaines de droites ne sont plus pris en compte. Si nécessaire, on peut décider d'ignorer aussi tous les opérateurs qui pourraient se trouver dans les clés:

$db->key_operators = false;

C . 4 - Mise à jour des données

Dans cette partie, nous verrons tour à tour les points suivants:

Dans la suite nous fournirons quelques exemples. Nous utiliserons de temps à autre notre base de données de tout à l'heure. Dans la table "etudiant", nous avons plusieurs dizaines de lignes dont les premières sont les suivantes:

studid nom prenom sexe ndate classid
1 Amadou Kingue 'M' 2007/08/27 5
2 Sanamo Steve 'M' 2008/01/01 5
3 Akanato Steffie 'F' 2005/05/15 3
4 Malik Stan 'm' 2006/09/25 1
5 Cheneau Stella 'f' 2007/12/27 4
6 Christina De Agua 'F' 2008/07/14 4
. . . . . . . . . . . . . . . . . .

C . 4 . 1 - Pseudo Active record

Nous avons esquissé une première utilisation du Pseudo Active record dans la partie Chargement par Pseudo Active record, mais certaines notions n'ont pas été totalement clarifiées. Nous savons déjà que nous avons besoin d'un objet WDBRow pour toute manipulation, objet qu'on peut obtenir de l'une des manières suivantes:

$row = $db->row($tableName, $keyName);
$row = $db->row($tableName, $keyName, $keyValue);

Une fois que l'objet WDBRow est obtenu, on peut lui ajouter des propriétés à souhait, leur affecter des valeurs comme on le désire. Ces propriétés doivent être des noms de colonnes existant dans la DB.

Dans l'exemple suivant, nous allons changer le nom, prenom et l'email d'un utilisateur dont l'ID (colonne userid, primary key) vaut 10. Dans la DB il est question des colonnes "nom", "prenom" et "email".

$row = $db->row("users", "userid", 10);
$row->nom = "Un nouveau nom";
$row->prenom = "Un nouveau prenom";
$row->email = "new_mail@mail.com";
if( $row->update() ) echo "Mise à jour éffectuée";
else echo "La mise à jour à échoué";

Comme WDB n'a aucune connaissance de la structure de la DB, l'objet WDBRow acceptera toutes les propriétés qu'on voudra bien lui ajouter. Mais si quelques-unes de ces proprétés ne correspondent pas à des colonnes dans la DB, ou si leur valeur ou leur type est erroné, l'erreur n'apparaitra qu'à l'exécution des requêtes.

Comme cela a été dit auparavant, s'il y a besoin d'un traitement de données avant enregistrement, on pourra charger les données voulues dans l'entité WDBRow avec la fonction WDBRow->load.

Comme vous pouvez l'imaginer, dans le cas d'une mise à jour, on doit faire connaitre à WDBRow la valeur de la colonne UNIQUE (ou clé) d'une manière ou d'une autre. Cela peut se faire à l'instanciation, au chargement des données ou par affectation directe.

# Au moment de l'instanciation
$row = $db->row("etudiant", "studid", 3);
# Au moment du chargement de données
$row = $db->row("etudiant", "studid");
$row->load(3, "nom, prenom, sexe");
# Par affectation
$row = $db->row("etudiant", "studid");
$row->studid = 3;

Dans le cas d'une clé composite, voir la partie Chargement par Pseudo Active record

L'objet WDBRow peut servir plus d'une fois, et cela sur la même table ou des tables differentes.

# Instanciation et première utilisation
$row = $db->row("etudiant", "studid", 3);
$row->prenom = "Steffie Mary";
$row->ndate = "2005/06/15";
if( $row->update() ) echo "Première mise à jour réussie";
else echo "Échec de la première mise à jour";
/*  Deuxième utilisation. Nous allons éditer les
 *  données d'un autre etudiant avec le même objet.
 *  Nous commencons d'abord par effacer les données
 *  utilisées jusque-là, et on fixe le nouvel ID
 */
$row->deleteData(); $row->studid = 6;
$row->sexe = "M"; $row->nom = "Christens";
if( $row->update() ) echo "Deuxième mise à jour réussie";
else echo "Échec de la deuxième mise à jour";
/*  Troisième utilisation, avec la table "users"
 *  dont la clé est "userid". Nous modifions quelques
 *  données de l'utilisateur dont le ID est 15
 */
$row->init("users", "userid", 15);
$row->nom = "Maus";  $row->email = "new_email@mail.com";
if( $row->update() ) echo "Troisième mise à jour réussie";
else echo "Échec de la troisième mise à jour";

La fonction WDBRow->deleteData() efface toutes les propriétés (nom de colonnes) et valeurs affectées à l'objet, à l'exception des noms de la table et de la clé. La valeur de la clé est aussi effacée.

La fonction WDBRow->init() re-initialise complètement l'objet. Les colonnes et leurs valeurs, ainsi que les noms de la table et de la clé sont effacés. Les noms de la nouvelle table et de la clé de celle-ci, ainsi que la possible valeur de la nouvelle clé doivent être renseignés.

L'objet WDBRow ne soulève normalement pas d'exceptions, et n'affiche pas de messages d'erreur. Si on veut le message d'erreur après une instruction ratée, on appellera WDBRow->error()

C . 4 . 2 - La fonction wdb->update()

La fonction wdb->update() permet de mettre à jour des données et admet deux signatures qui correspondent à deux situations bien différentes:  le cas où on a besoin de mettre à jour plusieurs lignes en utilisant les mêmes données et une condition. Et le cas où on veut mettre à jour un certain nombre de lignes avec des données individuelles, en utilisant la valeur de la clé pour cibler chaque ligne.

$db -> update ( $table, $data,  $where )

$db -> update ( $table$key$rows_list )

Les paramètres

$table :  nom de la table

$data : array sous forme clé-valeur

$where : une condition

$key : nom de la clé

$rows_list : liste des elements

en tant qu'array:    array ( $data_1, $data_2, . . ., $data_n )
en tant que params:   $data_1, $data_2, $data_n

C . 4 . 3 - Exemples

Dans la table "etudiant" esquissée en haut, nous voyons que la colonne "sexe" n'est pas normalisée. La valeur est tantôt en majuscule, tantôt en minuscule. Nous voulons mettre le sexe en majuscule, sachant que notre table contient des dizaines de lignes. Nous ne connaissons donc pas à priori toutes les lignes à éditer. Nous utilisons ainsi une condition pour le faire. Pour les filles dont le sexe vaut 'f', nous mettons 'F' et pour les garçons dont le sexe vaut 'm' nous mettons 'M'. Nous faisons cela en 2 étapes mais en une seule instruction.

$db -> update
( 'etudiant',
   array( 'sexe' => "F" )  # données à affecter, equivaut à  SET sexe='F'
   array( 'sexe' => "f")   # condition, equivaut à  WHERE sexe='f'
)
-> update
( 'classe',
   array( 'sexe' => "M" )
   array( 'sexe' => "m")
);

Nous voulons maintenant mettre à jour les données de quelques étudiants. Les nouvelles données à consigner dans la base de données sont les suivantes:

Nous utilisons la 2e signature de la fonction wdb :: update() . Nous avons juste besoin d'une table ayant une colonne de type UNIQUE. Chaque ensemble de données à enregistrer doit absolument posséder cette colonne. C'est sa valeur qui permet de cible une ligne de la table.

/*   Dans cet appel de la fonction update il n'y a pas d'obligation
 *   que les arrays de données aient le même nombre, ni les mêmes
 *   noms de colonnes, comme cela est le cas dans une instruction
 *   SQL normale.
 */
$db -> update
( 'etudiant',
  'studid',
   array
   (   array
       (  "studid" => 1,
          "prenom" => "Kinley",
          "classid" => 4
       ),
       array
       (  "studid" => 2,
          "prenom" => "Stevie",
          "sexe" => "F"
       ),
       array
       (  "studid" => 6,
          "nom" => "De Agua",
          "prenom" => "Christine",
          "ndate" => "2008/07/14"
       )
   )
);
/*  Les arrays de données peuvent aussi directement être
 *  passés les uns à suite des autres comme suit:
 */
$db -> update
( 'etudiant',
  'studid',
   array
   (  "studid" => 1,
      "prenom" => "Kinley",
      "classe" => 4
   ),
   array
   (  "studid" => 2,
      "prenom" => "Stevie",
      "sexe" => "F"
   ),
   array
   (  "studid" => 6,
      "nom" => "De Agua",
      "prenom" => "Christina",
      "ndate" => "2008/07/14"
   )
);

C . 4 . 4 - Les opérations unaires

Pour permettre la création simple et plus efficace des condition, WDB permet l'utilisation des opérateurs unaires suivants:   +=, *=, -=, *=,  .=     Leur utilisation se fait comme dans cet exemple:

$db->update
(  "table",
    array
    (  "colonne1 +=" => 3,    #  SET colonne1 =  colonne1 + 3
       "colonne2 *=" => 5,    #  SET colonne1 =  colonne2 * 3

       "colonne3 /=" => "#colonne4",    #  SET colonne3 =  colonne3 / colonne4
       "colonne5 -=" => "#colonne6",    #  SET colonne5 =  colonne5 / colonne6
       "colonne7 .=" => "un mot",       #  SET colonne7 =  CONCAT(colonne7, 'un mot')
       "colonne8 .=" => "#colonne9",    #  SET colonne8 =  CONCAT(colonne8, colonne9)
    ),
    $condition
);

Cet exemple ne sert que d'illustration. Dans la pratique, la fonction CONCAT() n'est pas nécessairement supportée par tous les SGBDs pris en charge. WDB se charge d'appliquer la fonction ou l'opérateur adéquat pour le SGBD installé. Quelques notions et explications supplémentaires concernant l'utilisation de l'hashtag sont à trouver dans la partie Hashtag et expressions

C . 5 - Insertion et suppression des données

C . 5 . 1 - Insertion par Pseudo Active record

L'insertion se passe plus ou moins de la même manière que la mise à jour, à 2 détails près: L'instanciation de l'objet WDBRow doit se faire sans valeur de la clé, et l'enregistrement doit se faire non pas avec la fonction update() mais avec la fonction insert()

/*  Nous ajoutons un étudiant dans la DB */
$row = $db->row("etudiant", "studid");
$row->nom = "De Chevalier";
$row->prenom = "Jean-Claude";
$row->sexe = "M";
$row->ndate = "2000/04/05";
$row->classid = 3;
if($row->insert()) echo "Étudiant ajouté avec succès. Son ID: " . $row->studid;
else echo "L'ajout a échoué. Erreur: " . $row->error();

/*  Nous ajoutons un autre étudiant. Nous devons d'abord vider l'objet avec
 *  la fonction WDBRow->deleteData() . Nous ajoutons ensuite les données avec
 *  WDBRow->set() et sauvegardons dans la DB en testant l'erreur avec la valeur
 *  la fonction insert(). Toutes ces fonctions peuvent être appelées une à une,
 *  mais elles peuvent aussi être chaînées comme ci-dessous:
 */
if($row->init()       # cette fonction renvoie le même objet $row
   ->set(array(       # cette fonction renvoie aussi le même objet $row
      "nom" => "Nkoo",
      "prenom" => "Emilienne",
      "sexe" => "F",
      "ndate" => "2002/12/08",
      "classid" => 1,
  ))->insert()         # cette fonction renvoie un booléen
) echo "Étudiant ajouté avec succès. Son ID: " . $row->studid;
else echo "L'ajout a échoué. Erreur: " . $row->error();

Si votre table contient une clé primaire auto-générée, elle ne devrait normalement pas faire partie des données, car certains SGBDs ne le supportent pas. Beaucoup d'autres supportent cela. À vous donc de voir.

C . 5 . 2 - Insertion avec la fonction wdb->insert()

La fonction wdb -> insert() permet d'ajouter des lignes dans une table de la BD. Son alias est wdb -> add() et sa signature est la suivante:

$db -> insert ( $table,  $rows_list )

Les paramètres

$table :  le nom de la table

$rows_list : Liste des éléments à ajouter, chacun étant un array

Array:    array ( $dataset_1,  $dataset_2, . . ., $dataset_n )
Params:   $dataset_1,  $dataset_2, . . ., $dataset_n

Résultat : Le même objet WDB

Ajoutons d'autres étudiants dans la base, en supposant comme précédemment que la colonne studid est auto-générée ( auto_increment, serial ou autre, comme on voudra ). Cela veut dire que la colonne studid ne sera pas dans les données.

/*  Les donnés des différentes lignes à ajouter peuvent être
 *  fournies les unes après les autres comme ici, ou mappées
 *  toutes dans un unique array de arrays.
 */
$db -> insert
( 'etudiant',
   array
   (  "nom" => "Arama",
      "prenom" => "Cirus",
      "sexe" => "M",
      "ndate" => "2008/08/05",
      "classid" => 8
   ),
   array
   (  "nom" => "De Boeuf",
      "prenom" => "Philipp",
      "sexe" => "M",
      "ndate" => "2009/10/28",
      "classid" => 5
   ),
   array
   (  "nom" => "Müller",
      "prenom" => "Anton",
      "sexe" => "F",
      "ndate" => "2007/12/25",
      "classid" => 4
   )
);

C . 5 . 3 - Suppression des données

La fonction wdb -> delete() permet d'éliminer des données dans une table de la BD. Cette fonction renvoie le même objet WDB, rendant possible le chaînage des fonctions.

Dans les exemples suivants nous voulons supprimer de la table etudiant les étudiants dont les numéros d'ID sont 5, 15 et 20. Les IDs sont uniques, et correspondent aux valeurs de la colonne studid

Une manière de supprimer les données est d'utiliser la fonction studid avec une condition. Toutes les colonnes vérifiant la condition sont supprimées.

$table = "etudiant";
$cond = array
(  "studid" => 5,
   "studid" => 10,
   "studid" => 20,
);
$db->delete( $table, $cond );

Une autre manière de supprimer les données est d'utiliser une colonne UNIQUE de la table si elle existe. Il pourrait s'agir d'une colonne PRIMARY KEY, mais elle peut aussi être une colonne quelconque. Elle doit juste avoir des valeurs uniques. Dans notre exemple, la colonne studid contient justement des valeurs uniques. Il reste juste à passer à la fonction delete() le nom de la table, celui de la colonne UNIQUE et la liste des valeurs pour lesquelles on souhaite supprimer les lignes.

$table = "etudiant";
$uniq_column = "studid";
$list_values = array(5, 10, 20);

$db->delete( $table, $uniq_column, $list_values );

Il n' y a pas d'obligation de mettre les valeurs dans un array comme nous venons de le faire. Elles peuvent aussi être listées les unes à la suite des autres après le nom de la colonne UNIQUE.

$table = "etudiant";
$uniq_column = "studid";

$db->delete( $table, $uniq_column, 5, 10, 20 );

Cette manière est commode et directe. Par exemple si on avait juste voulu éliminer l'étudiant dont le ID vaut 5 :

$db->delete( "etudiant", "studid", 5 );

La bonne nouvelle c'est que les clés multi-colonnes sont supportées. Ce qui dans les détails veut dire ceci : Il se peut que votre table ne possède pas de colonne dont les valeurs individuelles sont uniques, mais possède quelques colonnes dont les valeurs, une fois combinées, forment toujours un ensemble unique. On peut mettre à profit ce genre de situation pour éliminer des données.

Supposons, juste pour les besoins de cet exemple, que dans notre table etudiant, le nom, le prénom et la classe puissent identifier un étudiant de façon unique.

Nous voulons éliminer deux étudiants dont les données sont les suivantes:

nom: Malik - prenom: Stan  - classid: 1
nom: Christina - prenom: De Agua - classid: 4

$table = "etudiant";
$key = array("nom", "prenom", "classid");
$list_values = array(
   array("Malik", "Stan", 1),
   array("Christina", "De Agua", 4)
);

$db->delete( $table, $key, $list_values );

Ou plus simplement comme suit:

$db->delete( "etudiant", array("nom", "prenom", "classid"), 
  array("Malik", "Stan", 1), array("Christina", "De Agua", 4)
);

Mais si on avait voulu utiliser une condition:

$db->delete(
   "etudiant",
    array(
      array("AND", "nom" => "Malik", "prenom" => "Stan", "classid" => 1),
      array("AND", "nom" => "Christina", "prenom" => "De Agua", "classid" => 4)
    )
);

WDB vous offre toutes les possibilités, à vous de voir ce qui vous convient.

E Autres notions importantes


E . 1 - Paramètres de requête

Nous en avions pas parlé jusqu'à présent, mais WDB supporte bien les paramètres de requête. Il se peut que vous n'en ayez peut-être pas besoin, car WDB se charge en général de tout. Considérons la requête suivante:

$db -> insert
( 'classe',
   array
   (  "nom" => "Arama",
      "prenom" => "Cirus",
      "sexe" => "M",
      "ndate" => "2008/08/05",
      "classid" => 8
   )
);

En interne, WDB transforme automatiquement les valeurs de cette instruction en paramètres PDO, si bien qu'on n'a pas besoin, même si les données proviennent d'une souce tierce, de les passer soi-même en tant que paramètres PDO.

E . 1 . 1 - Où et comment utiliser les paramètres PDO

Il peut cependant avoir des situations où il est nécessaire de manipuler des paramètres de requête. Dans des cas par exemple où nous devons écrire une requête de manière directe dans une chaîne de caractères. Prenons un cas simple d'insertion dans la table "classe" . On pourrait le faire d'une façon très directe comme suit:

$db->query
( "INSERT INTO classe (nom, prenom, sexe, ndate, classid)".
  "VALUES ('Arama', 'Cirus', 'M', '2008/08/05', 8)"
);

La fonction WDB->query() permet d'exécuter une requête quelconque. Si nous ne connaissons pas a priori les données utilisées, ou si celles-ci proviennent d'une source tierce, cette manière de procéder est extrêmement dangereuse, et devrait en production être évitée à tout prix! Nous allons écrire la même instruction en utilisant nos paramètres PDO:

$db->query
( "INSERT INTO classe (nom, prenom, sexe, ndate, classid)".
  "VALUES (:nom, :prenom, :sexe, :date, :classid)"
)
->bind
(  array
   (  ":nom"     => "Arama",
      ":prenom"  => "Cirus",
      ":sexe"    => "M",
      ":ndate"   => "2008/08/05",
      ":classid" => 8,
   )
);

Dans cette instruction nous utilisons les paramètres nommés :name, :prenom :sexe, :ndate et :classid auxquels nous donnons respectivement les valeurs "Arama", "Cirus", "M", "2008/08/05" et 8.

La fonction wdb->bind() permet ainsi d'affecter des valeurs aux paramètres PDO. Cette affectation peut se faire en vrac comme ci-dessus, ou paramètre après paramètre comme ci-après:

/*  L'instruction suivante est alors équivalente à la précédente.
 *  Le 3e paramètre de wdb->bind() est optionnel, et indique le
 *  type de paramètre PDO.
 */
$db->query
( "INSERT INTO classe (nom, prenom, sexe, ndate, classid)".
  "VALUES (:nom, :prenom, :sexe, :date, :classid)"
)
->bind(":name", "Arama", PDO::PARAM_STR)
->bind(":vorname", "Cirus")
->bind(":sexe", "M")
->bind(":ndate", "2008/08/05")
->bind(":classid", 8, PDO::PARAM_INT);

Vous l'aurez remarqué, après l'appel de la fonction wdb->bind() dans la première instruction, ainsi qu'après les 5 appels de la fonction wdb->bind() dans la seconde instruction, nous n'avons pas besoin de faire quoi que ce soit d'autre. La fonction bind exécute automatiquement l'instruction quand tous les paramètres PDO ont reçu une valeur.

La fonction bind s'utilise donc de 2 manières:

/*  Quand on donne la valeur d'un seul paramètre */
wdb->bind($param, $value[, $pdo_type]);
/*  Ou quand on donne les valeurs de plusieurs paramètres */
wdb->bind($params[, $pdo_types]);

Dans cette dernière signature, si $pdo_types est fourni, il sera un array dont les clés sont des noms des paramètres PDO, et les valeurs sont des types PDO (PDO::PARAM_STR, PDO::PARAM_INT, ...) . C'est le type d'un paramètre qui indique à PDO comment la valeur du paramètre sera traitée. Voici comment WDB assigne le type d'un paramètre lorsque celui-ci n'est pas fourni explicitement:

On peut donc écrire le dernier exemple de la manière suivante:

$db->query
( "INSERT INTO classe (nom, prenom, sexe, ndate, classid)".
  "VALUES (:nom, :prenom, :sexe, :date, :classid)"
)
->bind
(  array
   (  ":name"    => "Arama",
      ":vorname" => "Cirus",
      ":sexe"    => "M",
      ":ndate"   => "2008/08/05",
      ":classid" => 8,
   ),
   array
   (  ":name"    => PDO::PARAM_STR,
      ":classid" => PDO::PARAM_INT
   )
);

Si les paramètres PDO doivent être utilisés dans un array de données ou dans un array qui doit servir de condition, cela sera fait dans le contexte des expressions!

L'exemple suivant va échouer:

/*  Les valeurs ":name", ":vorname", ":sexe", ":ndate" et
 *  ":classid" sont toutes interprétées comme des chaines de
 *  caractères simples, non comme des noms de paramètres PDO.
 */
$db -> insert
( "classe",
   array
   (  "nom"     => ":name",
      "prenom"  => ":vorname",
      "sexe"    => ":sexe",
      "ndate"   => ":ndate",
      "classid" => ":classid"
   )
)
->bind
(  array
   (  ":name"    => "Arama",
      ":vorname" => "Cirus",
      ":sexe"    => "M",
      ":ndate"   => "2008/08/05",
      ":classid" => 8,
   )
);

Il faudrait utiliser les expressions pour que cela fonctionne:

/*  Les valeurs ":name", ":vorname", ":sexe", ":ndate" et ":classid"
 *  sont interprétées maintenant comme des noms de paramètres PDO.
 */
$db -> insert
( "classe",
   array
   (  "nom"     => "#:name",
      "prenom"  => "#:vorname",
      "sexe"    => "#:sexe",
      "ndate"   => "#:ndate",
      "classid" => "#:classid"
   )
)
->bind
(  array
   (  ":name"    => "Arama",
      ":vorname" => "Cirus",
      ":sexe"    => "M",
      ":ndate"   => "2008/08/05",
      ":classid" => 8,
   )
);

E . 1 . 2 - Paramètres nommés et anonymes simultanés

Avec WDB, vous n'êtes pas limités aux paramètres nommés uniquement. L'exemple suivant d'insertion avec des paramètres anonymes fonctionne parfaitement:

$db -> insert
( "classe",
   array
   (  "nom"     => "#?",
      "prenom"  => "#?",
      "sexe"    => "#?",
      "ndate"   => "#?",
      "classid" => "#?"
   )
)
->bind
(  array
   (  1  => "Arama",
      2  => "Cirus",
      3  => "M",
      4  => "2008/08/05",
      5  => 8,
   )
);

Cet exemple nécessite peut-être quelques explications: PDO compte les paramètres anonymes à partir de 1 et en montant. Ainsi, notre instruction INSERT comporte 5 paramètres anonymes, identifiés comme suit:

$db -> insert
( "classe",
   array
   (  "nom"     => "#?",    /* paramètre 1 */
      "prenom"  => "#?",    /* paramètre 2 */
      "sexe"    => "#?",    /* paramètre 3 */
      "ndate"   => "#?",    /* paramètre 4 */
      "classid" => "#?"     /* paramètre 5 */
   )
)

Avec la fonction bind(), nous utilisons les numéros de 1 à 5 pour donner une valeur à chaque paramètre anonyme.

->bind
(  array
   (  1  => "Arama",
      2  => "Cirus",
      3  => "M",
      4  => "2008/08/05",
      5  => 8,
   )
);

Mieux que cela, WDB supporte l'utilisation simultanée des paramètres nommés et anonymes dans la même requête. PDO ne supportant pas cette fonctionnalité, WDB rend cela possible par émulation. Le code suivant fonctionne parfaitement:

/* Sélection de toutes les étudiantes nées après 2010/01/01 */
$db->select("*")->from("etudiant")
->where("ndate > :ndate AND sexe = ? ")
->bind(array(":ndate"=>"2010/01/01", 1=>"F"));

while($row = $db->fetch()) var_dump($row);

E . 1 . 3 - Paramètres de requête avec wdb->get

Cela a été souligné dans la section chargement des données avec wdb->get : lorsque la fonction wdb->get est utilisée sans paramètres de requête, elle renvoie directement les résultats. Si par contre les paramètres de requête sont utilisés, elle renvoie l'objet WDB, car la requête n'est pas exécutée tant qu'une valeur n'a pas été assignée à chaque paramètre.

/* Requête sans paramètres PDO. Les résultats
 * sont disponibles immédiatement.
 */
$results = $db->get("etudiant", "studid", 5);
/* Requête avec paramètres PDO. Il faut assigner une valeur
 * à chaque paramètre pour que l'exécution soit possible
 */
$result = $db->get("etudiant", "studid", "#:studid")
->bind(":studid", 5)->fetch();

Dans le code ci-dessus, la fonction bind détecte si tous les paramètres de requête ont reçu une valeur et exécute automatiquement l'instruction. Après il faut explicitement lire les résultats avec l'une des fonctions fetch , fetchAll, ou listAll

E . 1 . 4 - Liaison de variables par adresse

La fonction WDB->bindVar() permet de lier une variable par adresse à un paramètre PDO. L'idée est d'exécuter une même requête avec des valeurs différentes pour les paramètres PDO qu'elle contient. Quand une variable PHP est liée par adresse à un paramètre de requête, ce dernier reçoit automatiquement la valeur affectée à la variable PHP.

Pour faire simple dans cet exemple, nous voulons sélectionner et afficher toutes les étudiantes nées après 2010/01/01, et sélectionner et afficher ensuite tous les étudiants nés après 2009/01/01.

/*   Dans le code qui suit, nous utilisons simultanément un
 *   paramètre anonyme et un paramètre nommé.
 */
$ndate = "2010/01/01";  $sex = "F";

$db->select("*")->from("etudiant")
->where("ndate > :ndate AND sexe = ? ")
->bindVar(":ndate", $ndate)
->bindVar(1, $sex);

while($row = $db->fetch()) var_dump($row);


/*  Nous exécutons la même requête avec des nouvelles valeurs */
$ndate = "2009/01/01";  $sex = "M";
$db->exec();
while($row = $db->fetch()) var_dump($row);

Les deux nouvelles fonctions utilisées ici sont WDB->bindVar() et WDB->exec(). La première s'utilise de la manière suivante:

wdb->bindVar($param, $variable[, $pdo_type]);

La fonction WDB->exec() exécute simplement la dernière requête. Elle peut s'utiliser de 3 manières différentes:

wdb->exec();
/* Pour passer une valeur à un seul paramètre de requête */
wdb->exec($param, $value[, $datatype]);
/* Pour affecter des valeurs à plusieurs paramètres de requête */
wdb->exec($params[, $typeArray]);

Cette fonction n'aura besoin d'aucun paramètre quand la dernière requête ne contient aucun paramètre de requête, ou si tous les paramètres ont déjà reçu une valeur. S'il est nécessaire d'affecter une valeur à un paramètre de requête ou même à plusieurs, cela peut être fait directement à travers la fonction wdb->exec(). Les paramètres sont les mêmes que ceux de la fonction WDB->bind()

E . 1 . 5 - Manipulaton des LOBs

Supposons qu'avec notre base de données précédente, nous voulions ajouter un étudiant dans la table etudiant. Mais cette fois-ci nous voulons aussi y joindre la photo de l'étudiant. Nous supposons que la photo de l'étudiant est dans le fichier "chemin_vers_photo/photo.jpg"

Pour l'insertion d'un LOB, il suffira de passer la ressource du fichier en question dans les données comme on le ferait avec n'importe quelle autre donnée. WDB détecte la ressource en question et s'occupe du reste.

$photo = fopen("chemin_vers_photo/photo.jpg", "r");
$db->insert
(  "etudiant",
   array
   (  "nom"     =>  "Edinga",
      "prenom"  =>  "Emilia",
      "sexe"    =>  "F",
      "ndate"   =>  "2010/10/25",
      "classid" =>  10,
      "photo"   =>  $photo
   )
);

La mise à jour des données avec un BLOB sous forme de ressource se fait tout aussi simplement. Dans l'exemple qui suit nous changeons juste la photo de l'étudiant dont le numéro studid est 25

$photo2 = fopen("chemin_vers_photo/photo2.jpg", "r");
$db->update
(  "etudiant",
   array
   (  "photo"   =>  $photo2
   ),
   array("studid" => 25)
);

Si la source des données du LOB n'est pas une ressource ( fichier ouvert ), WDB n'aura alors aucun moyen de savoir qu'il s'agit d'un LOB. IL faut donc explicitement faire comprendre à WDB qu'il s'agit d'un LOB. On utilisera un paramètre PDO auquel on indiquera explicitement le type adéquat ( PDO::PARAM_LOB )

Supposons que dans une table mytable il y ait parmi d'autres colonnes une colonne de type LOB nommée content, destinée à contenir du texte. Au moment d'ajouter ou d'éditer une ligne dans la table mytable le texte est contenu dans une variable PHP $text.

$text = "
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but also the leap into
electronic typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
and more recently with desktop publishing software like Aldus PageMaker including
versions of Lorem Ipsum" ;

$db->insert
(  "mytable",
   array
   (  "columnn1" =>  $val1,
      "columnn2" =>  $val2,
	  ...
      "content"  => "#:text"  # Ici nous utilisons un param PDO
   )
)
->bind(":text", $text, PDO::PARAM_LOB);

Utiliser une ressource sur une colonne VARCHAR : Par défaut, WDB considère toute colonne avec une valeur de type ressource comme un BLOB. Mais WD vous offre aussi la possibilité d'utiliser une ressource pour une colonne du type CHAR ou VARCHAR.

Supposons justement que la colonne "column1" dans notre dernier exemple est du type VARCHAR, et que les données à affecter à cette colonne proviennent d'un fichier texte. Pour éviter que WDB ne se méprenne sur le type de colonne, voici ce qu'on pourrait faire:

$text = "
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but also the leap into
electronic typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
and more recently with desktop publishing software like Aldus PageMaker including
versions of Lorem Ipsum" ;

$textfile = fopen("/path_to_file/mytext.txt", "r");

$db->insert
(  "mytable",
   array
   (  "columnn1" =>  "#:textfile",
      "columnn2" =>  $val2,
	  ...
      "content"  => "#:text"  # Ici nous utilisons un param PDO
   )
)
->bind(":text", $text, PDO::PARAM_LOB);
->bind(":textfile", $textfile, PDO::PARAM_STR);

La reçupération d'un BLOB se fait naturellement comme une donnée quelconque. reçupérons par exemple quelques données de la table mytable

$condition = array( ... );

$db->select
(  "mytable",
   array
   (  "columnn1",
      "columnn2",
	  ...
      "content"
   )
   $condition
);

/*  On lit les résultats un à un.
 *  $row["content"] contient le BLOB
 */
while($row = $db->fetch())
{
     // Traitement des résultats 
}

reçupérons par exemple quelques données, photo comprise de l'étudiant dont l'ID (studid) vaut 20, en supposant qu'il existe.

$db->select
(  "etudiant",
   array
   (  "nom",
      "prenom",
      "classid"
      "photo"
   )
   array("classid" => 20)
);

/*  On lit le résultat.
 *  $row["photo"] contient le BLOB
 */
$row = $db->fetch();

Jusque-là tout va très bien. Le seul problème se trouve dans le format du BLOB renvoyé. Pour certains SGBDs le BLOB sera de type string (SQLite, MySQL, MariaDB, Firebird, SQLServer par exemple), alors que pour d'autres (PostGresSQL par exemple) le BLOB sera une ressource (fichier ouvert). Ce comportement vient de PDO, qui l'hérite lui-même des pilotes sous-jacents.

D'une façon ou d'une autre, on doit donc prendre en compte ce comportement au moment de traiter les résultats.

$db->select
(  "etudiant",
   array
   (  "nom",
      "prenom",
      "classid"
      "photo"
   )
   array("classid" => 20)
);

/*  On reçupère le résultat
 *  et on affiche le BLOB
 */
if( $row = $db->fetch() )
{
    if( is_resource($row["photo"]) )
    {
        fpassthru( $row["photo"] );
    }
    else
    {
        echo $row["photo"];
    }
}

Une alternative est d'isoler le LOB du set des résultats par l'utilisation de la fonction bindColumn. Nous reprenons l'exemple traité ci-dessus, mais cette fois-ci, nous voulons mettre notre LOB dans la variable php $image.

$db->select
(  "etudiant",
   array
   (  "nom",
      "prenom",
      "classid"
      "photo"
   )
   array("classid" => 20)
)
->bindColumn("photo", $image, PDO::PARAM_LOB) ;

/*  Une fois le résultat recupéré, la valeur ou le contenu
 *  de la colonne "photo" se trouve automatiquement dans la
 *  variable $image
 */
if( $row = $db->fetch() )
{
    if( is_resource($image) )
    {
        fpassthru( $image );
    }
    else
    {
        echo $image;
    }
}

La fonction bindColumn peut être utilisée sur n'importe quelle colonne présente dans les résultats, peu importe son type ou sa valeur.

E . 2 - Modes d'exécutions - Données raw .

E . 2 . 1 - Exécution immédiate

WDB exécute les requêtes de façon automatique une fois que les données nécessaires à l'exécution sont toutes disponibles. Si la requête ne contient pas de paramètre elle est exécutée immédiatement. Dans le cas contraire, elle est exécutée une fois que tous les paramètres ont reçu leur valeur. Dans la suite quelques exemples d'instruction sans paramètres.

# Exécution immédiate
$result = $db->get("users", "userid", 2);

# Exécution immédiate, mais il faut encore prendre le résultat
$db->query("SELECT * FROM users WHERE userid = 2");

# Ceci est un SELECT raccourci. Exécution immédiate.
# Il faudra encore prendre les résultats.
$db->select("users", "*", "userid = 2");

Une petite exception à cette règle est l'instruction "SELECT chaîné", puisque celle-ci peut être constituée de plusieurs fonctions chainées. Un "SELECT chaîné" sans paramètres sera exécuté soit explicitement, soit au moment où l'on demande les résultats

# L'instruction est consignée, mais pas exécutée
$db->select("*")->from("users")->where("userid = 2");

# Elle est exécutée maintenant, avant renvoi des résultats
while($row = $db->fetch()) var_dump( $row );

Cas d'instruction avec paramètres.

# Pas d'exécution, le paramètre :userid n'a pas encore reçu une valeur
$db->query("SELECT * FROM users WHERE userid = :userid");

# C'est la fonction bind qui exécute automatiquement la re-
# quête une fois que tous les paramètres ont reçu leur valeur.
# On peut alors prendre le résultat avec fetch.
$result = $db->bind(":userid", 2)->fetch();

E . 2 . 2 - Exécution différée

Il peut arriver comme on le verra dans la suite, qu'on ne veuille pas nécessairement exécuter une requête automatiquement ou dans l'immédiat. Il suffira pour cela d'appeler la fonction not_execute juste avant la requête. L'exécution ne pourra se faire que soit explicitement, soit à l'appel des résultats. La fonction not_execute sera appelée pour chaque nouvelle instruction dont nous voulons différer l'exécution.

# Pas d'exécution
$db->not_execute()->get("users", "userid", 2);
# L'exécution se fait automatiquement ici
$result = $db->fetch();

# Pas d'exécution, même si tous les paramètres ont reçu leur valeur
$result = $db->not_execute()->query(" SELECT * FROM users
WHERE userid = :userid ")->bind(":userid", 2);

# L'exécution peut se faire explicitement par l'appel de exec(), 
# mais après il faut prendre les résultats si nécessaire
$db->exec();

Vous l'aurez remarqué, les fonctions not_execute() et bind() renvoient toutes les deux l'objet WDB.

E . 2 . 3 - Données raw

Vous pouvez obtenir le code SQL généré par WDB. Deux fonctions existent pour cela, getLastSQL() et raw()

La fonction getLastSQL()

Renvoie le code SQL généré pour la dernière instruction. C'est ce même code qui est exécuté en interne par WDB. Il est fort possible que vous ne puissiez pas exécuter ce code après l'avoir obtenu, car il est susceptible de contenir non seulement vos propres paramètres de requête, mais aussi ceux générés en interne par WDB. Pour du code SQL exécutable consulter la fonction raw() .

var_dump( $db->select("*")->from("users")
->where("userid = 5")->getLastSQL() );

var_dump( $db->select("*")->from("users")
->where( array("userid" => 5) )->getLastSQL() );

Les deux instructions ci-dessus sont automatiquement exécutées. Si nous voulons uniquement obtenir le code SQL, nous pouvons donc éviter l'exécution de la requête en appelant no_execute() juste avant. Testé sous MYSQL, le code précédent affiche quelque chose du genre:

'SELECT  * 
FROM users
WHERE userid = 5' (length=38)
'SELECT  * 
FROM users
WHERE (`userid`=:wdbIprm8)' (length=48)

Il peut arriver qu'une instruction WDB génère plus d'une instruction SQL. Il faut alors indiquer le numéro de l'instruction dont on veut le code. Par défaut le code de la première instruction SQL est renvoyé.

Prenons par exemple le cas d'une modification de 2 lignes dans une table "users", sachant que "userid" est la colonne PRIMARY KEY. Cela peut être fait avec une seule instruction WDB, mais en réalité, deux instructions SQL sont générées en interne :

$db -> update
( 'users',
  'userid',
   array
   (   array
       (  "userid" => 1,
          "prenom" => "James",
          "nom"    => "Kinley"
       ),
       array
       (  "userid" => 2,
          "prenom" => "Anne",
          "nom"    => "Bigard"
       )
   )
);
var_dump( $db->getLastSQL(0), $db->getLastSQL(1) );

Sous MYSQL, l'affichage donne:

string 'UPDATE `users` SET `prenom`=:wdbIprm8,`nom`=:wdbIprm9
WHERE `userid`=:wdbIprm10' (length=79)
string 'UPDATE `users` SET `prenom`=:wdbIprm11,`nom`=:wdbIprm12
WHERE `userid`=:wdbIprm13' (length=81)

La fonction raw()

Renvoie le code SQL brute de la dernière instruction. Ce code est exécutable. Si l'instruction WDB correspond à plus d'une instruction SQL, il faudrait préciser le numéro de l'instruction dont on veut le code, le code de la première instruction SQL étant le code par défaut. Si la dernière instruction WDB contient des paramètres, la fonction raw doit être appelée seulement lorsque tous les paramètres ont reçu une valeur .

/* Sans paramètres de requête */
var_dump(
  $db->not_execute()->query("SELECT name, email
  FROM users WHERE userid <= 10")->raw()
);

/* Avec paramètres de requête */
var_dump(
  $db->not_execute()->query("SELECT name, email
  FROM users WHERE userid <= :number")
  ->bind(":number", 10)->raw()
);

Sous MYSQL, l'affichage donne:

string 'SELECT name, email
FROM users WHERE userid <= 10' (length=49)
	
string 'SELECT name, email
FROM users WHERE userid <= 10' (length=49)
	

E . 3 - Gestion des erreurs et sécurité

E . 3 . 1 - Signalement des erreurs

WDB peut se comporter de l'une des 3 manières suivantes lorsqu'une erreur se produit:

Le premier comportement est le comportement par défaut. Il y a deux façons différentes de choisir l'un ou l'autres de ces comportements. Cela peut être fait au moment de la connexion à la DB, en ajoutant la clé PDO::ATTR_ERRMODE aux options de connexions (voir les options de connexion).

$options = array( PDO::ATTR_ERRMODE  =>  PDO::ERRMODE_SILENT );

$db = new wdb(array(
  "server"  =>  "nom_du_serveur",
  "port"    =>  "port_de_connexion",
  "dbname"  =>  "nom_de_la_db",
  "type"    =>  wdb::MYSQL,
  "user"    =>  "nom_utilisateur",
  "pswd"    =>  "mot_de_passe",
  "options" =>  $options,
));

Dans cet exemple, nous optons pour le mode 3, c'est à dire rien ne sera fait en cas d'erreur. PDO::ATTR_ERRMODE peut prendre 3 valeurs qui correspondent respectivement aux 3 modes de signalement sus-cités:

L'autre manière de fixer le mode de signalement c'est de le faire à la volée pendant l'exécution. Cela se fait très simplement et reste valide tant qu'une nouvelle valeur n'a pas été affectée. Deux fonctions permettent de le faire:

$db->error_reporting( PDO::ERRMODE_SILENT );
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );

Ces deux instructions sont équivalentes. $db->error_reporting() permet de fixer et / ou d'obtenir la valeur courante du mode de signalement des erreurs. Elle peut recevoir l'une des 3 valeurs PDO::ERRMODE_EXCEPTION, PDO::ERRMODE_WARNING et PDO::ERRMODE_SILENT avec les effets que nous connaissons. Elle renvoie toujours la valeur courante du mode de signalement des erreurs.

$db->setAttribute() permet de fixer la valeur d'un ou plusieurs attributs. Dans ce cas précis, l'attribut est PDO::ATTR_ERRMODE qui peut donc recevoir l'une des 3 valeurs indiquées.

😕 Attention toutefois avec ces deux fonctions. Leur comportement peut être bloqué pour des raisons de sécurité par celui qui a créé l'objet WDB. Dans ce cas, leur appel ne causera pas d'erreur, mais restera sans effet.

E . 3 . 2 - Verrouiller l'instance WDB.

Dans un environnement de développement multi-scripts, la possibilité que chaque script puisse changer le mode de signalement des erreurs ou assigner de nouveaux réglages à WDB peut s'avérer problématique. Vous avez la possibilité de bloquer ce comportement.

Une première possibilité consiste à verrouiller le mode de signalement des erreurs. Cela se fait par une simple instruction comme suit:

$db->lock_error_reporting();

Une fois cette fonction appelée, il n'y a plus aucun moyen de changer encore le mode de signalement des erreurs. Cette fonction renvoie l'objet WDB pour permettre le chainage.

L'autre possibilité est d'opter pour un verrouillage généralisé comme suit:

$db->security_mode();

Le mode sécurisé annule le comportement de toutes les fonctions susceptibles d'affecter la configuration de l'objet PDO interne. Ces fonctions sont les suivantes: error_reporting(), setAttribute(), setAttributes() et pdo(). Si vous appelez une de ces fonctions après avoir exécuté la fonction security_mode(), cela ne provoquera pas d'erreur mais ladite fonction restera sans effet.

Le but du verrouillage est de préserver les réglages de l'instance WDB tels quels. Ceci veut aussi dire que seul le premier appel de chacune de ces fonctions est effectif, tous les appels suivants restant sans effet.

Attention tout de même à l'utilisation simultanée des deux verrouillages. Ce qui a été verrouillé par l'une des fonctions ne saurait être déverrouillé par l'autre et vice versa. Considérons le code suivant:

$db->security(FALSE)->lock_error_reporting();

L'appel de la fonction wdb: :security() avec l'argument FALSE indique à WDB de rejeter toute forme de verrouillage. Si bien que l'appel ultérieur de la fonction lock_error_reporting() n'a absolument aucun effet. Considérons encore le code suivant:

$db->lock_error_reporting()->security(FALSE);

L'appel de la fonction lock_error_reporting() verrouille le mode de signalement des erreurs. L'appel ultérieur de la fonction security() demande l'interdiction de toute forme de verrouillage. Cet appel sera effectif, sauf sur le mode de signalement des erreurs qui restera verrouillé.

E . 3 . 3 - Réinitialisation après une erreur

Peu importe le mode de signalemet choisi (il vaut PDO::ERRMODE_EXCEPTION par défaut), l'objet WDB devient invalide une fois qu'une erreur s'est produite. Toute instruction qu'on essayera d'exécuter après une erreur sera ignorée, jusqu'à ce que l'objet soit réinitialisé.

Il est donc nécessaire de tester l'erreur après chaque instruction. La fonction WDB->error() permet de tester et de récupérer le cas échéant la dernière erreur. Et la fonction WDB->init() réinitialise l'objet. Nous pouvons donc appeler nos fonctions chaînées sans problème et tester l'erreur à l'endroit adéquat, par exemple à la fin d'une instruction.

# Nous demandons à WDB d'ignorer les erreurs
$db->error_reporting( PDO::ERRMODE_SILENT );

# Nous exécutons notre requête et testons l'erreur à la fin
if( ! ($error = $db->select( $columns )->from( $table )
    ->where( $condition )->groupby($group)->orderby($order)
    ->exec()->error() )
)
{  # Si tout se passe bien nous affichons les données
    while($row = $db->fetch())
    {
        var_dump($row);
    }
}
else
{   # En cas d'erreur nous affichons un message et
    # réinitialisons l'objet
    echo "Erreur pendant l'exécution. Le script continue.";
    $db->init();
}

Après réinitialisation de l'objet, le message d'erreur ainsi que toute requête effectuée au préalable sont simplement effacés. Dans un environnement multi-scripts dans lequel tous les scripts utilisent le même objet WDB, il est dont recommandé de tester une éventuelle erreur de l'objet WDB au début de chaque script, et de le réinitialiser avant toute utilisation s'il y a erreur.

E . 4 - Fonctions utiles

add, beginTransaction, bind, bindColumn, bindVar, columnCount, commit, dbltype, dbms, dbtype, dbVersion, delete, dsn, error, error_reporting, exec, fetch, fetchAll, fjoin, from, get, getLastSQL, groupby, having, infos, init, insert, join, lastInsertId, limit, listAll, ljoin, lock_error_reporting, not_execute, orderby, pdo, query, quote, quoteIdent, raw, rjoin, rollback, row, rowCount, security_mode, select, setAttribute, setAttributes, sgbd, sql, sqliteCreateAggregate, sqliteCreateFunction, update, version, where

Pour les fonctions accompagnés d'un code d'exemple, cliquez sur la surface du code pour déplier toute la surface.


add ( . . )   :   wdb

Alias de la fonction insert


beginTransaction ( )   :   bool

Initialise une transaction. Elle renvoie TRUE en cas de réussite et FALSE sinon. La transaction ainsi initialisée peut être validée par commit() ou annulée en cas d'erreur par rollback()


bind ( mixed $param , mixed $value [ , int $datatype] )   :   wdb

bind ( array $params [ , array $datatypes] )   :   wdb

Permet d'affecter des valeurs aux paramètres de requêtes. Lire le paragraphe Paramètres de requête pour comprendre l'utilisation de cette fonction.


bindColumn ( mixed $column , mixed &$var , int $datatype = PDO::PARAM_STR , int $maxLength = 0 , array $driverOptions = null )   :   wdb

Permet de lier la valeur d'une colonne dans un set de résultat à une variable PHP.

Exemple: Nous voulons sélectionner les colonnes "nom" et "prenom" de la table "users". Mais nous voulons qu'après la lecture de chaque résultat, le nom et prénom de l'utilisateur soient automatiquement stoqués dans les variables PHP $user_name, et $user_firstname.

/*  La fonction exec() permet l'exécution de la requête
 *  SELECT avant l'appel de la fonction bindColumn()
 */
$db->select(array("nom", "prenom"))->from("users")
->where( "userid <= 10" )->exec()
->bindColumn("nom", $user_name)
->bindColumn("prenom", $user_firstname);

/*  Pour chaque résultat lu, nous affichons
 *  le nom complet de l'utilisateur concerné
 */
while( $db->fetch() )
{
    echo "UTILISATEUR: $user_name $user_firstname";
}

bindVar ( mixed $param , mixed &$var , int $datatype = false )   :   wdb

Permet d'affecter des valeurs aux paramètres de requêtes par adresse. Lire le paragraphe liaison de variables par adresse pour comprendre l'utilisation de cette fonction.


columnCount( )   :   int

Renvoie le nombre de colonnes du set de résultat. Le code suivant devrait afficher Chaque set de résultat contient 2 colonnes

$db->select(array("nom", "prenom"))->from("users")
->where( "userid <= 10" )->exec();

echo "Chaque set de résultat contient ", $db->columnCount( ) ." colonnes";

commit ( )   :   bool

Valide une transaction. Elle renvoie TRUE en cas de succès ou FALSE sinon.


dbltype ( )   :   string

Renvoie une chaîne de caractères représentant le type de base de données courante. Cette chaîne peut par exemple être une des valeurs parmi: "MYSQL", "SQLITE", "POSTGRESQL", "CUBRID", "INFORMIX", "SQLSERVER", "FIREBIRD", "ORACLE DB", "DB2", "SYBASE". Attention, si c'est Maria DB qui est installée, cette fonction renverra "MYSQL". Les deux autres alias de cette fonction sont dbms et sgbd


dbms ( )   :   string

Alias de la fonction dbltype


dbtype ( )   :   int

Renvoie un entier naturel représentant le type de la base de données courante. Cet entier peut être l'une des valeurs suivantes: WDB::CUBRID, WDB::FIREBIRD, WDB::INFORMIX, WDB::MYSQL, WDB::ORACLE, WDB::POSTGRESQL, WDB::SQLITE, WDB::SQLSERVER, WDB::DB2, WDB::SYBASE .


dbVersion ( bool $process = TRUE )   :   string

Renvoie la version du moteur de base de données installé . Cela renvoie quelque chose du genre: Mysql: 10.4.13 , SQL Server : 14.0.1000.169 , PostGresSQL: 9.6.22, Firebird: 3.0.8


delete ( string $table , mixed $where)   :   wdb

delete ( string $table , string $keyname , array $values)   :   wdb

Supprime les données dans la base de données. Pour comprendre l'utilisation de cette fonction, voir le paragraphe suppression des données .


dsn ( array $cdata , int &$dbtype = 0 , int &$nbr = 0 , string &$user = "" , string &$psw = "" )   :   string

Calcule et renvoie le dsn en utilisant un array de données de connexion $cdata. La fonction renvoie un STRING en cas de succès ou FALSE sinon. Pour ce qui concerne les données de connexion passées à cette fonction, voir la partie Connexion avec un Array de paramètres .

Voici la signification des autres paramètres de cette fonction, lorsqu'il sont fournis:

$dbtype : ressort avec une valeur entière qui indique le type de base de données

$nbr : non utilisé

$user : ressort avec l'identifiant de l'utilisateur ou une chaîne vide si non présent

$psw : ressort avec le mot de passe de l'utilisateur ou une chaîne vide si non présent


error ( )   :   string

Renvoie une chaine de caractères décrivant la dernière erreur survenue dans les requêtes. Si aucune erreur n'est survenue ou si l'objet WDB a été réinitialisé entre-temps, la fonction renvoie FALSE ou une valeur équivalente (chaine vide). Si une erreur survient dans un objet WDB, celui-ci reste invalidé jusqu'à sa réinitialisation. Voir la partie Gestion des erreurs pour plus de détails.


error_reporting ( [ int $value ] )   :   int

Permet de fixer et / ou obtenir le mode de signalement des erreurs. Cette fonction peut être bloquée auquel cas son appel n'aura aucun effet sur le mode de signalement des erreurs. Qu'elle soit bloquée ou pas, la fonction renvoie toujours une valeur entière correspondant au mode de signalement des erreurs courant. Voir la partie Signalement des erreurs pour plus de détails.


exec ( [ . . . ] )   :   wdb

Permet d'exécuter explicitement la dernière requête. Cette fonction peut recevoir les mêmes paramètres que la fonction bind . Ce qui veut dire que, si votre requête contient des paramètres, on peut leur affecter des valeurs directement à travers la fonction exec au moment de l'appel.

/*  Dans ce code, nous prenons les données de l'utilisateur
 *  dont l'ID est $userid. Nous utilisons un paramètre anonyme
 *  auquel nous affectons la valeur au moment de l'exécution.
 */
$userid = 10;
$user = $db->query("SELECT * FROM users WHERE userid = ? ")
->exec(1, $userid)->fetch();

fetch ( int $mode = \PDO::FETCH_ASSOC , int $cursorOrientation = \PDO::FETCH_ORI_NEXT , int $cursorOffset = 0)   :   mixed

Renvoie un élément de résultat ou NULL s'il n'y a aucun résultat ou si tous les résultats ont déjà été lus.


fetchAll ( [ int $mode = PDO::FETCH_ASSOC ] )   :   array

fetchAll ( int $mode = PDO::FETCH_COLUMN , int $column )   :   array

fetchAll ( int $mode = PDO::FETCH_FUNC , callable $callback )   :   array

fetchAll ( int $mode = PDO::PDO::FETCH_CLASS , string $class , ?array $constructorArgs )   :   array

Retourne un tableau contenant toutes les lignes du jeu d'enregistrements. Pour comprendre le fonctionnement de cette fonction voir la fonction PDO PDOStatement::fetchAll


fjoin ( string $table , mixed $condition )   :   wdb

fjoin ( array $tables )   :   wdb

Cette fonction effectue une ou plusieurs jointures de type FULL JOIN, et peut être appelée dans le cadre d'une instruction SELECT. Elle renvoie l'objet WDB, permettant ainsi le chaînage de fonctions. Elle s'utilise de la même façon que la fonction join .


from ( mixed $table )   :   wdb

Cette fonction renseigne la ou les tables à partir desquelles la sélection doit se faire. Elle doit être appelée dans le cadre d'une instruction SELECT chaînée. Elle renvoie l'objet WDB, permettant ainsi le chaînage de fonctions.

/*  Sélection à partir d'une seule table */
$db->select(" * ")->from("mytable");

/*  Sélection à partir d'une seule table */
$db->select(" * ")->from( array("mytable") );

/*  Sélection à partir de deux tables */
$db->select(" * ")->from("mytable, mytable2");

/*  Sélection à partir de deux tables */
$db->select(" * ")->from( array("mytable", "mytable2") );

Voir le paragraphe select raccourci pour d'autres informations.


get ( string $table, mixed $keyname, mixed $keyvalue [ , mixed $columns ] )   :   mixed

Permet la sélection de données en utilisant une colonne UNIQUE ou un certain nombre de colonnes dont les valeurs combinées forment un ensemble unique. Cette fonction renvoie directement un résultat ( array ) lorsqu'elle est utilisée sans paramètres de requête. Mais si les paramètres sont utilisés, elle renvoie l'objet WDB. Pour plus d'informations, voir les parties Chargement des données avec get() et Paramètres de requête avec get() .


getLastSQL ( [ int $i = 0 ] )   :   string

Renvoie le code SQL généré pour la dernière instruction. C'est ce même code qui est exécuté en interne par WDB. Ce code n'est pas nécessairement exécutable par l'utilisateur. Lire la partie Données raw pour plus d'informations.


groupby ( mixed $columns )   :   wdb

Réalise la commande SQL GROUP BY, et ne peut être appelée que dans le contexte d'une instruction SELECT chaînée.

/* Sélection du nombre d'étudiants par classe */
$res = $db->select(" classid, COUNT(studid) AS nbr ")
->from( "etudiant" )->groupby( "classid" )
->fetchAll();

having ( mixed $condition )   :   wdb

Réalise la commande SQL HAVING, et ne peut être appelée que dans le contexte d'une instruction SELECT chaînée. Voir le paragraphe les conditions pour comprendre l'utilisation générale des conditions.


infos ( )   :   array

Elle renvoie un certain nombre d'informations de configuration pour l'instance WDB et sur la connexion courante. Il s'agit d'un tableau dont le contenu dépend du type de base de données. Ce tableau contient entre autres les clés suivantes: "AUTOCOMMIT", "ERRMODE", "CASE", "TIMEOUT", "CONNEXION_STATUS", "ORACLE_NULLS", "PERSISTENT", "PREFETCH", "SERVER_INFO", "SERVER_VERSION", "CLIENT_VERSION", "DRIVER_NAME" .


init ( )   :   wdb

Réinitialise l'objet WDB après une erreur. Voir la partie Reinitialisation après une erreur .


insert ( string $table , array $rows )   :   wdb

Cette fonction ajoute de nouvelles lignes dans une table de la base de données. Voir la partie Insertion avec la fonction insert .


join ( string $table , mixed $condition )   :   wdb

join ( array $tables )   :   wdb

Cette fonction effectue une ou plusieurs jointures de type JOIN et ne peut être appelée que dans le cadre d'une instruction SELECT chaînée. Elle renvoie l'objet WDB, permettant ainsi le chaînage des fonctions.

/*  Cas de jointure d'une seule table */
$db->select(" * ")->from("mytable")
->where( $condition1 )
->join( "mytable2", $condition2 );

/*  Cas de jointure de deux tables */
$db->select(" * ")->from("mytable")
->where( $condition1 )
->join
(   array
    (  "mytable2" => $condition2,
       "mytable3" => $condition3
    )
);

/*  Cas de jointure de deux tables */
$db->select(" * ")->from("mytable")
->where( $condition1 )
->join( "mytable2", $condition2 )
->join( "mytable3", $condition3 );

lastInsertId ( string $table = "", string $key = "" )   :   int

Retourne l'identifiant de la dernière ligne insérée ou la valeur d'une séquence. Pour beaucoup de DBMS cette fonction ne nécessitera aucun paramètre, mais pour quelques-uns, il faudra préciser le nom de la table ainsi que le nom de la colonne auto-générée (AUTO-INCREMENT ou SEQUENCE). Nous conseillons donc de passer ces deux paramètres si on n'est pas absolument certains que cela puisse fonctionner sans.

/*  Exemple de récupération de l'ID après une insertion.
 *  On suppose que la colonne "userid" de table "users" est
 *  auto-incrementée
 */
$id = $db->insert("users", array('nom'=> "Konan",
'prenom' => "Lens", 'email' => "new@email.net", 'sexe' => "M"))
->lastInsertId('users', 'userid');

limit ( int $nbr , int $offset = 0 )   :   wdb

Permet de limiter le nombre de résultats renvoyés par l'instruction SELECT chaînée, et ne peut être appelée que dans le cadre de cette instruction. Elle renvoie l'objet WDB, permettant ainsi le chaînage des fonctions.

$nbr : indique le nombre maximum de lignes à renvoyer.

$offset : spécifie le nombre de lignes à ignorer avant de commencer à renvoyer les résultats.

Pour SQL Server, la clause ORDER BY doit être préalable à l'utilisation de LIMIT, étant donné que cette dernière est une simple option de la première. Voir l'instruction SELECT chaîné


listAll ( mixed $column = 0 )   :   array

Renvoie toutes les valeurs correspondant à une colonne donnée contenue dans les résultats. Un nom ou un numéro de colonne doit être fourni, le numéro de colonne par défaut étant 0.

$res = $db->select("name")->from("users")
->where("userid=2 OR userid=3")->listAll();

var_dump($res);

Ce code va afficher quelque chose du genre:

array (size=2)
  0 => string 'Amougi' (length=6)
  1 => string 'Polson' (length=5)

ljoin ( string $table , mixed $condition )   :   wdb

ljoin ( array $tables )   :   wdb

Cette fonction effectue une ou plusieurs jointures de type LEFT JOIN et ne peut être appelée que dans le cadre d'une instruction "SELECT chaîné". Elle renvoie l'objet WDB, permettant ainsi le chaînage des fonctions. Elle s'utilise de la même façon que la fonction join .


lock_error_reporting ( )   :   wdb

Empêche tout changement ultérieur du mode de signalement des erreurs. Seul le premier appel de cette fonction est effectif. Tout appel ultérieur n'engendrera pas d'erreur mais restera sans effet. Pour plus d'informations voir la gestion des erreurs .


not_execute ( )   :   wdb

Empêche l'exécution immédiate ou automatique de la prochaine requête. Pour plus d'informations voir la partie Exécution différée .


orderby ( . . . )   :   wdb

orderby ( mixed $columns )   :   wdb

Cette fonction réalise la commande SQL ORDER BY et ne peut être appelée que dans le cadre d'une instruction SELECT chainée. Elle renvoie l'objet WDB, permettant ainsi le chaînage des fonctions. Les trois instructions dans l'exemple suivant sont toutes équivalentes:

$res = $db->select("userid, name, first_name")
->from("users")->where("userid <= 20")
->orderby( "name ASC, first_name DESC" )
->fetchAll();

$res2 = $db->select("userid, name, first_name")
->from("users")->where("userid <= 20")
->orderby( "name ASC", "first_name DESC" )
->fetchAll();

$res3 = $db->select("userid, name, first_name")
->from("users")->where("userid <= 20")
->orderby( array("name" => "ASC", "first_name" => "DESC") )
->fetchAll();

pdo ( [ PDO $pdo , int $dbtype ] )   :   mixed

Remplace et / ou renvoie l'objet PDO utilisé par WDB. Cette fonctionnalité peut être bloquée, auquel cas la fonction reste sans effet et renvoie toujours NULL .  $dbtype indique le type de DB de l'objet PDO. Voir les constantes des types de SGBDs .

/*  Dans cet exemple, nous supposons que notre objet
 *  WDB $db a déjà été créé et existe dans le script.
 */

/* Nous créons un objet PDO quelque part */
$pdo = new \PDO('sqlite:/path/to/db_file.sqlite3', "", "");

/*  On assigne à WDB le nouvel objet PDO, 
 *  en renseignant aussi le type de DB .
 */
$db->pdo( $pdo, WDB::SQLITE );

query ( string $query )   :   wdb

Exécute une requête SQL quelconque. Ladite requête peut contenir des paramètres, auquel cas celle-ci n'est exécutée que lorsque tous les paramètres ont reçu une valeur.

/* Sans paramètres de requête */
$results = $db->query("SELECT name, email
FROM users WHERE userid <= 10")->fetchAll();

/* Avec paramètres de requête */
$results2 = $db->query("SELECT name, email
FROM users WHERE userid <= :number")
->bind(":number", 10)->fetchAll();

quote ( string $str,  int $type = PDO::PARAM_STR )   :   string

Place des guillemets simples autour d'une chaîne d'entrée si nécessaire, et protège les caractères spéciaux présents dans la chaîne d'entrée, en utilisant le style de protection approprié au pilote courant. Si le pilote supporte la fonction PDO::quote(), elle est utilisée, sinon une alternative interne est utilisée à la place, si bien que cette fonction réussira toujours.


quoteIdent ( string $ident, bool $multifield = FALSE )   :   string

Protege un identifiant pour une utilisation dans une requête sql. Cette fonction place des guillemets doubles autour d'un identifiant (si nécessaire), en utilisant le style de protection approprié au pilote courant.

$ident : La chaîne à protéger.

$multifield : Indique si le nom de l'identifiant doit être considéré comme identifiant à champ unique (exemple: mycolumn) ou à champs multiples (exemple: mytable.mycolumn).

Un identifiant à champ unique est traité de façon simple et directe, car considéré comme le vrai nom dans la DB. Mais l'analyseur des identifiants multi-champs accepte [], " " et ` ` comme protecteurs des champs. On peut voir cela dans l'exemple suivant sous MYSQL:

echo $db->quoteIdent("my ident", FALSE);     # `my ident`
echo $db->quoteIdent("my ident", TRUE);      # `my ident`
echo $db->quoteIdent("my.ident", FALSE);     # `my.ident`
echo $db->quoteIdent("my.ident", TRUE);      # `my`.`ident`
echo $db->quoteIdent("my . ident", FALSE);   # `my . ident`
echo $db->quoteIdent("my . ident", TRUE);    # `my`.`ident`
echo $db->quoteIdent("üßt . ident", FALSE);  # `üßt . ident`
echo $db->quoteIdent("üßt . ident", TRUE);   # `üßt`.`ident`
echo $db->quoteIdent("my tab.col", FALSE);   # `my tab.col`
echo $db->quoteIdent("my tab.col", TRUE);    # `my tab.col`
echo $db->quoteIdent("[my tab].col", FALSE); # `[my tab].col`
echo $db->quoteIdent("[my tab].col", TRUE);  # `my tab`.`col`
echo $db->quoteIdent('"my tab".col', FALSE); # `"my tab".col`
echo $db->quoteIdent('"my tab".col', TRUE);  # `my tab`.`col`

raw ( [ int $nbr = 0 ] )   :   string

Renvoie le code SQL exécutable brute de la dernière instruction. Lire la partie données raw pour plus d'informations.


rowCount ( )   :   int

retourne le nombre de lignes affectées par la dernière requête DELETE, INSERT ou UPDATE . Cette méthode retourne toujours "0" (zéro) avec le pilote SQLite, et avec le pilote PostgreSQL uniquement quand l'attribut de déclaration PDO::ATTR_CURSOR est défini à PDO::CURSOR_SCROLL.


security_mode ( [ bool $enabled = TRUE ] )   :   wdb

Détermine les fonctionnalités des fonctions error_reporting(), pdo() et setAttribute(). Si $enabled vaut TRUE ces fonctions resterons sans effet et la fonction pdo() renverra toujours NULL ou lieu de l'objet PDO. Si $enabled vaut FALSE ces fonctions fonctionneront toujours comme prévu et ne pourront d'aucune manière être bloquées. Seul le premier appel de security_mode() sera effectif, tous les autres appels resteront sans effet.


select ( . . . )   :   wdb

Fonction utilisée dans le cadre de la sélection des données avec l'instruction SQL SELECT. Pour ce qui concerne son utilisation, lire les parties select chaîné et select raccourci .


setAttribute ( array $attributes )   :   wdb

setAttribute ( int $attribute , mixed $value , . . . )   :   wdb

Définit un ou plusieurs attribut(s) de l'objet PDO interne. Les attributs spécifiques au pilote ne doivent pas être utilisés avec d'autres pilotes. Cette fonction peut être bloquée, auquel cas son appel restera sans effet. Pour plus de détails, voir la section verrouillage de l'instance WDB


setAttributes ( array $attributes )   :   wdb

setAttributes ( int $attribute , mixed $value , . . . )   :   wdb

Alias de setAttribute .


sgbd ( )   :   string

Alias de la fonction dbltype .


sql ( int $i = 0 )   :   string

Alias de la fonction getLastSQL .


sqliteCreateAggregate ( string $function_name, callable $step_func, callable $finalize_func, int $num_args = ?)   :   bool

Référence une fonction agrégative définie par l'utilisateur pour une utilisation dans les requêtes SQL. Voir le fonctionnement ici


sqliteCreateFunction ( string $function_name, callable $callback, int $num_args = -1, int $flags = 0 )   :   bool

Référence une fonction définie par l'utilisateur pour une utilisation dans les requêtes SQL. Voir le fonctionnement ici


update ( string $table , array $data , mixed $where )   :   wdb

update ( string $table , mixed $column_index , array $row_list )   :   array

update ( string $table , mixed $column_index , array $row1 . . . array $row_n )   :   array

La fonction met à jour les données. Pour plus d'informations sur l'utilisation de cette fonction voir la partie La fonction wdb->update()


version ( )   :   string

Renvoie la version courante de WDB.


where ( mixed $condition )   :   wdb

Renseigne la condition à utiliser dans le cadre de l'instruction "SELECT chaîné". Voir le paragraphe select chaîné" pour comprendre l'utilisation de cette fonction et le paragraphe les conditions pour comprendre l'utilisation générale des conditions.


Des questions ou des propositions? N'hesitez pas à me contacter.

@ Contactez-moi

Dites-moi quelque chose d'important, mais s'il vous plaît pas de spam.

Powered by w3.css

Free Web Hosting