>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
- <title>PHP : Fonctions</title>
+ <title>PHP : expressions régulières, fichiers, sessions</title>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<meta name="copyright"
- content="Copyright © 2013 Kim Nguyễn" />
+ content="Copyright © 2014 Kim Nguyễn" />
<!-- Load jQuery -->
<script src="../jquery-2.0.3.min.js" type="text/javascript" ></script>
</script>
</head>
<body>
- <a href="prog_internet_06.xhtml" class="sws-previous"/>
+ <a href="unix_prog_web_06.xhtml" class="sws-previous"/>
<div class="sws-slide sws-cover sws-option-nofooter">
<h1>Programmation Internet</h1>
<h1>Cours 7</h1>
<a href="http://www.lri.fr/~kn/">http://www.lri.fr/~kn</a>
</div>
- <h1>Définitions de fonctions</h1>
-
- <div class="sws-slide">
- <h1>Fonctions</h1>
- <p>Les fonctions sont déclarées à l'aide du
- mot-clé <tt><em>function</em></tt>. On renvoie des résultats à
- l'aide du mot-clé <tt><em>return</em></tt>.</p>
- <code><![CDATA[
- <?php
- ]]><em>function</em> double ($x)
- <em>{</em>
- <em>return</em> $x + $x;
- <em>}</em>
-
- echo double(10);
- <![CDATA[?>]]>
- </code>
- </div>
-
-
- <div class="sws-slide">
- <h1>Portée des variables locales et globales
- <b style="color:red">⚠</b>
- </h1>
- <div id="cont2" style="width:100%;position:relative;"
- onresize="draw_arrows();" >
- <div id="left2" style="display:inline-block;width:50%; position:relative;
- box-sizing:border-box;
- padding: 0 1em 0 2em;
- border-style:dashed;
- border-width: 0 1pt 0 0;
- border-color:gray; float:left;">
-<code> <?php
- <em style="color:red">$a</em> = 42;
- function add_a($x)
- {
- <span id="leftend" />
- return $x + <em style="color:red">$a</em>;<span id="leftstart" />
- }
- echo add_a(10);
- ?>
-</code>
- </div>
- <div id="right2" style="display:inline-block;
- width:50%; position:relative;
- box-sizing:border-box;
- padding: 0 2em 0 1em;
- vertical-align:text-top;
- ">
-<code > <?php
- <em>$a</em> = 42;<span id="rightend"/>
- function add_a($x)
- {
- <em>global $a</em>;<span id="rightmid"/>
- return $x + <em>$a</em>;<span id="rightstart"/>
- }
- echo add_a(10);
- ?>
-</code>
- </div>
- </div>
-
- <script type="text/javascript">
-
- function overlay(id) {
- var w = $("#" + id)[0].offsetWidth;
- var h = $("#" + id)[0].offsetHeight;
- $("#svg_"+id).remove();
- var paper = Raphael(id, w, h);
- paper.canvas.id = "svg_" + id;
- return paper;
- };
-
- function curve_to(paper, start, end, style) {
- var x1 = $(start)[0].offsetLeft;
- var y1 = $(start)[0].offsetTop;
- var x2 = $(end)[0].offsetLeft;
- var y2 = $(end)[0].offsetTop;
-
- var path_cmd =
- "M" + x1 + " " + y1 + " S" + x1 + " " + y2 + " " + x2 + " " + y2;
- var p1 = paper.path(path_cmd);
- p1.attr(style);
-
- };
-
- function draw_arrows(x) {
-
- var paper = overlay("left2");
- $("#svg_left2").css ( { 'z-index': '2', 'top':'0', 'left':'0', 'position':'absolute' } );
-
- curve_to (paper, "#leftstart", "#leftend", { 'stroke': "red",
- 'stroke-dasharray' : "-",
- 'stroke-width': 2,
- 'arrow-end' : "block-wide-long" });
-
- var paper = overlay("right2");
- $("#svg_right2").css({ 'z-index': '2', 'top':'0', 'right':'0', 'position':'absolute' });
-
- curve_to (paper, "#rightstart", "#rightmid", { 'stroke': "green",
- 'stroke-width': 2,
- 'arrow-end' : "block-wide-long" });
- curve_to (paper, "#rightmid", "#rightend", { 'stroke': "green",
- 'stroke-width': 2,
- 'arrow-end' : "block-wide-long" });
- };
- SWS.Presentation.registerCallback(0, draw_arrows);
- </script>
- <p>Le code de gauche <em style="color:red">affiche 10</em> !
- Les variables ont une portée <em style="color:red">locale</em>
- par défaut. Si <tt>$a</tt> n'est pas définie dans le corps de la
- fonction, sa valeur est <tt style="color:red">NULL</tt>
- (variable non définie). <span >Pour référencer
- des variables globales, on utilise le mot clé <tt><em>global</em></tt>.</span>
- </p>
- </div>
- <div class="sws-slide">
- <h1>Fonction : définition <b style="color:red">⚠</b></h1>
- <p>On peut utiliser une fonction <s>« avant »</s> de la définir :</p>
- <code> <?php
- echo next(10);
- echo <br/>;
-
- function next($x)
- {
- return $x + 1;
- }
- ?></code>
- <p>On définira <em>toujours</em> des fonctions <em>avant</em> de
- les utiliser. On ne peut pas définir deux fonctions avec le même
- nom.
- </p>
- </div>
- <div class="sws-slide">
- <h1>Fonctions : passage par référence</h1>
- <p>On utiliser le modificateur <tt><em>&</em></tt> devant
- un paramètre de fonction pour indiquer que ce dernier est passé
- par référence.</p>
- <div class="twocol">
- <div>
- <code><?php
- function add_a($tab)
- {
- $tab["a"] = 42;
- }
-
- $mytab = array();
- add_a($mytab);
- echo $mytab["a"];
- //<s>n'affiche rien (car NULL ⇝ "")</s>
-?></code>
- </div>
- <div>
- <code><?php
- function add_a(<em>&</em>$tab)
- {
- $tab["a"] = 42;
- }
-
- $mytab = array();
- add_a($mytab);
- echo $mytab["a"];
- //<em>affiche 42</em>
-?></code>
- </div>
-
- </div>
- <p>Lorsque l'on veut <em>modifier</em> un argument de la
- fonction (plutot que de renvoyer une version modifiée, par
- ex. mise à jour d'un tableau, d'une chaîne, …), on doit le
- passer par référence.
- </p>
- </div>
<h1>Manipulation des chaînes et expressions régulières</h1>
<div class="sws-slide">
<h1>Quelques fonctions utilitaires sur les chaînes</h1>
<dd>Retire les caractères blancs en début et en fin de
chaîne.</dd>
<dt><tt>htmlspecialchars($entree)</tt></dt>
- <dd>converti les caractères <tt>&</tt>, <tt>"</tt>,
+ <dd>convertit les caractères <tt>&</tt>, <tt>"</tt>,
<tt>'</tt>, <tt><</tt> et <tt>></tt> en
<tt>&amp;</tt>, <tt>&quot;</tt>,
<tt>&apos;</tt>, <tt>&lt;</tt> et <tt>&gt;</tt>.
utiliser <tt>===</tt> pour tester le résultat).
</p>
<code style="margin: 0em 2em"><?php
- $chaine = "ABCDEFABCDEF";
- echo preg_match(<em>'/ABC/'</em>, $chaine); // affiche 1
- echo preg_match(<em>'/DEF/'</em>, $chaine); // affiche 1
- echo preg_match(<em>'/^ABC/'</em>, $chaine); // affiche 1
- echo preg_match(<em>'/^DEF/'</em>, $chaine); // affiche 0
- echo preg_match(<em>'/ABC$/'</em>, $chaine); // affiche 0
- echo preg_match(<em>'/DEF$/'</em>, $chaine); // affiche 1
- echo preg_match(<em>'/(ABC...)+/'</em>, $chaine); // affiche 1
- echo preg_match(<em>'/[^A-Z]+/'</em>); // affiche 0
- echo preg_match(<em>'/[^A-Z]*/'</em>); // affiche 1 !
- echo preg_match(<em>'/^[^A-Z]*$/'</em>); // affiche 0
+ $chaine = <u>"ABCDEFABCDEF"</u>;
+ echo preg_match(<em>'/ABC/'</em>, $chaine); <span class="sws-pause">// affiche 1</span>
+ <span>echo preg_match(<em>'/DEF/'</em>, $chaine);</span> <span class="sws-pause">// affiche 1</span>
+ <span>echo preg_match(<em>'/^ABC/'</em>, $chaine);</span> <span class="sws-pause">// affiche 1</span>
+ <span>echo preg_match(<em>'/^DEF/'</em>, $chaine);</span> <span class="sws-pause">// affiche 0</span>
+ <span>echo preg_match(<em>'/ABC$/'</em>, $chaine);</span> <span class="sws-pause">// affiche 0</span>
+ <span>echo preg_match(<em>'/DEF$/'</em>, $chaine);</span> <span class="sws-pause">// affiche 1</span>
+ <span>echo preg_match(<em>'/(ABC...)+/'</em>, $chaine);</span> <span class="sws-pause">// affiche 1</span>
+ <span>echo preg_match(<em>'/[^A-Z]+/'</em>, $chaine);</span> <span class="sws-pause">// affiche 0</span>
+ <span>echo preg_match(<em>'/[^A-Z]*/'</em>, $chaine);</span> <span class="sws-pause">// affiche 1 !</span>
+ <span>echo preg_match(<em>'/^[^A-Z]*$/'</em>, $chaine);</span> <span class="sws-pause">// affiche 0</span>
?></code>
</div>
<div class="sws-slide">
<p>Renvoie un tableau avec une case par ligne dans le fichier. Chaque
entrée contient le "\n" terminal.</p>
</div>
+ <h1>En-tête de requêtes HTTP</h1>
+
+ <div class="sws-slide">
+ <h1>Retour sur le protocole HTTP</h1>
+ <ul><li><em>Client : </em>
+<code>GET <em>/~kn/index.html</em> HTTP/1.1
+Host: www.lri.fr
+</code> </li>
+<li><em>Serveur : </em><br/>
+ <code style="display:inline-block;width:60%;vertical-align:top;">HTTP/1.1 200 OK
+Server: nginx/1.4.1 (Ubuntu)
+Date: Sun, 17 Nov 2013 16:44:48 GMT
+Content-Type: <em>text/html</em>
+Content-Length: 2038
+<![CDATA[
+<html>
+ <head><title>Homepage</title> </head>
+ <body>
+ …
+]]>
+ </code>
+<code style="display:inline-block;
+ black;width:30%;vertical-align:top;">} ← <em>code de retour</em>
+
+
+} ← <em>type de contenu</em>
+} ← <em>longueur du contenu</em>
+<span style="font-size:400%;vertical-align:middle;">}</span> <span>←</span> <em>contenu (2038 octets)</em>
+</code>
+</li>
+ </ul>
+ </div>
+
+ <div class="sws-slide">
+ <h1>Retour sur le protocole HTTP (2)</h1>
+ <ul><li><em>Client : </em>
+<code>GET <em>/~kn/fichier.pdf</em> HTTP/1.1
+Host: www.lri.fr
+</code> </li>
+<li><em>Serveur : </em><br/>
+ <code >HTTP/1.1 200 OK
+Server: nginx/1.4.1 (Ubuntu)
+Date: Sun, 17 Nov 2013 16:44:48 GMT
+Content-Type: <em>application/pdf</em>
+Content-Length: 103449
+<![CDATA[
+%PDF-1.2
+%
+8 0 obj
+<</Length 9 0 R/Filter /FlateDecode>>
+stream
+………
+ ]]>
+ </code>
+
+</li>
+ </ul>
+ </div>
+<div class="sws-slide">
+<h1>Modifier le <em>content-type</em> en PHP</h1>
+<p>Fichier <tt>notes_csv.php</tt>:</p>
+<code> <?php<em>
+ header('Content-type: application/csv');
+ header('Content-Disposition: attachement; filename="notes.csv"');</em>
+ echo "Nom, Note\n";
+ foreach ($NOTES as $nom => $note)
+ echo $nom . ", " . $note . "\n";
+
+ ?></code>
+<p class="sws-pause"><b style="color:red">⚠ Attention!</b></p>
+<ul>
+ <li>Les appels à la fonction <em><tt>header()</tt></em> doivent se
+ trouver <s>avant</s> le premier <tt>echo()</tt> du code PHP</li>
+ <li>
+ Le code PHP doit générer (avec <tt>echo()</tt>) du contenu
+ compatible avec le type annoncé (et pas du HTML)
+ </li>
+</ul>
+</div>
+
+<div class="sws-slide">
+<h1>Quelques en-tête utiles</h1>
+<p>En tête utilisés par le serveur dans ses réponses</p>
+<dl>
+ <dt><tt>Content-type</tt></dt><dd>type MIME du contenu envoyé par le
+ serveur</dd>
+ <dt><tt>Content-Disposition</tt></dt><dd>permet de mentionner un nom de
+ fichier : <em><tt>attachment; filname="foobar.baz"</tt></em></dd>
+ <dt><tt>Cache-Control</tt></dt><dd>permet de forcer le client à
+ retélécharger la page: <em><tt>no-cache, must-revalidate</tt></em>
+ </dd>
+ <dt><tt>Last-Modified</tt></dt><dd>date de dernière modification du
+ contenu demandé</dd>
+</dl>
+<p>En tête utilisés par le client dans ses requêtes</p>
+<dl>
+ <dt><tt>Range</tt></dt><dd>permet de ne récupérer qu'un intervale
+ d'octets donné dans un fichier: <em><tt>bytes=500-999</tt></em>
+ </dd>
+ …
+</dl>
+
+</div>
+<div class="sws-slide">
+ <h1>Retour sur le protocole HTTP (3)</h1>
+ <p>On rappelle que HTTP est un protocole <em><i>stateless</i></em>
+ (sans état, <i>i.e.</i> le serveur Web ne conserve pas d'information
+ entre les connexions). Quel problème cela pose-t-il ?</p>
+ <ul >
+ <li class="sws-pause">Pas de partage d'information entre plusieur
+ pages</li>
+ <li class="sws-pause">Pas de mécanisme de reprise sur panne
+ </li>
+ <li class="sws-pause">Pas de persistance de l'information</li>
+ <li class="sws-pause">Pas d'authentification (impossible de savoir
+ que deux connexions successives ont été faites par le même
+ client)</li>
+ </ul>
+ <p class="sws-pause">⇒ difficle de réaliser une « application »
+ moderne répartie sur plusieurs pages</p>
+</div>
+
+<h1>Cookies</h1>
+<div class="sws-slide">
+<h1>Cookies</h1>
+<p>Un <em><i>cookie</i></em> est un paquet de données envoyé par le
+ serveur, stocké par le client (navigateur Web) et renvoyé au serveur
+ lors d'une nouvelle connexion. Les propriétés d'un cookie sont:
+</p>
+<dl>
+ <dt>Son nom</dt><dd>une chaîne de caractères</dd>
+ <dt>Sa valeur</dt><dd>une chaîne de caraceres</dd>
+ <dt>Sa durée de vie</dt><dd>jusqu'à la fin de la « session » ou pour
+ une période donnée</dd>
+ <dt>Son domaine</dt><dd>Le nom du site web émetteur du cookie</dd>
+ <dt>Son chemin</dt><dd>Le sous-répertoire (par rapport à la racine
+ du site) pour lequel le cookie est valide</dd>
+</dl>
+<p><b style="color:red">⚠ Attention!</b> seul le domaine qui a
+ déposé le cookie est capable de le relire</p>
+</div>
+<div class="sws-slide">
+<h1>Cookies en PHP</h1>
+<p>Créer ou mettre à jour un cookie sur le client:</p>
+<code style="text-justify:center">
+ setcookie(<em>$nom</em>, <em>$val</em>, <em>$date</em>);
+</code>
+<dl>
+ <dt><tt>$nom</tt></dt><dd>nom du cookie</dd>
+ <dt><tt>$val</tt></dt><dd>valeur du cookie</dd>
+ <dt><tt>$date</tt></dt><dd>date d'expiration en secondes
+ depuis <i>epoch</i> (1<sup>er</sup> janvier 1970 00:00:00)
+ ou <tt>NULL</tt> pour une expiration automatique.</dd>
+</dl>
+<p>(on peut récupérer le nombre de secondes depuis <i>epoch</i> avec
+ la fonction <tt>time()</tt>).<br/>
+ Exemple:
+</p>
+<code> setcookie("mon_cookie", "42", time() + 3600 * 24 * 30);</code>
+</div>
+<div class="sws-slide">
+<h1>Petite digression sur «<i>epoch</i>» </h1>
+<p>Représenter le temps (une date) dans un programme informatique est
+ quelque chose de compliqué. Quels problèmes cela pose-t-il ?
+</p>
+<ul>
+ <li class="sws-pause">Fuseaux horaires</li>
+ <li class="sws-pause">Conversion de temps (de fuseau)</li>
+ <li class="sws-pause">Taille des entiers (Bug de l'an 2000, de l'an
+ 2038, de l'an 292 277 026 596)</li>
+ <li class="sws-pause">Secondes intercalaires (« <i>leap second</i> »)</li>
+</ul>
+<p>Ce n'est pas encore quelque chose de bien maîtrisé !</p>
+</div>
+<div class="sws-slide">
+ <h1>Cookies en PHP</h1>
+ <p>On peut récupérer la valeur d'un cookie depuis PHP:
+ </p>
+ <code> <em>$_COOKIE["mon_cookie"]</em></code>
+ <p>Un cookie <tt>"foo"</tt> existe (<i>i.e.</i> a été défini
+ auparavant) si une entrée correspondante existe dans le tableau
+ global <em><tt>$_COOKIE</tt></em>. On peut tester qu'une entrée
+ existe dans un tableau avec <em><tt>isset()</tt></em>.
+ </p>
+ <p><b style="color:red">⚠ Attention!</b> </p>
+ <ul>
+ <li>On ne peut pas écrire dans <em>$_COOKIE</em> (par
+ exemple <tt>$_COOKIE["foo"] = 42</tt>), il faut
+ utiliser <em><tt>setcookie()</tt></em>.
+ </li>
+ <li><em><tt>setcookie()</tt></em>
+ utilise <em><tt>header()</tt></em> et doit donc être appelé avant
+ le premier <em><tt>echo()</tt></em> du fichier.
+ </li>
+ <li>Pour effacer un cookie, on peut lui donner une date
+ d'expiration antérieure à l'instant présent (<tt>0</tt> par exemple)</li>
+ </ul>
+</div>
+
+<div class="sws-slide">
+ <h1>Avantages et inconvénients des cookies</h1>
+<ul style="list-style-type:none;">
+ <li class="sws-pause"><b>+</b> stockage persistant</li>
+ <li class="sws-pause"><b>+</b> interface simple d'utilisation (une
+ variable pour la lecture et <tt>setcookie</tt> pour l'écriture)</li>
+ <li class="sws-pause"><b>-</b> limité en taille </li>
+ <li class="sws-pause"><b>-</b> limité en nombre par domaine</li>
+ <li class="sws-pause"><b>-</b> type de donnée limité à des chaînes
+ (on ne peut pas stocker un tableau PHP par exemple)</li>
+<li class="sws-pause"><b>+/-</b> stocké sur le client</li>
+</ul>
+</div>
+<h1>Sessions</h1>
+<div class="sws-slide">
+<h1>Sessions</h1>
+ <p>Une <em>session HTTP</em> est un ensemble de requêtes/réponses HTTP
+ entre un serveur et un <em>même</em> client.<br/>
+ Exemple d'un sondage en ligne:
+ </p>
+ <ol> <li>Le visiteur arrive sur la page <tt>q1.php</tt> en cliquant sur
+ le lien « commencer le sondage » (<em>Début de session</em>)
+ </li>
+ <li> Sur <tt>q1.php</tt>, l'utilisateur coche des choix dans un formulaire et appuie
+ sur un boutton de soumission qui l'envoie sur <tt>q2.php</tt>
+ </li>
+ <li>…</li>
+ <li> Sur <tt>q10.php</tt>, l'utilisateur coche des choix dans un
+ formulaire et appuie sur un bouton de soumission qui l'envoie
+ sur <tt>resultat.php</tt></li>
+ <li> Sur <tt>resultat.php</tt>, le résultat global du sondage (%
+ par question, nombre de participants jusqu'à présent etc...) est
+ affiché (<em>Fin de session</em>)
+ </li>
+ </ol>
+
+</div>
+<div class="sws-slide">
+ <h1>Variables de session</h1>
+ <p>Pour programmer une application Web, on souhaîte avoir accès à
+ des <em>variables de session</em> c'est à dire des variables qui
+ sont:
+ </p>
+ <ul><li>Globale au serveur, et accessibles depuis plusieurs pages
+ PHP différentes</li>
+ <li>Spécifiques à un « utilisateur » (c'est à dire à une session
+ particulière)
+ </li>
+ </ul>
+ <p>Les variables de sessions sont donc propres à chaque client et
+ persistent le temp de la session (le temps de session est décidé par
+ le serveur)</p>
+</div>
+<div class="sws-slide">
+ <h1>Variables de session en PHP</h1>
+ <p>On initie une session avec la fonction:</p>
+ <code> <em>session_start();</em> </code>
+ <p>Une fois appelée, la variable <em><tt>$_SESSION</tt></em>
+ contient un tableau que l'on peut utiliser entre plusieurs
+ pages. Les valeurs contenues dans le tableau persistent jusqu'à la
+ fin de la session. Une session se termine:
+ </p>
+ <ul><li>Quand le client se déconnecte</li>
+ <li>Après un certain temps (« votre session a expiré, veuillez
+ vous reconnecter»)</li>
+ <li>Quand le code PHP
+ appelle <em><tt>session_end();</tt></em></li>
+ </ul>
+<p><b style="color:red">⚠
+ Attention!</b> <em><tt>session_start()</tt></em> doit être appelé
+ avant le premier <tt>echo</tt> du fichier.</p>
+</div>
+<div class="sws-slide">
+ <h1>Variables de session en PHP (2)</h1>
+<code style="border: 2pt dashed gray;margin:5pt;">
+ <?php /* Fichier page1.php */
+ <em>session_start();
+ $_SESSION["Valeur"] = 42;</em>
+ ?>
+ <![CDATA[<html>
+ <body>
+ Veuillez cliquer sur le <a href=]]><em>"page2.php"</em><![CDATA[>lien</a>
+ </body>
+ </html>
+]]></code>
+<code style="border: 2pt dashed gray;margin:5pt;"> <![CDATA[<html>
+ <body>
+ La valeur est <?php]]> <em>echo $_SESSION["Valeur"];</em> <![CDATA[?>
+ <!-- affiche 42 -->
+ </body>
+ </html>
+]]></code>
+</div>
+<div class="sws-slide">
+ <h1>Avantages et inconvénients des session</h1>
+<ul style="list-style-type:none;">
+ <li class="sws-pause"><b>+</b> Informations stockées sur le serveur</li>
+ <li class="sws-pause"><b>+</b> Pas de limite de taille</li>
+ <li class="sws-pause"><b>+</b> Pas limité à des chaînes de caractères</li>
+ <li class="sws-pause"><b>-</b> Valeurs perdues en fin de session</li>
+ <li class="sws-pause"><b>-</b> <s>Nécessite des cookies</s></li>
+</ul>
+</div>
+<div class="sws-slide">
+ <h1>Sessions PHP: détails d'implantation</h1>
+ <div class="twocol">
+ <div><em>Coté client</em><br/>
+<br/>
+<br/>
+<br/>
+<br/>
+<br/>
+<br/>
+<br/>
+<br/>
+<br/>
+Connexion à une page PHP (envoie du cookie ("php_ssid", "12345"))
+
+
+ </div>
+ <div><em>Coté serveur (PHP)</em><br/>
+ <tt>session_start();</tt><br/>
+ - génération d'un ID unique "12345"<br/>
+ - dépot d'un cookie "php_ssid", valeur "12345", durée 10 minutes
+ - création dans un tableau global d'une entrée:<br/>
+ <tt>$_GLOBAL["12345"] = Array();</tt><br/>
+ <br/>
+ <tt>$_SESSION = $_GLOBAL[$_COOKIE["php_ssid"]]</tt>
+ </div>
+ </div>
+</div>
+
+<div class="sws-slide">
+ <h1>Dans la vraie Vie<sup>TM</sup></h1>
+ <p>Mélange de variables de sessions, cookies et bases de données.<br/>
+ Scénario réaliste: site de commerce en ligne
+ </p>
+ <ul>
+ <li>Login/mot de passe stocké dans
+ une <em style="color:blue;">BD</em> </li>
+ <li>Panier courant stocké dans une <em>variable de
+ session</em></li>
+ <li>Login, date de dernière visite, dernière page visitée stockés
+ dans un <em style="color:orange">en cookie</em></li>
+ </ul>
+ <p class="sws-pause">Pourquoi ?</p>
+ <ul>
+ <li><em style="color:blue;">BD</em>: information persistante,
+ côté serveur (mais la mise à jour, récupération de l'info est
+ coûteuse (en temps))
+ </li>
+ <li><em>Variables de sessions</em> : le panier n'a pas forcément
+ besoin d'être conservé entre deux sessions, mais on ne veut pas
+ que le client puisse fabriquer un panier frauduleux
+ </li>
+ <li><em style="color:orange">Cookie</em> : persistante à faible
+ coût (stocké sur le client), ce n'est pas grave si les
+ informations sont perdues ou corrompues
+ </li>
+ </ul>
+
+ </div>
</body>
</html>