19 octobre 2021 173.263K

Formation Laravel : Migrations

1. Création et connexion à la base de données

Avant d’entamer cette partie consacrée à la gestion de la base de données nous allons voir comment créer et connecter notre base de données à notre projet Laravel. Commençons donc par créer notre base de données. Pour ceux sur mac comme moi vous devez vous rendre dans la library mysql de votre MAMP voici le chemin :

/Applications/MAMP/Library/bin/mysql --host=localhost -uroot -proot

Ici –u (user) me permet de rentrer mon identifiant ‘root’ et –p (password) mon mot de passe.

Ensuite pour créer une base de données vous devez entrer la commande :

create database NomDeMaBaseDeDonnée;

Ici je vais appeler ma base de données ‘Tuto-Laravel’

create database tuto_laravel;

Voilà nous avons créer notre base de données ! Maintenant nous devons la connecter à notre projet Laravel.

Ouvrez donc les fichiers suivants :
• /config/database.php
• /.env (situé à la racine de votre projet)

<?php

use Illuminate\Support\Str;

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */

    'default' => env('DB_CONNECTION', 'mysql'),

    /*
    |--------------------------------------------------------------------------
    | Database Connections
    |--------------------------------------------------------------------------
    |
    | Here are each of the database connections setup for your application.
    | Of course, examples of configuring each database platform that is
    | supported by Laravel is shown below to make development simple.
    |
    |
    | All database work in Laravel is done through the PHP PDO facilities
    | so make sure you have the driver for your particular database of
    | choice installed on your machine before you begin development.
    |
    */

    'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            'url' => env('DATABASE_URL'),
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
            'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
        ],

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', '/Applications/MAMP/tmp/mysql/mysql.sock'),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        'pgsql' => [
            'driver' => 'pgsql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
            'schema' => 'public',
            'sslmode' => 'prefer',
        ],

        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
        ],

    ],

En ouvrant le fichier database.php vous remarquez qu’il s’agit en réalité d’un enorme tableau. Via ce tableau Laravel voud permet de vous connecter à divers types de bases de données (sqlite, mysql, pgsql, sglsrv). Dans ce cours j’utiliserai mysql.
Vous voyez également que certaines valeurs font appel à une fonction global env() et le premier paramètre passé dans cette fonction correspondant à une constante définit dans le fichier .env qui correspond à votre d’environnement.

C’est quoi un environnement ? Pourquoi ne pas directement mettre mes valeurs dans le fichier database.php ?

Un environnement est un environnement de travail, où vous avez vos propres mécanismes. Cela est très utile lorsque vous travaillez à plusieurs sur un même projet. En effet, pour reprendre l’exemple de la connexion à la base de données vous pouvez très bien avoir vos propres identifiants, appeler votre base de données différemment etc… que votre collègue. De la même manière que vous n’utilisez pas forcément les mêmes stylos que votre collègue de travail pour écrire sur une feuille.

Illustration environnement - Walker Spider

Donc si vous avez bien suivi vous devez rentrer vos valeurs dans le fichier .env

APP_NAME='Tuto-Laravel'
APP_ENV=local
APP_KEY=base64:MhfjMkyBLpdZmYpD5lLBdmLIbEmfR61ijAng4IcJcpQ=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

Pour les AppleMan qui utilisent MAMP nous avons une petite donnée à ajouter. Quand vous lancez votre MAMP une page d’accueil s’ouvre dans votre navigateur pour vous diriger vers votre server et base de données que vous pouvez retrouver via ce bouton “Open WebStart page” sur le launcher de l’application :

Mamp - Launcher

Ou directement via ce lien si vous êtes un peu perdu ^^ : http://localhost:8888/MAMP/?language=French Vous arrivez donc sur cette page :

Mamp webpage

Et vous remarquez que MAMP vous donne des instructions pour pouvoir vous connecter notamment un ‘socket’ que vous allez devoir insérer dans votre .env comme valeur de la constante DB_SOCKET ainsi que les autres informations de connexions à votre base de données :

APP_NAME='Tuto-Laravel'
APP_ENV=local
APP_KEY=base64:MhfjMkyBLpdZmYpD5lLBdmLIbEmfR61ijAng4IcJcpQ=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_SOCKET='/Applications/MAMP/tmp/mysql/mysql.sock'

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

