coincoins

PHP & base de données

Lire/écrire des données dans une base de données

Prérequis : La lecture dans une base de donnée est faite avec des requêtes SQL. Il faut donc avoir bien vu ce langage avant d'aborder ce cours.

(même si les requêtes de ce cours ne sont pas très avancées.)

l'algorithme classique
Pour lire une BDD, l'algorithme utilisé est très classique. Basé sur des fonctions qui dépendent du SGBD (Système de Gestion de BDD), il se compose de 7 étapes.

Définition préallable de paramètres importants

Les paramètres de connexion au serveur de données, le nom de la base de données doivent être définis. dans ce chapitre, on utilisera des paramètres classiques pour une connexion à un serveur local :

  • server : l'adresse du serveur (URL, IP)
  • user : l'identifiant de l'utilisateur de connexion au SGBD
  • pass : le mot de passe de connexion de cet utilisateur
  • dbName : le nom de la base de données à utiliser

 

Algorithme classique

Note : En PHP, cet algorithme utilise les fonctions : mysqli_***.

Remarque :

Ceci dit, on passera souvent aux PDO (Portable Data Object) pour communiquer avec la BDD : plus de souplesse et de sécurité.

Il s'agit de faire les étapes suivantes :

  1. Connexion au serveur,
  2. Sélectionner/ouvrir la base de données,
  3. Préparer la requête,
  4. Exécuter la requête,
  5. TANT QUE (Lire la requête fonctionne),
  6.   FAIRE :
    •   Traiter les données lues
    Fin TANT QUE
  7. Fermer la requête, la base et le serveur (dans cet ordre)

 

Algorithme obsolète ?

Cet algorithme est parfaitement fonctionnel mais un peu obsolète car la partie relation aux données et traitement des données sont mélangées.
Aujourd'hui, on sépare les deux ainsi que l'affichage, afin de faciliter la répartition du travail sur plusieurs fichiers. Voir un peu plus loin ...

En fait, on traville plutôt en programmation objet et même, avec des outils de développement automatisés (framework). Voir baeaucoup plus loin ...

 

Traduction en php avec mysqli:

<?php
// A) CONNEXION au serveur et ouverture de la base
	$connexion_id=mysqi_connect($server, $user_id, $user_pwd); // 1) Connecter le serveur,
	mysqli_select_db($connexion_id, $database_name); // 2) Ouvrir la bdd,
 
// B) EXECUTION de la requête après l'avoir préparée
	$requete="SELECT ... FROM ... ;"; // 1) Préparer la requête,
	$requete_id=mysqli_query($connexion_id, $sql); // 2) Exécuter la requête,
 
// C) LECTURE et TRAITEMENT des données tant qu'il y a des données à lire
	while ($enreg=mysqli_fetch_array($sql_id)) // 1) TQ(Lire requête ok),
	{   // FAIRE :
		//   2) Traiter les données lues,
	} // Fin TANT QUE,
 
	mysqli_close($connexion_id) // 3 Fermer la connexion
?>

Algo classique traduit avec PDO :

// A) CONNEXION à la base de données
	// 1) Initialisation des paramètres
	$dbServer="localhost"; // serveur
	$dbUser="root";        // utilisateur de connexion
	$dbPass="";            // mot de passe (vide!)
	$dbName="maSuperDataBase"; // nom de la BDD
 
	// 2) connexion & ouverture de la base 
	   // (ouais, c'est compliqué, mais quant y faut, y faut).
	$DB = new PDO("mysql:host=$dbServer;dbname=$dbName", $dbUser, $dbPass, 
	   array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
	);
 
// B) EXECUTION de la requête et récup des données
	$codeSQL = "SELECT * FROM fruits ;"; // 3) préparation de la requête
	$query_stmt = $DB->query($codeSQL);  // 4) exécution de la requête
 
// C) LECTURE et TRAITEMENT des données
	// 5) TANT QUE la liste n'est pas finie, lire un enregistrement
	while ($unEnreg = $query_stmt->fetch(PDO::FETCH_ASSOC)) { // lire et tester
	  // 6b) traiter l'enregistrement
	  echo $unEnreg['id']." : ".$unEnreg['nom']."<br>"; 
	}
 
	// 7) fermeture de la connexion
	unset($DB);

Algo "moderne" avec PDO :

Attention, ce code n'est pas très sécurisé contre les injections SQL (type d'attaque). Pour cela, il faudrait modifier la partie "lancement" de la requête

