start-databases.md 11.4 KB
Newer Older
Benoît committed
1 2 3
Travailler avec les bases de données
======================

Benoît committed
4 5 6 7
Cette section décrira comment créer une nouvelle page qui affiche des données pays récupérées dans une table de base 
de données nommée `country`. Pour ce faire, vous allez configurer une connexion à une base de données, créer une 
classe [Active Record](db-active-record.md), et définir une [action](structure-controllers.md), et créer une
[vue](structure-views.md).
Benoît committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

Au long de ce tutoriel, vous apprendrez comment :

* Configurer une connexion à une base de données
* Définir une classe Active Record
* Requêter des données en utilisant la classe Active Record
* Afficher des données dans une vue paginée

Notez que pour finir cette section, vous aurez besoin d'avoir une connaissance basique des bases de données.
En particulier, vous devez savoir créer une base de données, et exécuter des déclarations SQL en utilisant un client de
gestion de bases de données.


Préparer la Base de Données <a name="preparing-database"></a>
--------------------

Pour commencer, créez une base de données appelée `yii2basic`, depuis laquelle vous irez chercher les données dans 
votre application.
Vous pouvez créer une base de données SQLite, MySQL, PostgreSQL, MSSQL ou Oracle, car Yii gère nativement de nombreuses
applications de base de données. Par simplicité, nous supposerons que vous utilisez MySQL dans les descriptions qui 
suivent.

Next, create a table named `country` in the base de données, and insert some sample data. You may run the following SQL statements to do so:

```sql
CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `country` VALUES ('AU','Australia',18886000);
INSERT INTO `country` VALUES ('BR','Brazil',170115000);
INSERT INTO `country` VALUES ('CA','Canada',1147000);
INSERT INTO `country` VALUES ('CN','China',1277558000);
INSERT INTO `country` VALUES ('DE','Germany',82164700);
INSERT INTO `country` VALUES ('FR','France',59225700);
INSERT INTO `country` VALUES ('GB','United Kingdom',59623400);
INSERT INTO `country` VALUES ('IN','India',1013662000);
INSERT INTO `country` VALUES ('RU','Russia',146934000);
INSERT INTO `country` VALUES ('US','United States',278357000);
```

A ce niveau, vous avez une base de données appelée `yii2basic`, et dedans, une table `country` comportant trois colonnes, contenant dix lignes de données.

Configurer une Connexion à la BDD <a name="configuring-db-connection"></a>
---------------------------

Avant de continuer, assurons nous que vous avez installé à la fois l'extension PHP 
[PDO](http://www.php.net/manual/fr/book.pdo.php) et le pilote PDO pour la base de données que vous utilisez (c'est
à dire `pdo_mysql` pour MySQL). C'est une exigence de base si votre application utilise une base de données 
Benoît committed
59
relationnelle.
Benoît committed
60

Benoît committed
61
Une fois ces éléments installés, ouvrez le fichier `config/db.php` et modifiez les paramètres pour qu'ils correspondent à votre base de données. Par défaut, le fichier contient ce qui suit :
Benoît committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

```php
<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];
```

Le fichier `config/db.php` est un exemple type d'outil de [configuration](concept-configurations.md) basé sur un 
fichier. Ce fichier de configuration en particulier spécifie les paramètres nécessaires à la création et 
l'initialisation d'une instance de [[yii\db\Connection]] grâce à laquelle vous pouvez effectuer des requêtes SQL 
dans la base de données sous-jacente.

On peut accéder à connexion à la BDD configurée ci-dessus depuis le code de l'application vial'expression 
`Yii::$app->db`.

Benoît committed
83
> Info: Le fichier `config/db.php` sera inclus par la configuration principale de l'application `config/web.php`, 
Benoît committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
  qui spécifie comment l'instante d'[application](structure-applications.md) doit être initialisée.
  Pour plus d'informations, merci de vous référer à la section [Configurations](concept-configurations.md).


Créer un Active Record <a name="creating-active-record"></a>
-------------------------

Pour représenter et aller chercher des données dans la table `country`, créez une classe dérivée d'[Active Record](db-active-record.md) appelée `Country`, et enregistrez la dans le fichier `models/Country.php`.

```php
<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}
```

La classe `Country` étend [[yii\db\ActiveRecord]]. Vous n'avez pas besoin d'y écrire le moindre code ! Simplement avec
le code ci-dessus, Yii devinera le nom de la table associée au nom de la class. 

> Info: Si aucune correspondance directe ne peut être faite à partir du nom de la classe, vous pouvez outrepasser la méthode [[yii\db\ActiveRecord::tableName()]] pour spécifier explicitement un nom de table.

A l'aide de la classe `Country`, vous pouvez facilement manipuler les données de la table `country`, comme dans les bribes suivantes :

```php
use app\models\Country;

// chercher toutes les lignes de la table pays et les trier par "name"
$countries = Country::find()->orderBy('name')->all();

// chercher la ligne dont la clef primaire est "US"
$country = Country::findOne('US');

// afficher "United States"
echo $country->name;

// remplace le nom du pays par "U.S.A." et le sauvegarde dans la base de données
$country->name = 'U.S.A.';
$country->save();
```

> Info: Active Record est un moyen puissant pour accéder et manipuler des données d'une base de manière orientée objet.
Vous pouvez trouver plus d'informations dans la section [Active Record](db-active-record.md). Sinon, vous pouvez 
également interagir avec une base de données en utilisant une méthode de plus bas niveau d'accès aux données appelée 
[Data Access Objects](db-dao.md).


