Mars 2023

SAE 203

Réalisation d'un site web avec une base de données MySQL

Couverture
Unités d'enseignement mobilisées
Développer
Apprentissages critiques
AC4102 Produire des pages Web statiques et fluides utilisant un balisage sémantique efficace
AC4103 Générer des pages Web ou vues à partir de données structurées incluant des interactions simples
AC4104 Mettre en ligne une application Web en utilisant une solution d’hébergement standard
AC4105 Modéliser les données et les traitements d’une application Web
AC4106 Utiliser et adapter un modèle d’accès aux données
Présentation

Lors de cette SAE, j'ai réalisé un site web répertoriant différents films et séries.
Il était nécessaire d'avoir au moins 2 tables et un certains nombres de colonnes dans chacune d'entre elles.

Utilisation de l'API TheMovieDB

Afin de récupérer des données, j'ai utilisé l'API de TheMovieDB. Elle m'a permis de récupérer via différentes requêtes HTTP: une liste de films (avec leurs titres, descriptions, la bande-annonce, etc...), les genres associés et les acteurs ayant joué dans ces films.

Exemple de code ayant permis de récupérer les films dans les 20 premières pages

for($i = 1; $i <= 20; $i++) {
  $curl = curl_init();
  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.themoviedb.org/3/discover/movie?language=fr-FR&page={$i}&api_key=xxx",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_POSTFIELDS => "",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);
  curl_close($curl);

  $results = json_decode($response, true);
}

Stockage des données

J'ai utilisé au total 5 tables, la première stockait les films, la seconde les genres et la troisième les acteurs. Les deux dernières servaient de relation entre les tables.

Schéma SQL

Liste de tous les films

Sur la page répertoriant les films, j'ai réalisé un système de pages pour éviter que trop de films apparaissent et ralentissent la page.

$per_page = 50;
$query = $db->prepare("SELECT 
        movies.id as id,
        movies.name as name, 
        movies.description as description, 
        movies.picture as picture,
        movies.duration as duration,
        movies.revenue as revenue,
        movies.budget as budget,
        movies.release_date as release_date,
        GROUP_CONCAT(CONCAT(genres.name, ' (', genres.fg_color, '/', genres.bg_color, ')') SEPARATOR ', ') AS genres FROM movies 
        LEFT JOIN movies_genres ON movies.id = movies_genres.film_id 
        LEFT JOIN genres ON movies_genres.genre_id = genres.id
        GROUP BY movies.id
        LIMIT :limit OFFSET :offset
");
$query->bindValue(':offset', (($_GET['page'] ?? 1) - 1) * $per_page, PDO::PARAM_INT);
$query->bindValue(':limit', $per_page, PDO::PARAM_INT);
$query->execute();
$movies = $query->fetchAll(PDO::FETCH_ASSOC);

displayPagination($_GET['page'] ?? 1, $per_page, '', 'movies', []);

Etant donné que je devais réutiliser ce système pour d'autres pages comme celles du back-office, j'ai créé une fonction réutilisable

function paginationUrlBuilder($page, $search)
{
    return "?page=$page" . ($search !== '' ? "&search=$search" : '');
}

function displayPagination($page, $per_page, $search, $table, $fields)
{
    $fields = implode(' LIKE :search OR ', $fields) . ' LIKE :search';

    $count = $db->prepare("SELECT COUNT(*) FROM $table" . ($fields === ' LIKE :search' ? '' : " WHERE $fields"));
    if ($fields !== ' LIKE :search') {
        $count->bindValue(':search', '%' . $search . '%', PDO::PARAM_STR);
    }
    $count->execute();
    $count = $count->fetchColumn();
    $pages = ceil($count / $per_page);

    echo '';
    if ($page > 1) {
        echo '<<';
        echo '<';
    }
    for ($i = max(1, $page - 5); $i <= min($pages, $page + 5); $i++) {
        $class = '';
        if ($page == $i) {
            $class = 'class="active"';
        }
        echo "$i";
    }
    if ($page < $pages) {
        echo '>';
        echo '>>';
    }
    echo '';
}
Catalogue de films

Optimisation des images

Afin d'optimiser les images, j'ai réalisé une fonction permettant de convertir des fichiers JPEG vers des WEBP en rétrécissant leurs tailles.

function transformToWebp($picture, $path)
{
    $jpeg = imagecreatefromstring($picture);
    $webp = imagecreatetruecolor(imagesx($jpeg), imagesy($jpeg));
    imagecopy($webp, $jpeg, 0, 0, 0, 0, imagesx($jpeg), imagesy($jpeg));
    imagewebp($webp, $path);
}

Voir d'autres réalisations...