Énoncé 7 : Le framework PHP léger FPL
Introduction
Durée
2 heures 45
Mots-clés
Constructeur, réflexion, annotations, classe, interface, injection de dépendance, design pattern.
Objectifs
Le développement MVC est devenu aujourd’hui quasi incontournable et de nombreux frameworks sont disponibles pour PHP, tels que Yii, Cake, Laravel, Symfony et Zend framework. S’ils proposent tous des fonctionnalités très utiles au développement d’un site web, leur conception est avant tout holistique. Autrement dit, ils ne sont pas conçus pour être combinés ou utilisés en partie seulement.
C’est ce qui nous a orientés vers la mise au point de ce framework PHP FPL, en proposant une architecture MVC basique et sans imposer de fonctionnalités de haut niveau, de façon à favoriser l’apprentissage de PHP en tant que tel.
Le code source du framework PHP léger FPL illustre des aspects du langage assez étendus, des simples algorithmes de parcours de tableaux jusqu’aux annotations PHP. Ce chapitre étudie la structure du framework et propose de réaliser des extensions.
Prérequis
Pour valider les prérequis nécessaires, avant d’aborder le TP, répondez aux questions ci-après :
1. |
Qu’est-ce qu’une interface (au sens langage de programmation) ? |
|
|
a. |
Une page web |
|
b. |
Une classe intermédiaire entre le contrôleur et la base de données |
|
c. |
Un contrat de développement |
|
d. |
Un ensemble de méthodes définies par leur signature et sans implémentation |
2. |
Comment reconnaît-on le constructeur d’une classe ? |
|
|
a. |
Il s’appelle init() |
|
b. |
C’est la méthode qui initialise les valeurs par défaut |
|
c. |
C’est une méthode appelée __construct() |
|
d. |
C’est le code qui instancie la classe |
3. |
Qu’est-ce qu’un design pattern ? |
|
|
a. |
Une expression régulière type |
|
b. |
Une solution de conception générique et standardisée |
|
c. |
Un modèle de présentation graphique |
|
d. |
Un style de documentation du code |
4. |
Quel est le mot-clé pour implémenter une interface ? |
|
|
a. |
implements |
|
b. |
extends |
|
c. |
use |
|
d. |
inherit |
5. |
Qu’est-ce que l’API Reflection ? |
|
|
a. |
Un moyen de décrire et de manipuler les classes au moment de l’exécution |
|
b. |
Une technique pour router les requêtes HTTP |
... |
Énoncé 7.1 Structure du framework
Durée estimative : 30 minutes
Ce TP a pour objectif d’identifier les classes principales et les points d’entrée du framework FPL. On rappelle que le serveur HTTP Apache transfère toutes les requêtes .do au fichier router.php.
Modifiez le fichier router.php (situé dans application/) de façon à afficher les variables $route, $target_action et $model. Interrompez l’exécution du script après cet affichage. Testez le script à l’aide de l’URL http://localhost/teamup/application/mazone-moncontroller-monaction.do?key1=value1&key2=value2.
Rétablissez après ce test l’exécution normale du script router.php.
Affichez le chemin du script contenant le code source du contrôleur. Effectuez le test puis rétablissez le script original.
Étudiez la méthode FPLGlobal::process_result() qui appelle process_view_result(). Combien de templates de vue peuvent être traités ?
En s’inspirant des types de ActionResult existants, comment ajouter un nouveau type XmlResult ?
Énoncé 7.2 La fabrique de contrôleurs et l’injection de dépendances
Durée estimative : 30 minutes
Le contrôleur est une classe dérivant de baseController. Cette classe est instanciée à chaque requête en .do et la méthode portant le nom de l’action est invoquée. Le module chargé de ces opérations est une fabrique, du nom d’un design pattern standard. La fabrique utilise la programmation dynamique pour instancier la classe et invoquer la méthode action.
Au fil des TP, il apparaît que les ressources engagées par telle ou telle action (des instances de service, de DAO…) concernent généralement plusieurs actions au sein du même contrôleur. En programmeur avisé, nous serions tentés d’initialiser ces objets au niveau du constructeur, tel que c’est d’ailleurs pratiqué dans les classes Service qui appellent les différentes méthodes d’un DAO (cf. EvenementService).
Le présent exercice consiste à déclarer les ressources à fournir au contrôleur au moment de son instanciation, à l’aide d’annotations. Cette technique est appelée injection de dépendances. Les dépendances sont les ressources attendues par le contrôleur. En le réalisant de façon externe au code - à l’aide...
Énoncé 7.3 Intégrer du scripting dans les vues
Durée estimative : 30 minutes
Le but du design pattern MVC est de séparer les responsabilités dans la production d’une page web HTML. Autrement dit, la logique spécifique est consignée dans le contrôleur tandis que la vue ne se préoccupe que de problématiques de présentation. Pour un peu, on affirmerait qu’un minimum de programmation est nécessaire pour mettre au point une vue (c’est oublier l’appel des actions, des services web, et le code JavaScript). Ce TP tente d’illustrer ce principe en supprimant autant que possible l’usage de scripts de type <?php echo expression ?>. Nous allons remplacer ces instructions par des substitutions de variables déclenchées par la syntaxe {{ expression }}.
Créez une classe ViewScript dans le framework FPL et incluez-la dans le fichier main.php. Définissez trois propriétés publiques, $view_source, $view_context et $view_html. La première constitue l’entrée du processus de scripting, elle contient le code HTML et des appels de variables selon la syntaxe {{ variable }}. La seconde propriété est un tableau associatif contenant les variables qui seront appelées par le fragment HTML. La troisième propriété...
Énoncé 7.4 Ajouter des traces
Durée estimative : 45 minutes
Le langage PHP permet d’imprimer aisément n’importe quel message ou variable à l’aide de la commande echo. Oui, mais cette impression sort « n’importe où » dans le flux HTML, par exemple. Et si le script génère autre chose que du texte, les conséquences d’un echo mal maîtrisé s’avèrent désastreuses. Pour couronner le tout, le debogueur ne fonctionne qu’en environnement PHP sans Apache.
Il est temps d’ajouter un système de log dont la restitution appelée trace est activable à la demande ou en différé.
Ajoutez dans le framework un fichier trace.php. Définissez dans ce fichier une classe avec quatre constantes correspondant à autant de niveaux de journalisation :
class TraceLevel {
public const LEVEL_VERBOSE = 0;
public const LEVEL_INFO = 1;
public const LEVEL_WARNING = 2;
public const LEVEL_ERROR = 3;
}
Déclarez dans le fichier trace.php une interface TraceWriter. Les implémentations de cette classe seront le canal d’enregistrement des différentes traces (parmi ces canaux, on trouve la session PHP, la base de données, le fichier). Le paramètre...
Énoncé 7.5 Une interface pour visualiser les traces
Durée estimative : 30 minutes
Quand l’affichage des traces ne peut pas se faire sur la « page » demandée, par exemple si le type MIME n’est pas text/HTML, il faut pouvoir relire les traces en différé pour analyser le fonctionnement du programme. C’est précisément l’objet de ce TP.
Ajoutez dans l’interface TraceWriter et dans son implémentation une méthode clear_trace() qui efface les traces de la mémoire.
Ajoutez dans la classe TraceListener une méthode statique clear_trace().
Créez dans TraceListener une méthode statique get_all_trace_to_html(). Cette méthode doit présenter les traces par session HTTP, en affichant une seule fois l’URL, puis en donnant ligne à ligne le détail des traces. Elle ressemble donc à la méthode get_trace_to_html mais ne possède pas de filtre sur la session ou sur le niveau de journalisation et doit gérer des « ruptures ». Prévoyez des styles Bootstrap pour une meilleure lisibilité.
Sous le dossier racine du framework comfpl, créez un répertoire /trace et ajoutez-y deux fichiers : index.php et config.php. Recopiez le paramétrage du bundle du fichier application/config.php dans comfpl/trace/config.php....