Voilà ! Votre base de données est maintenant connectée à votre projet Laravel 😀

2. Que sont les Migrations ?

Alors avant de vous attaquer avec de nouveaux termes, expliquons ce que sont les migrations.

Les migrations sont une sorte de carnet de bords de toutes les modifications qui peuvent être effectuées dans l’organisation de votre base de données (création d’une table, ajout, suppression ou renommage de colonne dans une table etc…).

Vos migrations sont des fichiers php que vous pouvez retrouver directement dans vos dossiers, elles se situent dans le dossier : /database/migrations/

En vous rendant dans ce dossier vous découvrez que 2 migrations existent déjà. Une pour la création de la table users et une pour la table password_resets.

Arborescence Laravel - Dossier migrations

Vous pouvez ouvrir la migration de la création de la table users pour voir comment cela fonctionne.


<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
        * Run the migrations.
        *
        * @return void
        */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
        * Reverse the migrations.
        *
        * @return void
        */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}


Attention ici depuis la version 5.8 la méthode pour déclarer les primary column (les id) est bigIncrements(), avant cette version la méthode était increments().

3 Class sont utilisées ici :
• la Class Migrations qui est une Class abstraite que notre Class CreateUsersTable extends qui permet de récupérer le nom de la migration.
• la façade Schema, qui nous permettra, comme son nom l’indique, de gérer le schéma de notre base de données. Si vous avez bien suivi le chapitre précédent vous savez déjà comment fonctionne une façade. En vous rendant donc sur ce fichier vous pourrez trouver la Class Builder dans le namespace suivant :

\Illuminate\Database\Schema\Builder

Vous y trouverez les différentes méthodes que vous pouvez utiliser pour schématiser votre base de données.

• Ensuite vous avez la Class Blueprint qui vous permet de manipuler vos tables.

« Blueprint » (« impression en bleu » en anglais) est un anglicisme très utilisé dans les domaines du dessin industriel, ce sont des reproductions de plan détaillé.
Voyez donc cette Class comme l’outil vous permettant de réaliser un plan détaillé d’une objet (l’objet étant, ici, une table de votre base de données).

N’hésitez pas à regarder plus en détails les différentes méthodes de ces 2 dernières Class afin d’avoir une vue d’ensemble sur toutes les possibilités qui s’offrent à vous au cours de la construction de votre base de données.

Concernant les méthodes de la Class CreateUsersTable il n’y en a que 2 :
• la méthode up() qui permet d’ajouter de nouvelles tables, colonnes, index etc…
• la méthode down() qui permet de faire un « retour en arrière » de toutes les opérations effectuer par la méthode up().

Dans notre exemple ici avec ‘CreateUsersTable’ voici ce que l’on demande :

• dans la méthode up(), crée une table ‘users’ avec les colonnes suivantes :
– ‘id’ qui sera en auto incrémentation
– ‘name’ qui sera une chaîne de caractère
– ‘email’ qui sera aussi une chaîne de caractère mais également unique. C’est-à-dire qu’il ne pourra y avoir 2 fois la même valeur dans cette colonne. – ‘email_verified_at' qui sera un timestamp (une date) et qui aura la valeur par défaut null
– ‘password’ qui sera encore une fois une châine de caractère
– la méthode rememberToken() qui retourne ceci (cf Class Blueprint) :

public function rememberToken()
{
    return $this->string('remember_token', 100)->nullable();
}

Le deuxième paramètre de la méthode string étant la limite de caractère (ici 100).
– Et enfin la fonction timestamp() qui retourne ceci (cf Class Blueprint) :

public function timestamps($precision = 0)
{
    $this->timestamp('created_at', $precision)->nullable();
    $this->timestamp('updated_at', $precision)->nullable();
}

Maintenant que nous avons vu en détail la construction de cette migration ‘CreateUsersTable’ retournons dans la console et lançons la commande suivante depuis la racine de notre projet Laravel :

php artisan migrate

Voilà ! Vos migrations ont été effectuées et les modifications de votre base de données ont été réalisées. Retournons dans notre base de données mysql et allons checker ça :

use tuto_laravel;

