This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/includes/kohana/modules/userguide/guide/fr-fr/tutorials.databases.md
2011-05-03 09:49:01 +10:00

11 KiB

Base de données

Kohana 3.0 intégre un robuste module permettant de travailler avec les base de données. Par défauut, le module supporte MySQL et PDO.

Le module base de données est inclus par défaut dans votre installation de Kohana 3.0 mais n'est pas activé. Pour l'activer, éditez le fichier application/bootstrap.php et modifiez l'appel à [Kohana::modules] pour y inclure le module base de données:

Kohana::modules(array(
    ...
    'database' => MODPATH.'database',
    ...
));

Configuration

Aprés activation du module, il vous faut préciser les paramètres de configuration permettant à votre application de se connecter à la base de données. Un exemple de fichier de configuration peut être trouvé sous modules/database/config/database.php.

La structure d'un groupe de configuration pour une base de données, appelé instance, est de cette forme:

string INSTANCE_NAME => array(
    'type'         => string DATABASE_TYPE,
    'connection'   => array CONNECTION_ARRAY,
    'table_prefix' => string TABLE_PREFIX,
    'charset'      => string CHARACTER_SET,
    'profiling'    => boolean QUERY_PROFILING,
),

[!!] Plusieurs instances différentes de ces configurations peuvent être définies dans le fichier de configuration.

La compréhension de l'ensemble de ces paramètres est importante:

INSTANCE_NAME
nom personnalisé de l'instance. Il est obligatoire d'avoir au moins une instance appelée "default".
DATABASE_TYPE
type de base de données. Valeurs acceptées: "mysql" et "pdo".
CONNECTION_ARRAY
options de connection spécifiques au type de base de données choisis. Ces options sont explicités plus bas.
TABLE_PREFIX
prefixe qui sera ajouté à tous les noms de table par le constructeur de requêtes.
QUERY_PROFILING
activer le profiling des requêtes.

Exemple

L'exemple ci-dessous est composé de 2 connections MySQL, la première locale et l'autre distante:

return array
(
    'default' => array
    (
        'type'       => 'mysql',
        'connection' => array(
            'hostname'   => 'localhost',
            'username'   => 'dbuser',
            'password'   => 'mypassword',
            'persistent' => FALSE,
            'database'   => 'my_db_name',
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'profiling'    => TRUE,
    ),
    'remote' => array(
        'type'       => 'mysql',
        'connection' => array(
            'hostname'   => '55.55.55.55',
            'username'   => 'remote_user',
            'password'   => 'mypassword',
            'persistent' => FALSE,
            'database'   => 'my_remote_db_name',
        ),
        'table_prefix' => '',
        'charset'      => 'utf8',
        'profiling'    => TRUE,
    ),
);

Options de connection

Chacun des types de base de données possède des options différentes de connection.

MySQL

Les options de connection MySQL sont les suivantes:

Type Option Description Valeur par défaut
string hostname Hôte hébergeant la base localhost
integer port Numéro de port NULL
string socket Socket UNIX NULL
string username Utilisateur NULL
string password Mot de passe NULL
boolean persistent Connections persistantes FALSE
string database Nom de base de la base kohana

PDO

Les options de connection PDO sont les suivantes:

Type Option Description Valeur par défaut
string dsn Source PDO localhost
string username Utilisateur NULL
string password Mot de passe NULL
boolean persistent Connections persistantes FALSE

!! Si vous utilisez PDO et n'êtes pas sûr de la valeur du dsn, veuillez consulter PDO::__construct.

Connections et Instances

Chaque groupe de configuration est accessible en tant qu'instance de base de données. On accède à une instance en appelant [Database::instance]:

$default = Database::instance();
$remote  = Database::instance('remote');

Pour se déconnecter de la base de données, il suffit de détruire l'objet correspondant:

unset($default, Database::$instances['default']);

Si vous souhaitez déconnecter l'ensemble des instances d'un coup alors écrivez:

Database::$instances = array();

Ecrire des requêtes

Il existe 2 manières d'écrire des requêtes dans Kohana. La manière la plus simple est d'utiliser le constructeur de requête, via [DB::query]. Ces requêtes sont appelées des "requêtes préparées" ou prepared statements et permettent l'échappement automatique des paramètres de la requête.

La seconde manière est d'appeler directement les méthodes voulues.

[!!] Toutes les requêtes sont executées via la méthode execute, qui prend en paramètre un objet base de données ou un nom d'instance. Pour plus d'informations, consultez [Database_Query::execute].

Requêtes préparées

L'utilisation de requêtes préparées permet d'écrire des requetes SQL manuellement tout en échappant les paramètres de la requête automatiquement permettant ainsi de se prémunir contre les injections SQL. La création d'une requête est simple:

$query = DB::query(Database::SELECT, 'SELECT * FROM users WHERE username = :user');

La méthode [DB::query] créé un objet [Database_Query] et permet un chainage des méthodes. La requête contient un paramètre :user que l'on peut assigner comme suit:

$query->param(':user', 'john');

[!!] Les noms de paramètre peuvent être nimporte quelle chaine de caractères puisqu'elles sont remplacées en utilisant la fonction strtr. Il est vivement recommandé de ne pas utiliser de signe dollars ($) pour éviter toute confusion.

Si vous souhaitez afficher la requête SQL qui va être exécutée, il vous suffit de caster l'objet en chaine de caractères comme suit:

echo Kohana::debug((string) $query);
// Affichera:
// SELECT * FROM users WHERE username = 'john'

Vous pouvez aussi ré-assigner :user ultérieurement en appelant [Database_Query::param]:

$query->param(':user', $_GET['search']);

[!!] Pour assigner plusieurs paramètres à la fois, vous pouvez utiliser [Database_Query::parameters].

Une fois chacuns des paramètres de votre requête assignés, l'exécution de la requête se fait via:

$query->execute();

Enfin, il est aussi possible d'assigner un paramètre à une variable passée par référence. Cela peut s'avérer très utile lors de l'exécution de la même requête plusieurs fois avec des paramètres différents:

$query = DB::query(Database::INSERT, 'INSERT INTO users (username, password) VALUES (:user, :pass)')
    ->bind(':user', $username)
    ->bind(':pass', $password);

foreach ($new_users as $username => $password)
{
    $query->execute();
}

Dans l'exemple ci-dessus, les variables $username and $password sont changées à chacune des itérations de la boucle foreach. Cela s'avére très puissant et peut vous permettre d'alléger votre code.

Construction de requêtes

La création dynamique de requêtes en utilisant des objets et des méthodes de classe permet de créér des requêtes sans avoir de connaissances sur le langage SQL. Le constructeur se charge d'échapper les noms de table et colonnes mais aussi les valeurs des paramètres des requêtes.

[!!] A ce jour, Kohana ne dispose pas de moyens de combiner les requêtes préparées et la construction dynamique de requêtes.

SELECT

Chaque type de requête en base de données est représenté par une classe, chacunes possédant ses propres méthodes. Par exemple, pour créér une requête SELECT, utilisez [DB::select]:

$query = DB::select()->from('users')->where('username', '=', 'john');

Par défault, [DB::select] sélectionnera toutes les colonnes (SELECT * ...), mais vous pouvez aussi spécifier ces colonnes:

$query = DB::select('username', 'password')->from('users')->where('username', '=', 'john');

L'exemple ci-dessus illustre aussi la puissance du chainage de méthodes qui permet en une seule ligne de spécifier les paramètres de sélection, la table et les critères de filtrage via la méthode where. De la même manière que précédemment, si vous souhaitez afficher la requête SQL qui va être exécutée, il vous suffit de caster l'objet en chaine de caractères comme suit:

echo Kohana::debug((string) $query);
// Affichera:
// SELECT `username`, `password` FROM `users` WHERE `username` = 'john'

Notez que tout est échappé correctement et c'est là l'un des grands avantages de l'utilisation du constructeur de requêtes.

La création d'alias AS se fait comme ci-dessous:

$query = DB::select(array('username', 'u'), array('password', 'p'))->from('users');
// Requête exécutée:
// SELECT `username` AS `u`, `password` AS `p` FROM `users`

INSERT

Pour insérer des enregistrements dans la base de données il faut utiliser [DB::insert]:

$query = DB::insert('users', array('username', 'password'))->values(array('fred', 'p@5sW0Rd'));
// Requête exécutée:
// INSERT INTO `users` (`username`, `password`) VALUES ('fred', 'p@5sW0Rd')

UPDATE

La modification d'un enregistrement en base se fait via [DB::update]:

$query = DB::update('users')->set(array('username' => 'jane'))->where('username', '=', 'john');
// Requête exécutée:
// UPDATE `users` SET `username` = 'jane' WHERE `username` = 'john'

DELETE

Pour supprimer un enregistrement, il faut utiliser [DB::delete]:

$query = DB::delete('users')->where('username', 'IN', array('john', 'jane'));
// Requête exécutée:
// DELETE FROM `users` WHERE `username` IN ('john', 'jane')

Fonctions spécifiques

Il est commun d'utiliser des fonctions spécifiques de base de données telles que COUNT. Le constructeur de requête vous permet de les utiliser de 2 manières. La première est la suivante:

$query = DB::select(array('COUNT("username")', 'total_users'))->from('users');

Ca ressemble beaucoup à l'aliasing AS mais notez que le nom de colonne est entouré de doubles quotes. A chaque fois qu'un nom de colonne est entouré de doubles quotes, alors seules les parties entourées seront échappées. Cette requête générerait le SQL suivant:

SELECT COUNT(`username`) AS `total_users` FROM `users`

Expressions complexes

De temps à autre on a besoin d'écrire des requêtes contenant des expressions complexes. Dans ce cas, cette expression sera créé via [DB::expr]. Une expression est prise telle quelle par la méthode et de ce fait aucun échappement n'est fait.