// A) CONNEXION à la base de données
	// 1) Initialisation des paramètres
	$dbServer="localhost"; // serveur
	$dbUser="root";        // utilisateur de connexion
	$dbPass="";            // mot de passe (vide!)
	$dbName="maSuperDataBase"; // nom de la BDD
 
	// 2) Connexion & ouverture de la base 
	$DB = new PDO("mysql:host=$dbServer;dbname=$dbName", $dbUser, $dbPass, 
	   array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
	);
 
// B) RECHERCHER toutes les données : lancement de la requête et récup des données
	$codeSQL = "SELECT * FROM fruits ;"; // 1) préparation de la requête
	$query_stmt = $DB->query($codeSQL);  // 2) exécution de la requête
	$lesEnreg = $query_stmt->fetchAll(PDO::FETCH_ASSOC); // 3) lire ttes les lignes 
	unset($DB);	// 4) fermeture de la connexion
 
// C) TRAITER les données
	// POUR CHAQUE enregistrement de la liste des enregistrements
	foreach ($lesEnregs as $unEnreg) { 
	  // traiter l'enregistrement
	  echo $unEnreg['id']." : ".$unEnreg['nom']."<br>"; 
	}
 

Que voit-on ?

On retrouve toutes les notions d'algo : les instructions, les variables, les boucles, les blocs, etc. ...

Cet algorithme générique permet de traiter toutes les lignes d'un tableau de données fourni par la requête.

Si la requête ne retourne aucun enregistrement, aucune ligne ne sera traitée

La fonction prédéfinie mysqli_fetch_array retourne les données sous forme d'un tableau avec indices numériques ET indices associatifs, c-à-d que les indices des cellules sont nommées par les noms de champs de la table résultante de la requête

Il existe d'autres types de résultats (non utilisés en terminale SIG) :

  1. mysqli_fetch_assoc : ne retourne que le tableau associatif
  2. mysqli_fetch_row : ne retourne que le tableau à indice numériques
  3. mysqli_fetch_array : ***_assoc + ***_row ; c'est celui qu'on utilise en terminale
  4. mysqli_fetch_objet : retourne un objet enregistrement (pour de la programmation "objet")

Retennez bien cet algorithme, il est la base de toutes les variantes possibles pour une lecture ET une modification des données d'une base.

Modifier les données
Où on en arrive a faire de vraies manip de l'information.

Modifier la base de données ou son contenu est une démarche plus simple qu'avant (d'où l'intérêt d'apprendre le chapitre précédent).

En fait, il n'y a pas de boucle, tout est terminé à l'étape 4 : "exécution de la requête".

On aura donc l'algorithme suivant :

Préallable : Définition des paramètres server_name, user_id, user_pwd, database_name

  1. Connexion au serveur,
  2. Sélectionner/ouvrir la base de données,
  3. Préparer la requête,
  4. Exécuter la requête,
  5. Fermer la requête, la base et le serveur (dans cet ordre)

traduction en php avec mysqli_* :

// A) Connexion : déjà fait
 
// B) préparer et exécuter la requête
	$requete="SELECT ... FROM ... ; // Préparer la requête,
	$requete_id=mysqli_query($connexion_id, $sql); // Exécuter la requête,
 

Algo classique traduit avec PDO :

// A) CONNEXION à la base de données, déjà fait
 
// B) EXECUTION de la requête et récup des données
	$codeSQL = "SELECT * FROM fruits ;"; // 3) préparation de la requête
	$query_stmt = $DB->query($codeSQL);  // 4) exécution de la requête
 

Note : Si on peut maintenant modifier le contenu des tables, il suffit de mettre les bonnes requêtes pour pourvoir modifier la structure de la base (LDD) ou administrer celles-ci (LCD). Donc : tout est dans le SQL ... hé hé hé.

Algo "moderne" avec PDO :

Attention, ce code n'est pas très sécurisé contre les injections SQL (type d'attaque). Pour cela, il faudrait modifier la partie "lancement" de la requête

Spécial PDO : Préparer la requête en toute sécurité
Ajouter la sécurisation contre les injection SQL, une attaque classique (voir BTS, Bloc 3
Considérations supplémentaires
Trucs & astuces

a) Mutualisation de l'ouverture de la connexion

Souvent, la connexion est ouverte en début de script php et fermée à la fin (étapes 1, 2 et 7).

Entre les deux, on pourra ouvrir plusieurs requêtes, les lire, modifier le contenu des tables, etc. ...

b) Indépendance de l'application et de la base

Autre pratique très courante et conseillée : Mettre les appels à la base de donnée dans un fichier PHP séparé.

On pourra alors changer facilement de base de données, mutualiser des fonctions complexes entre plusieurs pages

Ceci nous emmène petit à petit vers un modèle MVC (modèle-vue-contrôleur) en mettant les accès à la base de données dans un/des fichiers séparés de l'application.