Créer une Action <a name="creating-action"></a>
------------------

Pour exposer les données pays aux utilisateurs, vous devez créer une action. Plutôt que de placer la nouvelle action 
dans le contrôleur `site`, comme vous l'avez fait dans les sections précédentes, il est plus cohérent de créer un 
nouveau contrôleur spécifiquement pour toutes les actions liées aux données pays. Nommez ce contrôleur 
`CountryController`, et créez-y une action `index`, comme suit.

```php
<?php

namespace app\controllers;

use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}
```

Enregistrez le code ci-dessus dans le fichier `controllers/CountryController.php`.

L'action `index` appelle `Country::find()`. Cette méthode Active Record construit une requête de BDD et récupère toutes
les données de la table `country`.
Benoît committed
180
Pour limiter le nombre de pays retournés par chaque requête, la requête est paginée à l'aide d'un objet
Benoît committed
181 182 183 184 185 186 187 188 189 190 191 192 193
[[yii\data\Pagination]]. L'objet `Pagination` dessert deux buts :

* Il ajuste les clauses `offset` et `limit` de la déclaration SQL représentée par la requête afin qu'elle en retourne
  qu'une page de données à la fois (au plus 5 colonnes par page).
* Il est utilisé dans la vue pour afficher un pagineur qui consiste en une liste de boutons de page, comme nous
  l'expliquerons dans la prochaine sous-section.

A la fin du code, l'action `index` effectue le rendu d'une vue nommée `index`, et lui transmet les données pays ainsi que les informations de pagination.


Créer une Vue <a name="creating-view"></a>
---------------

Benoît committed
194
Dans le dossier `views`, commencez par créer un sous-dossier nommé `country`. Ce dossier sera utilisé pour contenir
Benoît committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
toutes les vues rendues par le contrôleur `country`. Dans le dossier `views/country`, créez un fichier nommé
`index.php` contenant ce qui suit :

```php
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->name} ({$country->code})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>
```

La vue a deux sections relatives à l'affichage des données pays. Dans la première partie, les données pays fournies
Benoît committed
217 218
est parcourue et rendue sous forme de liste non ordonnée HTML.
Dans la deuxième partie, un widget [[yii\widgets\LinkPager]] est rendu en utilisant les informations de pagination transmises par l'action.
Benoît committed
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
Le widget `LinkPager` affiche une liste de boutons de pages. Le fait de cliquer sur l'un deux rafraichit les données pays dans la page correspondante.


Essayer <a name="trying-it-out"></a>
-------------

Pour voir comment tout le code ci-dessus fonctionne, utilisez votre navigateur pour accéder à l'URL suivant :

```
http://hostname/index.php?r=country/index
```

![Liste de Pays](images/start-country-list.png)

Au début, vous verrez une page affichant cinq pays. En dessous des pays, vous verrez un pagineur avec quatre boutons.
Si vous cliquez sur le bouton "2", vous verrez la page afficher cinq autres pays de la base de données : la deuxième 
page d'enregistrements.
Benoît committed
236
Observez plus attentivement et vous noterez que l'URL dans le navigateur devient
Benoît committed
237 238 239 240 241

```
http://hostname/index.php?r=country/index&page=2
```

Benoît committed
242
En coulisse, [[yii\data\Pagination|Pagination]] fournit toutes les fonctionnalités permettant de paginer un ensemble de données :
Benoît committed
243 244 245 246 247 248 249 250

* Au départ, [[yii\data\Pagination|Pagination]] représente la première page, qui reflète la requête SELECT de country
  avec la clause `LIMIT 5 OFFSET 0`. Il en résulte que les cinq premiers pays seront trouvés et affichés.
* Le widget [[yii\widgets\LinkPager|LinkPager]] effectue le rendu des boutons de pages en utilisant les URLs créés par 
  [[yii\data\Pagination::createUrl()|Pagination]]. Les URLs contiendront le paramètre de requête `page`, qui représente
  les différents numéros de pages.
* Si vous cliquez sur le bouton de page "2", une nouvelle requête pour la route `country/index` sera déclenchée et 
  traitée.
Benoît committed
251
  [[yii\data\Pagination|Pagination]] lit le paramètre de requête `page` dans l'URL et met le numéro de page à 2.
Benoît committed
252 253 254 255 256 257 258 259 260 261 262
  La nouvelle requête de pays aura donc la clause `LIMIT 5 OFFSET 5` et retournera le cinq pays suivants pour être
  affichés.


Résumé <a name="summary"></a>
-------

Dans cette section, vous avez appris comment travailler avec une base de données. Vous avez également appris comment 
chercher et afficher des données dans des pages avec l'aide de [[yii\data\Pagination]] et [[yii\widgets\LinkPager]].

Dans la prochaine section, vous apprendrez comment utiliser le puissant outil de génération de code, appelé 
Benoît committed
263
[Gii](tool-gii.md), pour vous aider à implémenter rapidement des fonctionnalités communément requises, telles que les 
Benoît committed
264 265 266
opérations Créer, Lire, Mettre à Jour et Supprimer (CRUD : Create-Read-Update-Delete) pour travailler avec les données 
dans une table de base de données. En fait, le code que vous venez d'écrire peut être généré automatiquement dans Yii 
en utilisant l'outil Gii.