1 PHP Première application WEB

Dans ce TP nous allons créer une application web Utilisant le modèle MVC sans utiliser de framework. Néanmoins, nous allons sélectionner quelques packages disponibles afin de gérer la partie ‘frontend’ plus facilement.

1.1 Architecture du projet

Nous allons mettre en oeuvre une architecture de notre projet qui facilite la recherche des classes de notre application et qui permette l’intégration de classes de librairies tiers.

Dans le modèle MVC on retrouve :

  • Le modèle qui donne une représentation des données utilisées dans notre application. Les données sont généralement stockées dans une base de données. Dans notre TP nous allons utiliser le système de gestion de base de données MySQL et l’ORM Doctrine pour établir le dialogue entre notre application et la base de données. Doctrine est la librairie utilisée par Symfony.

  • Les vues qui affichent dans le navigateur les réponses aux requêtes. La librairie Twig sera utilisée comme librairie tiers qui génère des pages HTML à partir de template. Cela permet de séparer l’aspect visuel et le code pour le traitement. Twig est une version équivalente du moteur de template Twig utilisé dans Symfony

  • Le contrôleur analyse les requêtes, aiguille vers le code (Contrôleur spécifique) pour traiter la requête. Le contrôleur récupère les données nécessaires pour répondre à la requête et construit la vue qui sera renvoyée au navigateur. Dans notre cas le contrôleur utilisera le moteur de template Twig L’acteur qui permet facilement d’aiguiller la requête vers le bon contrôleur s’appelle un routeur. La librairie miladrahimi/phprouter va nous permettre de mettre un routeur autonome et disposant de nombreuses possibilités.

A l’aide de PhpStorm, créez un nouveau projet ProjetBiblio et créez à la racine un répertoire src.

Créez à la racine de votre projet un fichier composer.json à l’aide de la commande composer init.

Ajoutez au fichier composer.json une référence au code source de votre projet (choisir un préfixe) qui se trouvera dans le répertoire src.

Voici un exemple de propriété autoload :

Vous devez fixer un préfixe (_vendor_) pour votre code. Par exemple \IutLens\Biblio

Ajouter à votre projet les dépendances à l’aide de la commande composer require :

  • D’une part :
    • Le moteur de templates : twig/twig
    • l’ORM Doctrine : doctrine/orm
    • analyseur de syntaxe yaml : symfony/yaml
    • Le routeur : miladrahimi/phprouter
  • D’autre part :
    • Le framework de formatage : twbs/bootstrap,
    • La librairie javascript : components/jquery,
    • Une police de caractères : components/font-awesome et
    • L’interpréteur de texte markdown : michelf/php-markdown

1.2 Le modèle

Dans cette section nous allons mettre en place la couche modèle. Notre application assurera toutes les opérations de base d’une application CRUD (_Create_, Read, Update, Delete).

Notre modèle est essentiellement composé de la classe Auteur et Livre dont voici le listing :

Vous aurez noté les annotations doctrine qui permettent de faire le mapping entre le monde objet de PHP et le monde des bases de données relationnelles.

A l’aide de doctrine, il est possible de créer les tables dans la base de données.

  1. Création d’un fichier bootstrap.php à la racine du projet qui définit la base de données utilisée

  2. Création d’un fichier cli-config.php à la racine du projet

  3. Doctrine met à votre disposition des commandes pour créer, modifier, supprimer les tables de la base de données.

Dans le répertoire src/Modele, ajoutez les fichiers Auteur.php et Livre.php.

A la racine de votre projet, créez le fichier bootstrap.php et cli-config.php.

A l’aide d’une commande doctrine, créez les tables auteurs et livres dans votre base de données.

1.2.1 Ajouter des données dans les tables

Nous allons placer dans les tables créées des données aléatoires. Pour cela vous allez ajouter dans votre projet deux librairies supplémentaires à l’aide des commandes suivantes :