Ici le nom de ma DB est tuto_laravel

puis :

describe users;
CLI mysql database

Vous pouvez voir que notre table ainsi que ses colonnes ont bien été créées.

Pour les personnes qui ne sont pas très à l’aise avec la console vous pouvez bien évidemment aller checker tout ça via phpMyAdmin accessible depuis votre navigateur.

3. Créer une nouvelle migration

Nous avons vu comment envoyer une nouvelle migration dans notre base de données mais celles-ci étaient déjà créées.

Pour créer une nouvelle migration il vous suffit de rentrer la commande :

php artisan make:migration nom_de_ma_migration

En voyant les 2 fichiers de migration de base de Laravel vous pouvez voir que le framework a une certaine convention de nommage concernant ses fichiers de migration. On peut y voir un timestamp suivi du nom de la migration, le tout séparé par des undescores. On appelle cette convention de nommage le « Snake case » (ou bien Underscore case).
Donc ! Lors de la création de votre migration vous aurez à taper le nom de votre migration ainsi. Pas besoin, en effet, de taper le timestamp, Laravel sans occupera pour vous. Ce timestamp au début de vos fichiers vous permet d’avoir un rangement chronologique et précis dans le temps.

Après avoir créé votre migration vous pouvez commencer à mettre en place votre table.

Comme vous le souhaitez. Pour l’exemple nous allons créer une table ‘posts’.

php artisan make:migration create_posts_table --create=posts

Avec l’option –create on precise que nous voulons créer une table nommée ‘posts’ ce qui nous permettra d’avoir un fichier de migration un peu plus entamé et nous évitera de taper quelques lignes de codes en plus. ^^

On nous précise que la migration a été créée avec succès. On peut donc se rendre dans notre fichier. Dans cette table posts je veux qu’il y ait
• un titre,
• une description,
• un contenu
• et un auteur

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
        * Run the migrations.
        *
        * @return void
        */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->char('title', 255);
            $table->text('description', 1048);
            $table->text('content');

            $table->timestamps();
        });
    }

    /**
        * Reverse the migrations.
        *
        * @return void
        */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Pour le title j’utilise char() à la place de texte car je veux une limite de caractère. On doit toujours définir la limite avec ce type de colonne. Vous devez donc rentrer en second paramètre le nombre que vous souhaitez. Ici on met 255. Pour les descriptions et le contenu, pas de soucis un simple text() suffit, on ne veut pas limiter les caractères.

Maintenant Je voudrais rajouter un auteur à mon article et le mieux serait de directement relier un user de ma table users et un post ou des posts de ma table posts non ?

Nous allons donc créer une clé étrangère.

4. Créer une clé étrangère

Pour créer une clé étrangère voici ce qu’il faut ajouter à la suite de nos précédentes modifications (‘title’, ‘description’, ‘content’) :

$table->unsignedInteger('user_id');
$table->foreign('user_id')
        ->references('id')
        ->on('users');

On déclare donc notre colonne 'user_id' comme un UNSIGNED INTEGER, ensuite on précise que cette colonne 'user_id' est une clé étrangère qui fait référence (references) à la colonne 'id' de sa table d’origine users (on).

Lorsque vous déclarez une clé étrangère il faut également prévoir comment la drop via la méthode down() :

Schema::table('users', function(Blueprint $table) {
    $table->dropColumn('user_id');
    $table->dropForeign(['user_id']);
});

Bien nous avons vu comment construire nos tables, dans le prochain chapitre nous allons voir comment créer, récupérer, modifier et supprimer les données de notre base.

Besoin d'une formation personalisée ?

Avis

4,9
Rated 4.9 out of 5
Excellent88%
Splendide !12%
Sympa0%
Sans plus0%
Pas terrible0%

Pas de titre

Rated 5 out of 5
15 avril 2024

cool

paul

Pas de titre

Rated 5 out of 5
2 avril 2024
Evelyn

Pas de titre

Rated 4 out of 5
2 avril 2024

Merci beaucoup pour ce cour.

adil

Pas de titre

Rated 5 out of 5
7 mars 2024

super

hajar

Pas de titre

Rated 5 out of 5
21 juin 2023

Merci énormément je suis sur exciter à cause de ce cours

Kassi Patrick