phpInfo.netLes ArchivesLes éléPHPants

  
  Accueil
  Trucs & Astuces
  Scripts
  Regex
  Annuaire
  Articles

.
      
 Articles   Utiliser MySQL avec PHP  Par Frédéric BOUCHERY   Mars 2001    »  Introduction
 »  Connexion au serveur de données
 »  Sélection de la base
 »  Requête
 »  Exploitation des requêtes
 »  Fermeture de la connexion
 »  Gestion des erreurs
 »  Conseils
 »  Exemple


Introduction

MySQL est un système de gestion de base de données (SGBD). C'est un ensemble d'applications permettant de manipuler les données (ajout, suppression, modification et lecture), mais aussi de contrôler l'accès.
Les données sont structurées de la manière suivante :

Un ensemble de données connexes regroupées en enregistrement.



Un ensemble d'enregistrements groupés dans une table.



Un ensemble de tables groupées dans une base de données.



L'ensemble des bases de données composant le serveur de données.



Le serveur de données est composé de plusieurs bases de données afin de mieux organiser les données, mais aussi fixer des règles d'accès différentes pour chacune d'entre elles. C'est souvent le cas des hébergeurs qui attribuent une base de données pour chaque site avec des droits d'accès réservés à ce dernier.

Attention : si vous avez votre propre serveur de données, vous pouvez être tenté de créer plusieurs bases pour mieux vous organiser, mais il faut savoir que dans ce cas, vous ne pouvez pas "mixer" (jointure) des données en provenance de tables placées dans des bases différentes.

L'utilisation de MySQL avec PHP s'effectue en 4 temps :

    » Connexion au serveur de données
    » Sélection de la base de données
    » Requête
    » Exploitation des requêtes

On peut ajouter à ça, un 5ème temps facultatif dans le cas d'une connexion simple : fermeture de la connexion.



Connexion au serveur de données

Pour se connecter au serveur de données, il existe 2 méthodes :

    » Ouverture d'une connexion simple avec la fonction mysql_connect
    » Ouverture d'une connexion persistante avec la fonction mysql_pconnect