Pour automatiser la génération, nous allons utiliser un fichier de commandes load-fixtures.php qui sera plaçé dans le répertoire racine.

Et créer les classes qui génèrent de façon aléatoire, des enregistrements dans les tables :

Ajouter des données dans les tables auteurs et livres en utilisant la commande `load-fixtures.php.

1.2.2 Modification du modèle

Nous avons de ce projet deux entités : les auteurs et les livres, nous allons ajouter une association entre ces deux entités : EcritPar. Nous allons considérer qu’un livre est écrit par un auteur et qu’un auteur peut écrire plusieurs livres. C’est une association de type “Un vers plusieurs”. Voici le modèle de notre système d’informations :

A l’aide de l’ORM doctrine il est possible de gérer ce type d’association et d’autres, voir la documentation de doctrine.

Nous allons modifier les classes modèles pour intégrer l’association qui relie les deux entités.

Modifiez le modèle des tables auteurs et livres.

Ajouter des données aléatoires dans les tables auteurs et livres en utilisant la commande load-fixtures.php.

1.2.3 Accès aux données

1.2.4 Première page web

L’interpréteur PHP dispose d’un serveur web de développement, nous allons l’utiliser dans la suite du TP pour développer notre application web. Ce serveur web s’exécute sur votre machine (localhost) et il attente des requêtes sur le port 8080 par défaut. C’est une version simple d’un serveur d’applications comme apache ou encore nginx.

Pour lancer ce serveur de développement, utilisez la commande suivante :

ou

Lance un serveur web dont la racine est le répertoire courant (le symbole ‘.’ après l’option -t ) qui écoute sur le port 8080 ici. L’Url http://localhost:8080 va exécuter le code présent dans le fichier index.php.

Ecrire un script listeAuteursWeb.php qui affiche l’ensemble des auteurs contenues dans la base dans une page web.

Tester votre script http://localhost:8080/listeAuteursWeb.php.

1.3 Mise en oeuvre du moteur de templates

La réalisation des vues représente un travail important lors du développement d’une application web. Ce travail se décompose en deux parties

  • Le style, l’organisation des données, ce que les spécialistes appellent la charte graphique, qui est réalisée par des graphistes. Une connaissance du langage CSS associée au langage de balises HTML est requise.
  • Insertion des données qui répondent à la requête. C’est le travail de l’informaticien de retrouver les informations, il utilise pour cela un langage de programmation (en particulier PHP).

Un site web utilise, en général, une charte, un style qui est partagé par l’ensemble des pages. Il existe des librairies qui mettent en oeuvre ce qu’on appelle un moteur de templates. L’idée est de définir une charte dans un template (un modèle) et de permettre l’ajout de paramètres (similaire au format de la fonction sprintf() déjà utilisée, mais ici pour une page HTML).

1.3.1 Utilisation du moteur de templates Twig

Parmi les moteurs de templates nous avons retenu Twig car c’est celui que sera utilisé dans le framework Symfony.

  1. Il faut ajouter le moteur Twig dans votre projet

  2. Configurer l’exécution du moteur de templates. Comme cette opération ne doit être faite qu’une seule fois, nous allons créer une classe Twig qui met en oeuvre le patron de conception Singleton. Voir le listing suivant pour un exemple d’implémentation de la classe Twig.

    Dans le code on précise que les vues (templates) seront placées dans le répertoire templates (ici comme la classe se trouve dans le répertoire src/Singleton pour respecter le namespace, les vues seront placées dans le répertoire templates à la racine du projet).

  3. Créer un template.

    Un template est une page HTML classique contenant des directives Twig qui seront interprétées par le moteur de templates. Pour avoir la liste compléte des directives, voir la documentation Twig.

    Voici un exemple de template auteurs.html qui affiche une liste des auteurs.

    Dans la page on utilise la directive {% for ... %} qui fonctionne comme l’instruction foreach en PHP et la syntaxe {{ }} qui permet d’afficher des données PHP dans notre template en utilisant la notation pointée.

    Le fichier style.css dans le répertoire public/css contient les instructions suivantes :

  4. Utilisation du template.

    Pour utiliser le template, on appelle la méthode render avec deux paramètres :

    1. le nom du template
    2. un tableau associatif des données utilisées dans le template.

    Voici un exemple qui utilise le template auteurs.php

1.3.2 Pour aller plus loin avec Twig

1.3.2.1 Les variables

Les variables permettent les échanges entre le langage PHP et le moteur de template. Il est possible d’accéder aux propriétés d’un objet en utilisant la notation pointée ou la notation clé/valeur d’un tableau associatif.

{{obj.prop}}
{{obj['prop']}}

Il est possible d’affecter une valeur à une variable dans un bloc de code :

{% set var = 'valeur' %}
{% set tab = [1,3,5] %}

1.3.2.2 Les filtres

Twig introduit la notion de filtre qui permet de modifier la valeur d’une variable. Les filtres peuvent s’enchaîner

{{ nom | upper }} {# Transforme en majuscule #}
{{ liste | join(', ') }} {# Transforme un tableau d'éléments en une chaîne de caractères d'éléments séparés par des virgules #}
{% filter upper  %}
  Ce texte sera transformé en majuscules.
{% endfilter %}

1.3.2.3 Les fonctions

Twig propose des fonctions prédéfinies comme range(). Voir la documentation pour avoir la liste.

1.3.2.4 Les structures de contrôle

  • Le for

    <h1>Members</h1>
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
  • Le if

    {% if users|length > 0 %}
        <ul>
            {% for user in users %}
                <li>{{ user.username|e }}</li>
            {% endfor %}
        </ul>
    {% endif %}

1.3.2.5 L’inclusion de parties de template

1.3.2.6 L’héritage de template

Dans un template il est possible de définir des blocs. Ces blocs pourront éventuellement être remplacés dans le cas d’un héritage pour extension.

Dans le listing base.html qui suit, les blocs head, title, content et footer sont définis.

Le listing du fichier index.html qui suit donne un hétitage du template base.html.

  • extends permet d’indiquer le template hétité.
  • Le bloc title aura pour contenu Index
  • Le bloc head aura pour contenu celui défini dans base.html ({{ parent() }})
  • Le bloc content aura pour contenu celui indiqué ici sans reprendre le contenu hérité
  • Le bloc footer restera le même que celui défini dans base.htmlcar il n’a pas été redéfini ici.

Nous allons mettre en place notre page standard. * Le fichier master.html

Mettre à jour les dépendances dans votre projet pour permettre l’utilisation de Twig, bootstrap, ….

Voir les librairies qui sont indiquées en introduction du TP en laissant de côté pour le moment les librairies miladrahimi/phprouter.

Créez les fichiers :

  • master.html
  • header.html
  • footer.html

Dans le répertoire templates à la racine de votre projet.

Le fichier master.html devra contenir une partie variable.

Vous pouvez partir des fichiers exemples donnés plus haut dans le texte et les adapter à votre goût

En utilisant les fichiers templates que vous venez de créer répondre aux questions suivantes :

Ecrire le script listeAuteursTwig.php qui liste les auteurs présents dans la base de données

Ecrire le script creeAuteur.php qui ajoute un auteur dans la base de données

1.4 Mise en oeuvre du routeur

Une application web qui met en oeuvre un modèle MVC utilise une entrée unique qui dispatche les requêtes vers la bonne partie du code à exécuter. Pour dispatcher les requêtes, un mécanisme de routage est utilisé. La encore, il existe plusieurs librairies qui propose une implémentation d’un routeur. Dans la suite du TP nous allons utiliser la librairie miladrahimi/phprouter.

Un mécanisme de communication normalisée entre le routeur et le code à exécuter permettra de gérer les paramètres et le contenu des requêtes. La librairie zendframework/zend-diactoros implémente la norme PSR-7 qui propose une interface pour représenter les messages (requêtes et réponses) HTTP.

1.4.1 Utilisation d’un routeur dans notre application

Nous allons créer un script index.php dans le répertoire racine du projet qui sera le point d’entrée de notre application.

Dans ce script nous allons créer une instance de la classe Router proposée par la librairie miladrahimi/phprouter. L’instance de la classe Router nous permettra de créer des routes (aiguillages) entre une URL et une action. Par exemple :

Dans l’exemple deux routes ont été déclarées :

  • / qui exécutera la fonction index de la classe Welcome.
  • /welcome qui exécutera la fonction welcome de la classe Welcome.

Les fonctions exécutées ont pour rôle de produire la réponse à la requête, en général une page HTML. Voici le code de ces fonctions :

Dans le code donné, on utilise le moteur de templates Twig pour produire le code HTML.

  1. La fonction index utilise la vue hello.html qui utilise une variable visiteur.

    Voici le code de la vue hello.html qui utilise les fichiers master, header, footer utilisés dans la section précédente :

  2. La fonction welcome utilise la vue infohtml qui utilise une variable content.

    Ici on utilise un fichier au format markdown dans le répertoire public à la racine du projet. Le contenu du fichier welcome.md peut être récupéré ici. On utilise la librairie michelf/php-markdown et la classe MarkdownExtra pour transformer le fichier welcome.md en code HTML.

    Le code du script info.html est le suivant :

1.4.2 Utilisation de paramètre dans la route

Il est possible de donner un paramètre dans la route. Ce paramètre pourra devenir un argument de la fonction associée à la route. Par exemple :

Utilise le paramètre id qui pourra être un argument de la fonction show

1.4.3 Utilisation du contenu de la requête

Il est possible de transmettre le contenu de la requête comme argument de la fonction associée à une route. Par exemple :

Utilise le paramètre id qui pourra être un argument de la fonction show

Ici l’argument $request contient les données de la requête. La fonction affiche une réponse au format Json.

Mettre à jour les dépendances dans votre projet pour permettre l’utilisation du routeur, de l’interface des messages HTTP, ….

Créer une classe AuteursController dans le fichier AuteursController.php du répertoire src/Controleur

Dans la classe AuteursController créer un constructeur qui fait le lien entre la base de données et la classe

Dans la classe AuteursController créer les fonctions :

  • index() qui liste les auteurs de la base de données.
  • show($id) qui affiche les détails d’un auteur La fonction sera utilisée pour valider une demande de suppression d’un auteur.
  • create() qui affiche le formulaire de création d’un auteur.
  • store($request) qui vérifie la saisie du formulaire (à l’aide de la fonction valideAuteur), ajoute l’auteur dans la base de données et renvoie vers l’affichage de la liste des auteurs si la saisie est correcte ou renvoie vers la création d’un auteur sinon.
  • edit($id) qui affiche le formulaire de modification d’un auteur.
  • update($request, $id) qui vérifie la saisie du formulaire (à l’aide de la fonction valideAuteur), modifie l’auteur dans la base de données, renvoie vers l’affichage de la liste des auteurs si la saisie est correcte ou renvoie vers la modification d’un auteur sinon.
  • destroy($id) qui supprime un auteur de la base de données.
  • valideAuteur($request, &$auteur) qui vérifie que les champs du formulaire ont été saisis correctement (présence obligatoire des champs) et affecte les valeurs saisies dans le formulaire à la variable $auteur donnée en argument de la fonction.

Dans le répertoire templates créer les templates :

  • create.html qui affiche un formulaire de saisie d’un auteur.
  • edit.html qui affiche un formulaire de modification d’un auteur.
  • show.html qui affiche un auteur et les livres qu’il a écrit.
  • auteurs.html qui affiche la liste des auteurs dans la base de données.

 

IUT de Lens Département Informatique

2018