Les bases de données représentent un point clé de l'organisation d'une application web. PHP propose des extensions pour piloter les bases les plus courantes :
Pour ce cours, nous considérerons que vous avez déjà des notions de bases de données, et ne parlerons que de l'intégration des bases de données dans du code PHP.
Notez que nous nous focaliserons sur les bases de données relationelles, mais qu'il existe également d'autre type de bases.
L'interêt du requêtage est d'intéragir dynamiquement avec la base de données, c'est à dire (entre autre):
PHP propose une interface générique pour accéder aux bases de différents types: PDO, pour PHP Data Object.
L'utilité est de faire abstraction du type de la base de données utilisée.
La connexion peut être établie en instanciant un PDO
comme cela:
<?php
/**
* Créer une instance pour communiquer avec la base de données :
* - DSN: Data Source Name
* - Utilisateur
* - Mot de passe
*/
try {
return new PDO(
'mysql:dbname=user;host=127.0.0.1',
'user',
'pass'
);
} catch (PDOException $exception) {
echo 'Erreur: '.$exception->getMessage()
."\n";
exit(1);
}
Les trois paramètres sont le nom de la source des données -et par conséquent le nom
du type de la base de données utilisée-, le nom d'utilisateur et le mot de passe. En cas
d'échec, une exception de type PDOException
sera levée.
Voici un exemple de requêtage utilisant le PDO:
<?php
$pdo = include('connection.php');
$sql = 'SELECT * FROM users';
echo "Utilisateurs :\n";
foreach ($pdo->query($sql) as $row) {
echo '* ';
echo $row['firstname'] . ' ';
echo $row['lastname'] . ' ';
echo '(' . $row['age'] . ' ans)';
echo "\n";
}
Les requêtes utilisant la notation SELECT * FROM ...
peuvent sembler pratiques, mais
elles deviennent vite problématique dans le cas suivant par exemple:
<?php
//...
$query = $pdo->query(
'SELECT * FROM films INNER JOIN
genres ON genres.id = films.genre_id'
);
foreach ($query as $row) {
// Nom du genre, ou du film?
echo $row['nom']."\n";
}
Auparavant, il arivait souvent que les requêtes soient générées à la main par concaténation avec des variables provenant du reste de l'application puis executées comme dans l'exemple précédent. Cette méthode pose cependant plusieurs problèmes :
Pour palier à ces défauts, la préparation de requêtes est maintenant employée:
<?php
$pdo = include('connection.php');
$sql = 'SELECT * FROM users WHERE age > :age';
$query = $pdo->prepare($sql);
$query->execute(['age' => 50]);
echo "Utilisateurs qui ont plus de 50 ans :\n";
foreach ($query->fetchAll() as $row) {
echo '* ';
echo $row['firstname'] . ' ';
echo $row['lastname'] . ' ';
echo '(' . $row['age'] . ' ans)';
echo "\n";
}
L'insertion peut se faire de la même manière que le requêtage:
<?php
$pdo = include('connection.php');
$insert = $pdo->prepare('INSERT INTO users
(firstname,lastname,age) VALUES (?,?,?)');
// Insère 10 Jean Durand de 40 ans
for ($i=0; $i<10; $i++) {
$insert->execute(['Jean', 'Durand', 40]);
}
Le système de PDO
supporte le requêtage transactionnel, c'est à dire
qui permet d'effectuer des actions puis de les intégrer, ou de tout annuler de manière
atomique:
<?php
$pdo = include('connection.php');
// Commence une transaction
$pdo->beginTransaction();
// Actions
$pdo->exec('DELETE FROM users WHERE
age = 40');
$pdo->exec('INSERT INTO users
(firstname,lastname,age) VALUES
("Jean","Durand",40)');
// Commit our rollback, pour confirmer
// ou annuler
$pdo->commit();
//$pdo->rollback();
De cette manière, si quelque chose se passe mal, les requêtes seront toutes annulées, et les états incohérents pourront être évités.