PHP, TEMPLATE ET HTTP Développer des application Web
Notion de template 1 Un template est modèle de document, c est-à-dire un document dont la forme est définie, mais dont une partie du contenu est variable. Pour réaliser les parties variables, on insère dans le texte du document des instructions qui permettront au moteur de template de produire le texte variable. On utilise généralement des balises telles que <% et %>, pour séparer les instructions que le moteur de template doit interpréter, du texte qu il doit copier sans changement dans le ou les documents résultants.
Notion de moteur de template 2 Un moteur de templates (template processor) est un programme qui combine un template (modèle) et des données pour produire un ou plusieurs documents. Données... <h1> <?=$titre?> </h1>... Moteur de templates Documents résultants Template (patron) Quelques exemples : ASP.NET, JSP, Apache Velocity
PHP, un langage de template? 3 Le code PHP peut être intégré dans n importe quel fichier de texte grâce aux balises PHP (<?php et?>) À l exécution, les balises PHP sont remplacées par le texte affiché par le code. PHP peut donc être utiliser comme un langage de template et son interpréteur comme un moteur de template.
Exemple de template PHP 4 Fichier guestbook.php <?php // inclut le fichier autoload.php qui contient // les fonctions nécessaires au chargement des // classes utilisée dans le script. require_once('../library/autoload.php'); // appelle la méthode getallmessages définie // dans la classe MessageDAO et qui renvoie // un tableau d objets de type Message. $dao = new \Guestbook\MessageDAO(); $messages = $dao->getallmessages();?> <head> Ce retour à la ligne est <title>livre Copié dans d or</title> la sortie standard Les balises PHP peuvent <h2>livre d or</h2> apparaître n'importe où <div class="message-list> <?php foreach ($messages as $message):?> <div class="message-item" <?php endforeach;?> Cette portion de code ne produit pas de texte id="<?php echo $message->getid();?>"> <?php echo $message->getpseudo();?></br> <?php echo $message->getmessage();?> Pour chaque message, répète la partie du template qui se trouve entre ces deux lignes (ces lignes ne produise pas de texte) <head> <title>livre d'or</title> <h2>livre d'or</h2> <div class="message-list"> <div class="message-item" id="1"> Jean<br> Merci pour toutes ces informations! <div class="message-item" id="2"> Pierre<br> Super site, plein d'informations utiles. <div class="message-item" id="3"> Grégoire<br> Bof... Rien de bien intéressant Interpréteur PHP
Exemple de template JSP 5 Fichier guestbook.jsp <%@ page import="database.*" %> <% // appelle la fonction getallmessage définie // dans le class DAO du package database et qui // renvoie un tableau d objets de type Message. Collection<Message> messages = DAO.getAllMessages(); %> <head> Ce retour à la ligne est <title>livre copié dans d or</title> la sortie standard Les balises JSP peuvent <h2>livre d or</h2> apparaître n'importe où <div class="message-list> <% for(messages : message) { %> <div class="message-item" <% } %> Cette portion de code ne produit pas de texte id="<% out.print(message.getid());%>"> <% out.print(message.getpseudo());%></br> <% out.print(message.getmessage());%> Pour chaque message, répète la partie du template qui se trouve entre ces deux lignes (ces lignes ne produise pas de texte) <head> <title>livre d'or</title> <h2>livre d'or</h2> <div class="message-list"> <div class="message-item" id="1"> Jean<br> Merci pour toutes ces informations! <div class="message-item" id="2"> Pierre<br> Super site, plein d'informations utiles. <div class="message-item" id="3"> Grégoire<br> Bof... Rien de bien intéressant Servlet Container
Remarques 6 Le jeu de caractères de PHP est l ASCII mais en dehors des balises et dans les chaînes de caractères, n importe quel caractère (octet) est transmis tel quel. En conséquence : l encodage de la sortie est le même que celui du fichier source. L encodage du fichier source est sans importance tant que le jeu de caractères est compatible avec l ASCII. Tous les caractères (octets) se trouvant en dehors des balises PHP sont copiés dans la sortie standard, cela inclut les caractères blancs tels que : espaces, tabulations, retours de chariot (CR), fins de ligne (LF) les trois octets du BOM au début d un fichier UTF-8
PHP et HTTP 7 Le but d un script côté serveur est fournir une réponse à une requête HTTP reçue par le server HTTP. Lorsque le serveur HTTP passe un script à l interpréteur PHP, il passe donc également un certain nombre d informations concernant la requête à traiter. Parmi ces informations, les plus utilisées sont : La méthode : $_SERVER[REQUEST_METHOD] Les paramètres de l URL : $_GET Les données d un formulaire : $_POST Les cookies : $_COOKIE
Informations pour une requête GET 8 $_SERVER[REQUEST_METHOD] $_SERVER[REQUEST_URI] $_SERVER[SERVER_PROTOCOL] GET /index.php HTTP/1.1 $_SERVER[HTTP_HOST] Host: localhost Connection: keep-alive Accept: text/html,application/xhtml+xml,[ ] User-Agent: Mozilla/5.0 (X11; Linux x86_64)[ ] Accept-Encoding: gzip,deflate,sdch Accept-Language: fr-fr,fr;q=0.8,en-us;q=0.6,en;q=0.4 getallheaders()
Informations pour une requête POST 9 $_SERVER[REQUEST_METHOD] $_SERVER[REQUEST_URI] $_SERVER[SERVER_PROTOCOL] POST /editors/customers/71 HTTP/1.1 Host: localhost Connection: keep-alive $_SERVER[HTTP_HOST] Content-Length: 117 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,[ ] Origin: http://localhost User-Agent: Mozilla/5.0 (X11; Linux x86_64)[ ] Content-Type: application/x-www-form-urlencoded Referer: http://localhost/~dev/editors/customers/71 Accept-Encoding: gzip,deflate Accept-Language: fr-fr,fr;q=0.8,en-us;q=0.6,en;q=0.4 firstname=th%c3%a9odore&name=aeby&address=rue+d[ ] getallheaders() $_POST
PHP et réponse HTTP 10 Le but d un script PHP est de produire une réponse HTTP, le document (HTML ou autre) n en est que le contenu. L interpréteur PHP ajoute les en-têtes indispensables à la réponse, mais c est la responsabilité du script de spécifier son statut ainsi que certains en-têtes, tels que : Cache-Control Last-Modified, Expires, ETag Pour spécifier des en-têtes, on utilise la fonction header. Cette fonction doit être appelée avant d écrire le premier caractère dans la sortie standard.
Template de réponse HTTP 11 Fichier guestbook.php <?php http_response_code(200); header("content-type: text/html"); header("cache-control: no-cache"); // inclut le fichier autoload.php qui contient // les fonctions nécessaires au chargement des // classes utilisée dans le script. require_once('../library/autoload.php'); // appelle la méthode getallmessages définie // dans la classe MessageDAO et qui renvoie // un tableau d objets de type Message. $dao = new \Guestbook\MessageDAO(); $messages = $dao->getallmessages();?> <head> <title>livre d or</title> <h2>livre d or</h2> <div class="message-list"> <?php foreach ($messages as $message):?> <div class="message-item" id="<?php echo $message->getid();?>"> <?php echo $message->getpseudo();?></br> <?php echo $message->getmessage();?> <?php endforeach;?> Status: 200 OK Content-Type: text/html Cache-Control: no-cache <head> <title>livre d'or</title> <h2>livre d'or</h2> <div class="message-list"> <div class="message-item" id="1"> Jean<br> Merci pour toutes ces informations! <div class="message-item" id="2"> Pierre<br> Super site, plein d'informations utiles. Interpréteur PHP
Séparer PHP et HTML 12 Dans les exemples précédent, le code PHP et le code HTML sont mélangé dans le même fichier. Bien que cela soit du code valide, ce n est pas une bonne pratique pour au moins trois raisons : Les code HTML sont souvent réalisés par des spécialistes du design (souvent non-programmeurs). D une manière générale, on cherche à éviter l utilisation de plusieurs langage dans un même fichier source. Le mécanisme d inclusion (transculsion) permet de facilement séparer le code PHP et le code HTML.
Template HTML en PHP 13 Un template HTML devrait avoir une extension.phtml et ne devrait contenir que du code HTML et le sous-ensemble de PHP suivant : Affichage d une expression n <?=expression?> <?=$variable?> ou <?=$objet->getmembre()?> Structures de contrôle avec la syntaxe alternative n <?php foreach ($list as $element):?> <?php endforeach;?> n <?php while ($expression):?> <?php endwhile;?> n <?php if ($expression):?> <?php endif;?> On utilise l instruction include pour inclure le template et exécuter les instructions PHP qu il contient. Ces règles sont conventionnelles, PHP ne vérifie pas leur application. Une autre option est d utiliser un moteur de template comme Smarty, Twig ou Haml au lieu de PHP.
Exemple de template HTML 14 Fichier guestbook.phtml (template HTML) <head> <title>livre d or</title> <h2>livre d or</h2> <div class="message-list"> <?php foreach ($messages as $message):?> <div class="message-item" id="<?= $message->getid();?>"> <?= $message->getpseudo();?></br> <?= $message->getmessage();?> <?php endforeach;?> Fichier guestbook.php (code uniquement) <?php // On peut utiliser l'inclusion de fichier, // pour séparer le code PHP du template HTML http_response_code(200); header("content-type: text/html"); header("cache-control: no-cache"); require_once('../library/autoload.php'); $dao = new \Guestbook\MessageDAO(); // définition de la variable $messages // utilisée dans le template $messages = $dao->getallmessages(); // inclut le fichier de tempate include('guestbook.phtml'); Status: 200 OK Content-Type: text/html Cache-Control: no-cache <head> <title>livre d'or</title> <h2>livre d'or</h2> <div class="message-list"> <div class="message-item" id="1"> Jean<br> Merci pour toutes ces informations! <div class="message-item" id="2"> Pierre<br> Super site, plein d'informations utiles. Interpréteur PHP