Base de données
Introduction
Bow rend l'interaction avec les bases de données extrêmement simple en utilisant le SQL brut, le générateur de requêtes fluide et l'ORM Barry.
Actuellement, Bow prend en charge trois bases de données:
- MySQL
- PostgreSQL
- SQLite
Configuration
La configuration de la base de données de votre application se trouve dans le fichier config/database.php. Dans ce fichier, vous pouvez définir toutes les connexions à vos bases de données. Des exemples de configuration sont fournis pour tous les types de bases de données supportés.
Configuration SQLite
Après avoir créé une nouvelle base de données SQLite à l'aide d'une commande telle que touch var/database.sqlite, vous pouvez facilement configurer vos variables d'environnement (dans le fichier .env.json) pour qu'elles pointent vers cette base de données en utilisant le chemin absolu:
{
"DB_DEFAULT": "sqlite",
"SQLITE_DATABASE": "/absolute/path/to/database.sqlite"
}
Connexions multiples
Lorsque vous utilisez plusieurs connexions, vous pouvez accéder à chaque connexion via la méthode statique connection de la classe Bow\Database\Database::class. Le nom passé à la méthode doit correspondre à l'une des connexions définies dans votre fichier de configuration config/database.php:
use Bow\Database\Database;
$users = Database::connection('sqlite')->select(...);
Ou via le helper db:
$users = db('sqlite')->select(...);
Une fois la configuration modifiée, elle est directement appliquée sur la connexion des modèles. Consultez la documentation ORM pour plus d'informations sur les modèles.
Utilisation de requêtes SQL brutes
Les requêtes brutes sont des requêtes SQL écrites directement sans passer par le Query Builder.
Dans cette section, nous allons utiliser une table nommée pets pour effectuer nos exemples.
Voici la structure de la table pets:
CREATE TABLE `pets` (
id int primary key,
name varchar(200),
color varchar(50)
);
Description des colonnes de la table:
| Colonne | Description |
|---|---|
id | Clé primaire de la table |
name | Nom de l'animal |
color | Couleur de l'animal |
💡 Pour information, un
petest un animal domestique en anglais.
Exécution de requêtes SELECT
Pour exécuter une requête brute de type SELECT, vous devez utiliser la méthode Database::select ou le helper app_db_select. Considérons notre table pets et supposons que nous sommes bien connectés à la base de données.
Exemple pour récupérer toutes les informations de la table pets:
use Bow\Database\Database;
$pets = Database::select('select * from `pets`');
Via helper app_db_select:
$pets = app_db_select('select * from `pets`');
Sélection avec conditions
Voici comment récupérer un enregistrement spécifique de la table pets en utilisant une condition WHERE:
use Bow\Database\Database;
$pets = Database::select('select * from `pets` where id = :id', ['id' => 1]);
Via helper app_db_select:
$pets = app_db_select('select * from `pets` where id = :id', ['id' => 1]);
La méthode app_db_select retourne un array d'objets stdClass ou un tableau vide s'il n'y a aucun résultat. Chaque élément du tableau est un objet contenant les colonnes de la table. Pour plus d'informations sur stdClass, consultez la documentation PHP.
Récupérer une seule ligne
Quand vous attendez exactement un résultat, selectOne retourne un seul
objet (ou null) plutôt qu'un tableau :
use Bow\Database\Database;
$pet = Database::selectOne('select * from `pets` where id = :id', ['id' => 1]);
// Via helper
$pet = app_db_select_one('select * from `pets` where id = :id', ['id' => 1]);
Exécution de requêtes INSERT
Pour exécuter une requête brute de type INSERT, utilisez la méthode Database::insert ou le helper app_db_insert.
Exemple d'insertion d'un enregistrement dans la table pets:
use Bow\Database\Database;
$pet = [
'id' => 1,
'name' => 'Medor',
'color' => 'Green'
];
$inserted = Database::insert('insert into `pets` (id, name, color) values (:id, :name, :color);', $pet);
Via helper app_db_insert:
$pet = [
'id' => 2,
'name' => 'Marshmallow',
'color' => 'White'
];
$inserted = app_db_insert('insert into `pets` (id, name, color) values (:id, :name, :color);', $pet);
La méthode app_db_insert retourne un entier représentant le nombre de lignes insérées.
Insertion multiple
Vous pouvez également insérer plusieurs enregistrements simultanément.
use Bow\Database\Database;
// Liste de plusieurs animaux
$pets = [
[
'id' => 1,
'name' => 'Médor',
'color' => 'Black'
],
[
'id' => 2,
'name' => 'Milou',
'color' => 'White'
]
];
$inserted = Database::insert(
'insert into `pets` (id, name, color) values (:id, :name, :color);',
$pets
);
Via helper app_db_insert:
$updated = app_db_insert(
'insert into `pets` (id, name, color) values (:id, :name, :color);',
$pets
);
Exécution de requêtes UPDATE
Pour exécuter une requête brute de type UPDATE, utilisez la méthode Database::update ou le helper app_db_update.
Exemple de mise à jour d'un enregistrement dans la table pets:
use Bow\Database\Database;
$pet = [
'id' => 1,
'name' => 'Medora',
'color' => 'Purple'
];
$updated = Database::update(
'update `pets` set id = :id, name = :name, color = :color where id = :id',
$pet
);
Via le helper app_db_update:
$pet = [
'id' => 2,
'name' => 'Spark',
'color' => 'Yellow'
];
$updated = app_db_update(
'update `pets` set id = :id, name = :name, color = :color where id = :id',
$pet
);
Exécution de requêtes DELETE
Pour exécuter une requête brute de type DELETE, utilisez la méthode Database::delete ou le helper app_db_delete.
Exemple de suppression d'un enregistrement dans la table pets:
use Bow\Database\Database;
$deleted = Database::delete(
'delete from `pets` where id = :id',
['id' => 1]
);
Via le helper app_db_delete:
$deleted = app_db_delete(
'delete from `pets` where id = :id',
['id' => 2]
);
Exécution de requêtes génériques
Pour exécuter des requêtes autres que SELECT, UPDATE, INSERT ou DELETE (comme ALTER TABLE, CREATE TABLE, etc.), utilisez la méthode Database::statement ou le helper app_db_statement.
use Bow\Database\Database;
Database::statement('alter table `pets` add `owner` varchar(80) default null;');
Via le helper app_db_statement:
app_db_statement('alter table `pets` add `owner` varchar(80) default null;');
Transactions de base de données
Bow offre deux styles de transactions : automatique (callback) et manuelle (begin / commit / rollback).
Transaction automatique avec Database::transaction()
Passez votre logique dans une closure à Database::transaction() : si une
exception est levée, la transaction est annulée (rollback) ; sinon elle est
validée (commit). C'est l'approche recommandée pour la plupart des cas.
use Bow\Database\Database;
$result = Database::transaction(function () {
Database::update('update users set votes = :votes', ['votes' => 1]);
Database::delete('delete from posts');
return 'ok'; // valeur renvoyée par transaction()
});
Database::startTransaction() n'accepte pas de callback : c'est la
méthode bas-niveau qui démarre simplement la transaction. Pour le style
callback, utilisez Database::transaction($callback).
Transaction manuelle
Pour un contrôle plus fin, vous pouvez gérer le cycle vous-même :
use Bow\Database\Database;
Database::startTransaction();
try {
Database::update('update users set votes = :votes', ['votes' => 1]);
Database::delete('delete from posts');
Database::commit();
} catch (\Throwable $e) {
Database::rollback();
throw $e;
}
Les helpers équivalents :
app_db_transaction(); // démarre une transaction (alias de startTransaction)
app_db_commit(); // valide
app_db_rollback(); // annule
app_db_transaction_started(); // bool : transaction en cours ?
Les helpers app_db_transaction(), app_db_commit(), app_db_rollback()
n'acceptent pas d'arguments. Pour le style callback, appelez directement
Database::transaction($callback).
Dernier identifiant inséré
Après une insertion, vous pouvez récupérer la dernière valeur auto-incrémentée :
use Bow\Database\Database;
Database::insert('insert into `pets` (name, color) values (:name, :color)', [
'name' => 'Médor',
'color' => 'Black',
]);
$id = Database::lastInsertId();
// Pour PostgreSQL avec sequence nommée :
$id = Database::lastInsertId('pets_id_seq');
Jointures SQL
Les jointures permettent de combiner des données de plusieurs tables. Considérons les tables suivantes:
create table `authors` (
`id` int primary key,
`name` varchar(200)
);
create table `pets` (
`id` int primary key,
`name` varchar(200),
`color` varchar(50),
`author_id` int default 0
);
Pour effectuer une jointure dans Bow Framework, ouvrez un Query Builder via
Database::table() (ou le helper app_db_table()) puis chaînez join() :
use Bow\Database\Database;
$results = Database::table('pets')
->join('authors', 'authors.id', '=', 'pets.author_id')
->get();
// Via helper
$results = app_db_table('pets')
->join('authors', 'authors.id', '=', 'pets.author_id')
->get();
Vous pouvez ajouter des conditions avec la clause WHERE pour filtrer les résultats:
$results = app_db_table('pets')
->join('authors', 'authors.id', '=', 'pets.author_id')
->where('pets.author_id', 1)
->get();
Vous pouvez chaîner plusieurs jointures pour combiner plus de deux tables.
Par exemple, si nous avons une table countries contenant les pays des propriétaires, et que la table authors devient:
create table `authors` (
`id` int primary key,
`name` varchar(200),
`country_id` int
);
Notre requête avec deux jointures sera:
$results = app_db_table('pets')
->join('authors', 'authors.id', '=', 'pets.author_id')
->join('countries', 'countries.id', '=', 'authors.country_id')
->where('pets.author_id', 1)
->get();
Vous pouvez consulter l'API de la classe Database pour plus d'information.
Il manque quelque chose ?
Si vous rencontrez des problèmes avec la documentation ou si vous avez des suggestions pour améliorer la documentation ou le projet en général, veuillez déposer une issue pour nous, ou envoyer un tweet mentionnant le compte Twitter @bowframework ou sur directement sur le github.