La deuxième méthode diffère de la première par le fait que la connexion reste active après la fin du script, mais tous les hébergeurs n'autorisent pas cette possibilité, et on a même tendance à penser qu'il n'est pas bon de l'utiliser (Pour plus d'informations, lisez les remarques sur les connexions persistantes de la doc PHP).

Pour se connecter, il faut paramétrer l'adresse du serveur de données ainsi que votre nom d'utilisateur (" login " en anglais) et votre mot de passe (" password " en anglais). En retour, vous obtenez un identifiant. Si l'identifiant est à 0, une erreur s'est produite pendant la phase de connexion. Cette erreur peut venir du fait que l'on ne peut pas joindre le serveur (ex : panne réseau), que le nom du serveur n'est pas bon, que vous n'êtes pas autorisé à accéder à ce serveur ou que votre mot de passe n'est pas correct.
Maintenant, si l'identifiant est différent de 0, tout c'est bien passé et vous êtes connecté au serveur de données.

Remarque : Vous pouvez garder cet identifiant dans une variable, mais si vous n'ouvrez pas d'autres connexions en parallèle, ce n'est pas utile.

Exemple : connexion à une base de données sur " Free " :

<?php

if( mysql_connect( 'sql.free.fr' , 'monchat.moustique' , 'miaou' ) > 0 )
    echo
'Connexion réussie !' ;
else
    echo
'Connexion impossible !' ;

?>


Sélection de la base

En fait, les étapes sélection et requête peuvent être faites en même temps, mais il est plus simple si vous utilisez une seule base, de la sélectionner avant de commencer vos requêtes. Ainsi, toutes les requêtes à venir utiliseront cette base par défaut.
Pour faire cette sélection, utilisez la fonction mysql_select_db et vous lui passez en paramètre, le nom de votre base.
Si la connexion n'aboutit pas, la fonction vous retourne "False" (ou "0" si vous préférez) sinon elle retourne "True".

Remarque : Si cela vous chante, ou si vous avez ouvert plusieurs connexions en parallèle, vous pouvez ajouter un second paramètre qui est l'identifiant de la connexion. Si vous n'en donnez pas, la fonction utilise la dernière connexion ouverte.

Exemple :
Connexion à la base de donnée " ma_base "

<?php

if( mysql_select_db( 'ma_base' ) == True )
    echo
'Sélection de la base réussie' ;
else
    echo
'Sélection de la base impossible' ;

?>


Requête

Maintenant, le plus intéressant, c'est d'accéder aux données, soit pour les lire, soit pour les modifier ou encore les supprimer. Pour faire cela, il n'y a pas de fonctions du genre mysql_read, mysql_write, …etc. En fait, on utilise un langage qui s'appelle le langage SQL (Structured Query Language). Je vous renvoie donc aux différents articles déjà en ligne sur ce site (SQL par l'exemple 1ère (SELECT) et 2ème partie).

Pour envoyer ces requêtes, on peut utiliser 2 fonctions :

    » mysql_query dans le cas où la base de données serait déjà sélectionnée
    » mysql_db_query dans le cas où l'on voudrait sélectionner la base en même temps.

Comme pour la connexion, cette fonction retourne un identifiant qui est à "0" lorsqu'une erreur s'est produite.
Contrairement aux autres fonctions (connexion et sélection), cet identifiant est très important, il est utilisé pour retrouver les données rapatriées par une requête de sélection.

Lorsque l'on fait une requête de sélection, MySQL retourne les données et PHP les place en mémoire. L'identifiant permet donc de retrouver ces données en mémoire. En fin de script, la mémoire est libérée et les données sont donc perdues. Il est possible de libérer la mémoire, pour ne pas surcharger le serveur, avant la fin du script au moyen de la commande mysql_free_result.

Exemple :
On part du principe que la base de données est déjà sélectionnée et on veut avoir des informations sur le membre nommé "moustique" :

<?php

$requete
= "SELECT * FROM membres WHERE pseudo = 'moustique' ";
$resultat = mysql_query( $requete );

?>


Exploitation des requêtes

Suite à une requête de sélection

Après l'exécution d'une requête de sélection, les données ne sont pas "affichées", elles sont simplement mises en mémoire, il faut donc aller les chercher enregistrement par enregistrement et les afficher avec un minimum de traitement.
PHP gère un pointeur de résultat, c'est à dire qu'il repère un enregistrement parmi les autres, et lorsque l'on veut en lire un, c'est celui qui est pointé qui sera retourné.
Lorsque vous utilisez une fonction de lecture, le pointeur est déplacé sur l'enregistrement suivant et ainsi de suite jusqu'à ce qu'il n'y en ait plus.
Les fonctions qui retournent un enregistrement sont : mysql_fetch_row, mysql_fetch_array et mysql_fetch_object et prennent comme paramètre l'identifiant de la requête.
Les 3 exemples suivants partent d'une requête "SELECT nom, prenom, date FROM membres."

» mysql_fetch_row :Cette fonction retourne un enregistrement sous la forme d'un tableau simple.

<?php

    $enregistrement
= mysql_fetch_row( $resultat );
    
// Affiche le champ - nom -
    
echo $enregistrement[0] . '<br>';
    
// Affiche le champ - prenom -
    
echo $enregistrement[1] . '<br>';
    
// Affiche le champ - date -
    
echo $enregistrement[2] . '<br>';

?>

» mysql_fetch_array : Cette fonction retourne un enregistrement sous la forme d'un tableau associatif.

<?php

    $enregistrement
= mysql_fetch_array( $resultat );
    
// Affiche le champ - prenom -
    
echo $enregistrement['prenom'] . '<br>';
    
// Affiche le champ - nom -
    
echo $enregistrement['nom'] . '<br>';
    
// Affiche le champ - date -
    
echo $enregistrement['date'] . '<br>';

?>

» mysql_fetch_object :Cette fonction retourne un enregistrement sous forme d'une structure (objet).

<?php

    $enregistrement
= mysql_fetch_object( $resultat );
    
// Affiche le champ - date -
    
echo $enregistrement->date . '<br>';
    
// Affiche le champ - nom -
    
echo $enregistrement->nom . '<br>';
    
// Affiche le champ - prenom -
    
echo $enregistrement->prenom . '<br>';

?>

Si il n'y a pas ou plus d'enregistrement à lire, ces fonctions retournent "false."
Enfin, si vous voulez savoir combien d'enregistrements ont été retournés par la sélection, vous pouvez utiliser la commande mysql_num_rows qui prend comme paramètre l'identifiant de la requête.

Il existe une autre fonction pour lire des enregistrements, mais je vous déconseille de l'utiliser car elle est beaucoup moins performante, et présente peu d'intérêt, c'est la fonction mysql_result. Je ne la détaille pas, vous pouvez vous reporter à la documentation PHP si vous voulez vraiment l'utiliser !

Exemple :
On affiche le nombre d'enregistrement et on parcourt l'ensemble des données en les affichant au moyen d'une boucle :

<?php

    
echo 'Il y a ' . mysql_num_rows( $resultat ) . ' membre(s)';
    while(
$enregistrement = mysql_fetch_array( $resultat ))
    {
        echo
$enregistrement['nom'] . ' ' . $enregistrement['prenom'];
        echo
' – ' . $enregistrement['date'] . '<br>' ;
    }

?>



Suite à une requête d'insertion

Une requête d'insertion ne retourne pas de donnée en principe, mais il y a une chose que l'on peut exploiter, c'est la valeur d'un champ auto incrémenté.
En effet, si un champ est déclaré "auto incrémenté", il est souvent utile de connaître la valeur de ce champ après l'insertion, c'est le rôle de la fonction mysql_insert_id qui ne prend aucun paramètre et retourne la valeur de la dernière requête d'insertion effectuée.

Exemple :
Suite à une requête d'insertion, on veut afficher le numéro auto incrémenté :

<?php

    
echo "Votre numéro d'identifiant est " . mysql_insert_id();

?>



Suite à une requête de modification
Lorsque l'on change les données en insérant, supprimant ou modifiant, il est possible de connaître le nombre d'enregistrements affectés par la requête. C'est la fonction mysql_affected_rows qui ne prend pas de paramètres comme la fonction mysql_insert_id.
Toutefois, il existe une petite exception : lorsque vous exécutez une commande "DELETE" sans la clause "WHERE", tous les enregistrements sont effacés, mais pour optimiser cette requête, mySQL supprime tout bonnement le fichier et le recrée immédiatement. A partir de ce moment, on n'est pas capable de savoir combien d'enregistrements il y avait avant, et la fonction mysql_affected_rows retourne "0".

Exemple :
Suite à une commande "UPDATE", on voudrait savoir combien de lignes ont été modifiées :

<?php

    
echo mysql_affected_rows() . 'enregistrement(s) modifié(s)';

?>



Fermeture de la connexion

Vous pouvez fermer la connexion au moyen de la fonction mysql_close, mais il est bon de savoir que cette opération sera faite lorsque le script se terminera. C'est donc une opération facultative, à mon goût et c'est pourquoi je n'entrerai pas dans le détail.


Gestion des erreurs

Vous avez vu qu'il était possible de savoir si la requête a fonctionné, mais que faire quand ça ne fonctionne pas ?
D'une manière générale, si la requête n'a pas marché, il y a une erreur dans la syntaxe dans votre requête et il n'est pas très judicieux de continuer le script. Mais avant de quitter brutalement, il est important de pouvoir expliquer ce qui n'a pas marché. Pour cela, on utilise la fonction mysql_error qui ne prend pas de paramètres.
Cette fonction vous indique généralement votre erreur dans la langue de Shakespeare.
Une bonne méthode pour se retrouver facilement est de faire comme suit :

<?php

    $resultat
= mysql_query( $requete )
    or die (
'Erreur dans la requête : ' . $requete . '<br>Avec l\'erreur : ' . mysql_error() );

?>



Conseils

» Variables intermédiaires :

Il est TRES fortement conseillé de ne pas écrire les paramètres de connexion directement dans la fonction car si une erreur survient, PHP va afficher la ligne incriminée, laissant apparaître votre mot de passe aux yeux de tous !
C'est pour cette raison que l'on utilise des variables intermédiaires. Voici un exemple de script

<?php

    $mysqlserver
= 'sql.le_serveur.fr';
    
$mysqlloggin = 'mon_login';
    
$mysqlpassword = 'secret';
    
mysql_connect( $mysqlserver , $mysqlloggin , $mysqlpassword ) ;

?>

De même pour la sélection de la base de données.
L'idéal, c'est de placer ces variables dans un fichiers de configuration protégé par un ".htaccess" (si vous utilisez Apache)

» Opération réccurrente :

Dans la majorité des cas, vous utiliserez toujours la même base de données, sur le même serveur. C'est pour cette raison que je vous conseille d'écrire un script contenant les fonctions de connexion et de sélection :

<?php

    
// Dans ce fichier, vous placez vos paramètres de connexion
    // [ voir : Variables intermédiaires ]
    // $mysqlserver , $mysqlloggin , $mysqlpassword et $mysqlmaindb
    
require 'connexion.conf.php3' ;

    
// connexion au serveur de données
    
@mysql_connect( $mysqlserver , $mysqlloggin , $mysqlpassword )
    or die(
'Connexion au serveur de données impossible' ) ;

    
// Sélection de la base de données
    
@mysql_select_db( $mysqlmaindb )
    or die(
'Sélection de la base de donnée impossible' ) ;

?>

Remarque : Vous avez vu que j'utilise le préfixe @ qui a pour rôle de désactiver les rapports d'erreur. En effet, si une erreur survient (lors d'une connection par exemple), un rapport d'erreur est généré, et si vous n'avez pas fixé le "error_reporting" à 0, un "warning" est affiché par PHP, ce qui n'est pas toujours du plus bel effet ! [ Merci Métabaron pour cette précision oubliée :-) ]

» Contrôle des erreurs :

Il n'est pas rare, dans les phases de développement, de faire des erreurs dans une requête SQL, et si vous ne faites pas de contrôle, vous risquez d'avoir des petits soucis pour les retrouver. Je conseille TRES FORTEMENT de créer une fonction qui fait la requête et le contrôle en même temps :

<?php

    
// Cette fonction fait la même chose que "die" mais
    // vous pouvez faire
    // une mise en forme qui correspond plus à votre site.
    
function erreur( $message )
    {
        echo
$message ;
        exit ;
    }

    
// fonction pour faire des requêtes
    
function requete( $requete )
    {
        if(
$resultat = mysql_query( $requete )) return $resultat ;
        
erreur( "Erreur dans la requête : $requete<br>" . mysql_error() ) ;
    }

?>

» Synthèse :

Aux vues de ces conseils, on peut enviseager de les synthétiser sous forme d'un script que l'on utilisera dans chacun de nos développements, ce qui donnerait :
connexion.conf.php3
<?php

    $mysqlserver
= 'sql.le_serveur.fr';
    
$mysqlloggin = 'mon_login';
    
$mysqlpassword = 'secret';
    
$mysqlmaindb = 'ma_base';

?>

database.inc.php3
<?php

    
// Cette fonction fait la même chose que "die" mais vous pouvez
    // faire une mise en forme qui correspond plus à votre site.
    
function erreur( $message )
    {
        echo
$message ;
        exit ;
    }

    
// emplacement des données de connexion
    
require 'connexion.conf.php3';

    
// connexion au serveur de données
    
@mysql_connect( $mysqlserver , $mysqlloggin , $mysqlpassword )
    or
erreur( 'Connexion au serveur de données impossible' ) ;

    
// Sélection de la base de données
    
@mysql_select_db( $mysqlmaindb )
    or
erreur( 'Sélection de la base de donnée impossible' ) ;

    
// fonction pour faire des requêtes
    
function requete( $requete )
    {
        if(
$resultat = mysql_query( $requete )) return $resultat ;
        
erreur( "Erreur dans la requête : $requete<br>" . mysql_error() ) ;
    }

?>



Exemple

Voici un exemple d'utilisation de MySQL avec PHP. On utilisera le script de connexion à la base de données que l'on a écrit dans les "conseils".
Dans notre exemple, on fait un affichage de la liste des membres d'un site.

<?php

    
// Connexion à la base de données
    
require 'database.inc.php3';
    
// Requête
    
$requete = 'SELECT nom, prenom, date FROM membres';
    
// Execution de la requête
    
$resultat = requete( $requete );
    
// Récupération du nombre d'enregistrements
    
$nombre_membre = mysql_num_rows( $resultat );
    
// Affichage du nombre de membres
    
echo 'Il y a ' . $nombre_membre . ' membre' . ($nombre_membre > 1 ? 's' : '' );
    echo
"<br>\n";
    
// boucle d'affichage
    
while( $row = mysql_fetch_array( $resultat ) ) {
        echo
$row['prenom'] . ' ' . $row['nom'] . ' - ' . $row['date'];
        echo
"<br>\n";
    }

?>

Vous pouvez remarquer que l'on utilise directement les tableaux retournés et que l'on ne fait pas de choses du genre :

<?php

    $nom
= $row['nom'];
    
$prenom = $row['prenom'];
    echo
$prenom.' '.$nom;

?>

Pourquoi utiliser une variable intermédiaire alors que l'on a déjà la valeur dans le tableau ? [ Merci Perrich pour cette remarque :-) ]

Synseo