L2 MIASHS 2016-2017 - Déroulement réel des cours

La « pensée » du lendi 20 novemb' 2017 , 23h40m52s :
Adam a peu souffert du complexe d'Oedipe.
  -- Le Chat (Philippe Geluck)

Semaine du lendi 9 janbier 2017 : CM n°1 (Cumul=1,5h)

Avant-propos

HTML5

  • Quelques balises de base (dans leur version la plus simple) valables dans toutes les versions de (x)HTML(5): <h1>, <h2>, etc., <p>, <ul>, <ol>, <li>, <span>, <div> (section 2.6 du poly).
  • En-tête d'une page HTML5
    Pour passer les tests du W3C une page doit avoir la structure suivante :
    <!DOCTYPE html>
    <html>
      <head lang="fr">
        <meta charset="utf-8">
        <title>Un titre si possible intelligent...</title>
      </head>
      <body>
        ....
        ....
      </body>
    </html>
    
    Contrairement à xHTML, l'utilisation des majuscules & minuscules n'est pas différenciée en HTML5.
  • Présentation de l'exercice (site01x.html, site02x.html et site03x.html).
Dernière modification : 20/4/2017

Semaine du lendi 16 janbier 2017 : TD n°2 (Cumul=2h)

Avant-propos

HTML5

  • En-tête d'une page HTML5
    Pour passer les tests du W3C une page doit avoir la structure suivante :
    <!DOCTYPE html>
    <html>
      <head lang="fr">
        <meta charset="utf-8">
        <title>Un titre si possible intelligent...</title>
      </head>
      <body>
        ....
        ....
      </body>
    </html>
    
    À comparer avec celui nécessaire pour xHTML visible dans la section 2.5 du poly.
    Contrairement à xHTML, l'utilisation des majuscules & minuscules n'est pas différenciée en HTML5.
  • Application directe
    Réalisez les trois pages site01x.html, site02x.html et site03x.html. Vos pages doivent absolument passer avec succès les tests du W3C. Vous ne vous occuperez bien entendu pas du tout de la présentation : ce sera fait avec l'étude des CSS.
    Remarque : Si vous voulez les modifier en y intégrant vos propres loisirs, réels ou inventés, vous pourrez trouver les noms d'un grand nombre de collections sur les pages http://capsules.musa.free.fr/Collections05.html et http://christophe.giordani.free.fr/collections.htm.
    Sur les machines des salles pédagogiques, vous enregistrez vos pages sous votre répertoire www et vous les visualisez dans le navigateur à l'adresse
    http://hebergement-peda.univ-lille3.fr/~votreLogin/chemin
    chemin est le chemin relatif vers votre page depuis www
  • Suite...
    Sur la première page, les mots « Licence MIASHS » devront être un lien vers une page institutionnelle de votre choix, en rapport avec la licence MIASHS (la page de l'université, cette page-ci, la page de l'UFR MIME, etc.), tandis que les mots « Machin Chose » (ou ce que vous aurez mis à la place) devront être un lien vers la page d'accueil que votre voisin est en train de réaliser en même temps que vous.

Acid Test

Si vous ne comprenez pas pourquoi les informaticiens vous cassent la tête en essayant de vous expliquer qu'Internet Explorer c'est vraiment pas bon, utilisez l'Acid Test, pour tester la compatibilité de votre navigateur avec les standards du W3C (l'organisme mondial chargé d'élaborer et de gérer les standards du web) :

CSS

Dernière modification : 20/4/2017

Semaine du lendi 16 janbier 2017 : CM n°2 (Cumul=3h)

Gestion des couleurs en HTML et CSS

CSS

  • Feuille de style, séparation données-présentation, syntaxe d'une feuille de style.
  • Unités de longueurs : em, ex, cm, in, pc, px, %, pt.
Dernière modification : 20/4/2017

Semaine du lendi 23 janbier 2017 : TD n°3 (Cumul=4h)

Gestion des couleurs en HTML et CSS

CSS

Exercice

Dernière modification : 20/4/2017

Semaine du lendi 23 janbier 2017 : CM n°3 (Cumul=4,5h)

Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

CSS

  • Propriétés des liens
    a:link { /* pour les liens sans particularités */ }
    a:visited { /* pour les liens déjà visités */ }
    a:hover { /* pour les liens survolés par le pointeur de la souris */ }
    a:visited:hover { /* pour les liens déjà visités, survolés par le pointeur de la souris */ }
    a:active { /* au moment du clic */ }
    Rappel : hover existe pour n'importe quelle balise.)
  • Signature : http://mammouthland.free.fr/cours/css/cours5.php
  • Feuilles de style différentes pour l'écran et l'impression.
    Deux solutions :
    • Deux fichiers (ou plus) différents, et mettre dans l'en-tête de la page :
      <link rel="stylesheet" href="fichierCSSgénérale" media="all" />
      <link rel="stylesheet" href="fichierCSSécran" media="screen" />
      <link rel="stylesheet" href="fichierCSSimprimante" media="print" />
    • Un seul fichier et le structurer ainsi :
      @media all {
      /* Ce qui concerne tous les medias */
      }
      @media print {
      /* Ce qui concerne uniquement l'impression */
      }
      @media screen {
      /* Ce qui concerne uniquement l'écran */
      }

Bonus

  • Les bugs d'Internet Explorer, les contourner, les utiliser : voir le chapitre 14 du poly.

HTML5

  • Nouveautés en HTML5 : nous nous concentrerons sur les nouvelles balises qui apportent de la sémantique au texte. Vous pourrez comprendre la philosophie derrière HTML5 en vous plongeant dans le livre Dive into HTML5 : http://diveintohtml5.info/. (Voir la page https://fr.wikipedia.org/wiki/HTML5 pour une simple liste de toutes les nouveautés.)
    • main : Définit le contenu principal de la page, il doit être unique dans la page.
    • section : Section générique regroupant un même sujet, une même fonctionnalité, de préférence avec un en-tête, ou bien section d'application web.
    • nav : Section possédant des liens de navigation principaux (au sein du document ou vers d'autres pages).
    • article : Section de contenu indépendante, pouvant être extraite individuellement du document ou syndiquée (flux RSS ou équivalent), sans pénaliser sa compréhension.
    • aside : Section dont le contenu est un complément par rapport à ce qui l'entoure, qui n'est pas forcément en lien direct avec le contenu mais qui peut apporter des informations supplémentaires.
    • hgroup : La balise <hgroup> n'existe plus en HTML5 (février 2013). Eh oui, ce sont des choses qui arrivent quand on travaille sur un truc pas entièrement finalisé.
    • mark : Définit un texte marqué. Surligneur de texte.
    • header : Section d'introduction d'un article, d'une autre section ou du document entier (en-tête de page).
    • footer : Section de conclusion d'une section ou d'un article, voire du document entier (pied de page).

    Vous trouverez sur le web de nombreuses images illustrant l'utilisation de ces balises, comme par exemple celle-ci qui provient de Alsacréation :

    Imbrication des balises de base en HTML5

    Inconvénients : Ces balises ne sont pas forcément compatibles avec tous les navigateurs... En particulier les anciens, et en particulier toutes les anciennes versions de IE jusqu'à IE8 compris. Visitez http://html5test.com/ pour connaître le niveau de compatibilité de votre navigateur.

Dernière modification : 20/4/2017

Semaine du lendi 30 janbier 2017 : TD n°4 (Cumul=6h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

CSS

HTML5

  • Nouveautés en HTML5 : nous nous concentrerons sur les nouvelles balises qui apportent de la sémantique au texte. Vous pourrez comprendre la philosophie derrière HTML5 en vous polongeant dans le livre Dive into HTML5 : http://diveintohtml5.info/. (Voir la page https://fr.wikipedia.org/wiki/HTML5 pour une simple liste de toutes les nouveautés.)
    • main : Définit le contenu principal de la page, il doit être unique dans la page.
    • section : Section générique regroupant un même sujet, une même fonctionnalité, de préférence avec un en-tête, ou bien section d'application web.
    • nav : Section possédant des liens de navigation principaux (au sein du document ou vers d'autres pages).
    • article : Section de contenu indépendante, pouvant être extraite individuellement du document ou syndiquée (flux RSS ou équivalent), sans pénaliser sa compréhension.
    • aside : Section dont le contenu est un complément par rapport à ce qui l'entoure, qui n'est pas forcément en lien direct avec le contenu mais qui peut apporter des informations supplémentaires.
    • hgroup : La balise <hgroup> n'existe plus en HTML5 (février 2013). Eh oui, ce sont des choses qui arrivent quand on travaille sur un truc pas entièrement finalisé.
    • mark : Définit un texte marqué. Surligneur de texte.
    • header : Section d'introduction d'un article, d'une autre section ou du document entier (en-tête de page).
    • footer : Section de conclusion d'une section ou d'un article, voire du document entier (pied de page).

    Vous trouverez sur le web de nombreuses images illustrant l'utilisation de ces balises, comme par exemple celle-ci qui provient de Alsacréation :

    Imbrication des balises de base en HTML5

    Inconvénients : Ces balises ne sont pas forcément compatibles avec tous les navigateurs... En particulier les anciens, et en particulier toutes les anciennes versions de IE jusqu'à IE8 compris. Visitez http://html5test.com/ pour connaître le niveau de compatibilité de votre navigateur.

  • Compatibilité : comme dit précédemment, les balises HTML5 ne sont pas forcément compatibles avec tous les navigateurs, et en particulier toutes les anciennes versions de IE.

    Les navigateurs autres que IE se contentent d'ignorer les balises qu'ils ne connaissent pas. Votre page ne sera pas présentée selon vos souhaits, mais le contenu sera là quand même.
    IE, lui, ignore le texte qui se trouvent dans de telles balises... Votre page risque d'être intégralement vide... Gênant...

    Pour vous protéger, vous pouvez placer les fichiers html5shiv.js et html5shiv-printshiv.js dans votre répertoire, et ajouter le code suivant dans vos pages web, juste avant </head> :

          <!--[if lt IE 9]>
             <script src="html5shiv.js"></script>
             <script src="html5shiv-printshiv.js"></script>
          <![endif]-->        
      

Réglages de Web Developer

  • Vérifiez que votre version de Web Developer est bien réglée : dans le menu Outils cliquez sur réglez les outils, et vérifier que le standard choisi est bien CSS3 (voir capture d'écran ci-dessous).
    Si ce n'est pas le cas, Web Developer trouvera des « fausses » erreurs dans les exemples de l'exercice suivant, ainsi que dans votre travail.... régler Web Developer pour CSS3

Exercice d'application

  • Réalisez ce site : Les girafes.
    Ce n'est pas forcément un modèle à essayer de reproduire aveuglément, mais plutôt un exemple destiné à vous donner des idées et vous montrer quelques possibilités des CSS. Vous pouvez utiliser vos propres idées.
  • Vous pouvez ensuite améliorer votre travail grâce à un menu déroulant, comme dans cette version-ci.
  • Ajoutez une feuille de style pour l'impression, de façon à ce que les articles (les pages) s'impriment correctement et sobrement, sans les menus et autres décorations.
Dernière modification : 20/4/2017

Semaine du lendi 30 janbier 2017 : CM n°4 (Cumul=6h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

HTML, compléments pour l'exercice

Quelques compléments pour les deux versions de l'exercice, la version simple et la version avec menus déroulants.

Espacement et retraits

L'espacement entre les paragraphes doit être géré avec les propriétés margin et padding.
On peut gérer séparement les marges et retraits à gauche, à droite, en haut et en bas (avec margin-left, margin-right, etc. ou en donnant les 4 mesures dans la propriété margin).

L'espacement en début de première ligne doit être géré par la propriété text-indent.

Remarque de la première page

Pour la remarque de début de la première page, on utilisera de préférence blockquote.

Lettrines et premières lignes

Les pseudo-classes first-line et first-letter permettent de modifier respectivement la présentation de la première ligne et de la première lettre (lettrine) d'un élément de type block.

Image de fond

Ce qui suit est valable pour toutes balises. Si la balise est body, ça concerne l'ensemble de la page.

Principales propriétés, avec leurs principales valeurs possibles :

  • Pour utiliser une image en fond : background:url(URL de l'image);.
  • Si l'image ne couvre pas l'ensemble de la zone concernée, elle sera répétée horizontalement et verticalement.
    La propriété background-repeat permet de modifier cela.
    Valeurs possibles : repeat, repeat-x, repeat-y, no-repeat.
  • Pour positionner l'image : background-position.
    Valeurs possibles : left top, left center, left bottom, right top, etc.
    Si ne précisez qu'une seule valeur, la deuxième est supposée être center.)
  • Si rien n'est précisé, l'image sera affichée à l'échelle 1 (i.e. 1 pixel d'image pour 1 pixel d'écran).
    La propriété background-size permet de modifier cela.
    Valeurs possibles : auto, une ou deux dimensions, un pourcentage, cover, contain.

Pour des infos supplémentaires sur les images de fond, voir CSS background-image Property sur W3Schools, ou Image de fond en CSS sur Mammoutland, ou background-image sur css-tricks, ou Propriété background-image - CSS sur zonecss.

Menu non déroulant

  • Positionnement avec nav en position:fixed et main en position:absolute.
  • Animation avec border:outset pour div.eltmenu et border:inset pour div.eltmenu:hover.
  • Suppression du soulignement des liens par text-decoration:none.

Menu déroulant

nav.menu { 
  position:fixed;
  left:1%;
  top:10%;
  width:17%;
  background:white;
  border:thin silver solid;
}
div.eltmenu, div.eltmenuactif  { 
  display:none; /* par défaut, éléments du menu invisibles */>
}
nav.menu:hover div.eltmenu { 
  display:block; /* éléments du menu visibles au survol de nav.menu */>
  padding:3px;
  border: 2px outset rgb(230,230,255);
}
nav.menu:hover div.eltmenu:hover { 
  border-style: inset; /* animation au survol des boutons */>
}
nav.menu:hover div.eltmenuactif { 
  display:block;
  background:rgb(70%,70%,70%);
  padding:3px;
  border: 1px solid rgb(70%,70%,70%);
}
nav.menu a:link { 
  text-decoration:none; 
}
a:link,a:hover,a:visited,a:visited:hover { 
  color:black; 
} 

Infobulles

span.infobulle { 
  display:none; /* par défaut, infobulles invisibles */>
}
div.eltmenuactif:hover span.infobulle,
div.eltmenu:hover span.infobulle { 
  display:inline; /* au survol du menu, bulles visibles */>
  position:absolute;
  top:-2em;
  left:2em;
  border:thin solid blue;
  background:yellow;
  color:blue;
  font-size:80%;
  padding:2px;
  text-align:left;
}

Animation des couleurs

th{  
  color:rgb(90%,90%,90%);
  background:rgb(25%,25%,25%);
  animation: changecouleur 3s infinite;
  /* voir http://www.w3schools.com/cssref/css_animatable.asp */
  /* ou http://www.creativejuiz.fr/blog/tutoriels/quelques-idees-danimations-simples-en-css3 */
}
@keyframes changecouleur { 
  from {background-color: blue;}
  to {background-color: orange;}
}

Le salut dans la fuite

HTML
<div class="piste">
  <span class="coureur">
    <span class="texte1">Attrapez moi.</span>
    <span class="texte2">Perdu, je suis parti.</span>
  </span>
</div>
CSS
.texte1 { 
  display:inline; /* visible par défaut */
} 
.texte2 { 
  display:none; /* invisible par défaut */
} 
div.piste { 
  padding-bottom:5em;
}
div.piste:hover .texte1 { 
  display:none; /* invisible au survol de la piste */
} 
div.piste:hover .texte2 { 
  display:inline; /* visible au survol de la piste */
} 
  color:red;
} 
.coureur { 
  background:rgb(75%,75%,75%);
  padding:0em;
  border:black thin solid;
}
div.piste:hover .coureur { 
  position:relative; /* positionnement du coureur au survol de la piste */
  top:-10em;
  left:75%;
}

PHP

Dernière modification : 20/4/2017

Semaine du lendi 6 fébrier 2017 : TD n°5 (Cumul=8h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Finir l'exercice

  • Réalisez ce site : Les girafes.
    Ce n'est pas forcément un modèle à essayer de reproduire aveuglément, mais plutôt un exemple destiné à vous donner des idées et vous montrer quelques possibilités des CSS. Vous pouvez utiliser vos propres idées.
  • Vous pouvez ensuite améliorer votre travail grâce à un menu déroulant, comme dans cette version-ci.
  • Ajoutez une feuille de style pour l'impression, de façon à ce que les articles (les pages) s'impriment correctement et sobrement, sans les menus et autres décorations.

PHP

Dernière modification : 20/4/2017

Semaine du lendi 6 fébrier 2017 : CM n°5 (Cumul=7,5h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

PHP

Dernière modification : 20/4/2017

Semaine du lendi 13 fébrier 2017 : TD n°6 (Cumul=10h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

PHP

Dernière modification : 20/4/2017

Semaine du lendi 13 fébrier 2017 : CM n°6 (Cumul=9h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Formulaires

Dernière modification : 20/4/2017

Semaine du lendi 27 fébrier 2017 : TD n°7 (Cumul=12h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Exercices

Dernière modification : 20/4/2017

Semaine du lendi 27 fébrier 2017 : CM n°7 (Cumul=10,5h)

Rappel : Le contrôle n°1 aura lieu le lundi 6 mars, de 15h30 à 17h, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

Formulaire et traitement dans le même fichier

  • Exercice 5 du Chapitre 7 (Calculatrice).
    calculatrice.php
    [cacher les numéros de lignes]
    1. <!DOCTYPE html>
    2. <html>
    3.   <head lang="fr">
    4.     <meta charset="utf-8" />
    5.     <link rel="shortcut icon"
    6.           href="http://www.grappa.univ-lille3.fr/~gonzalez/images/dg.ico"
    7.           type="image/ico" />
    8.     <title>Calculatrice</title>
    9.   </head>
    10.   <body>
    11.     <?php
    12.     // récupération du nom du programme pour renseigner l'attribut "action"
    13.     $cettepage=basename($_SERVER["PHP_SELF"]);
    14.     ?>
    15.     <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    16.     avec liste déroulante :<br />
    17.     <form action="<?php echo $cettepage; ?>">
    18.       <input name="a" />
    19.       <select name="par">
    20.         <option>+</option>
    21.         <option>-</option>
    22.         <option>*</option>
    23.         <option>/</option>
    24.       </select>
    25.       <input name="b" />
    26.       <input type="submit" value="=" />
    27.     </form>
    28.     <hr />
    29.     <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    30.     avec boutons radios :<br />
    31.     <form action="<?php echo $cettepage; ?>">
    32.       <input name="a" />
    33.       <input type="radio" name="par" value="+" checked />+
    34.       <input type="radio" name="par" value="-" />-
    35.       <input type="radio" name="par" value="*" />*
    36.       <input type="radio" name="par" value="/" />/
    37.       <input name="b" />
    38.       <input type="submit" value="=" />
    39.     </form>
    40.     <hr />
    41.     <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    42.     <?php
    43.     if (isset($_GET["par"])) {
    44.       $a=$_GET["a"];
    45.       $b=$_GET["b"];
    46.       $par=$_GET["par"];
    47.       echo "le résultat du calcul précédent est : $a$par$b=";
    48.       switch ($par) {       /* ******************************* */
    49.         case "+":           /*  On aurait pu aussi écrire :    */
    50.           echo $a+$b;       /*                                 */
    51.           break;            /*   if ($par=="+") {              */
    52.         case "-":           /*       echo $a+$b;               */
    53.           echo $a-$b;       /*   } elseif ($par=="-") {        */
    54.           break;            /*       echo $a-$b;               */
    55.         case "*":           /*   } elseif ($par=="*") {        */
    56.           echo $a*$b;       /*       echo $a*$b;               */
    57.           break;            /*   } else {                      */
    58.         default:            /*       echo $a/$b;               */
    59.           echo $a/$b;       /*   }                             */
    60.       }                     /* ******************************* */
    61.     }
    62.     ?>
    63.   </body>
    64. </html>
    65.  

Quelle valeur pour method ? get ou post ?

get post
Données visibles Oui, dans l'adresse de la page. Non : à privilégier quand les informations transmises contiennent des données sensibles (mots de passe par exemple).
En cas de reload La page est recalculée sans demande de confirmation : à éviter quand la page modifie quelque chose, par exemple dans une base de données. Le navigateur demande confirmation avant de recalculer la page : à privilégier pour toute saisie de données destinées à modifier le contenu d'une base de données ou d'un fichier.
Taille limite pour les données Oui, en général aux alentours de 2000 caractères Non.
Format des données Exclusivement des caractères ASCII. Libre.
Javascript Les données sont dans l'adresse, donc javascript peut les récupérer. Javascript ne peut pas les récupérer directement.

Chaînes de caractères et formulaires

  • Exercice du Chapitre 8.
    Correction, formulaire & traitement dans le même fichier :
    identite.php
    [cacher les numéros de lignes]
    1. <!DOCTYPE html>
    2. <html>
    3.   <head lang="fr">
    4.     <meta charset="utf-8">
    5.     <link rel="shortcut icon"
    6.           href="http://www.grappa.univ-lille3.fr/~gonzalez/images/dg.ico"
    7.           type="image/ico" />
    8.     <title>Identité...</title>
    9.   </head>
    10.   <body>
    11.     <h2>Premiers essais de contrôle d'identité</h2>
    12. <?php
    13. if (isset($_POST["nom"])
    14.     && (trim(strtolower($_POST["nom"])) == "atte")
    15.     && (trim(strtolower($_POST["prenom"])) == "tom")
    16.     && (trim(strtolower($_POST["motdepasse"])) == "rouge")
    17.    ) {
    18.    echo "Bienvenue chez vous, Tom Atte...<br/>\n";
    19. } else {
    20.    // sortie provisoire du mode php (pour écrire du texte html pur)
    21. ?>
    22.     <hr/>
    23.     Veuillez vous identifier SVP&nbsp;:<br/>
    24.     <form method="post" action="identite.php">
    25.       Nom&nbsp;: <input name="nom" /><br/>
    26.       Prénom&nbsp;: <input name="prenom" /><br/>
    27.       Mot de passe&nbsp;: <input type="password" name="motdepasse" /><br/>
    28.       <input type="submit" />
    29.     </form>
    30.     <hr/>
    31.     <em>Indication&nbsp;:</em> essayez avec «&nbsp;Atte&nbsp;» comme
    32.     nom, «&nbsp;Tom&nbsp;» comme prénom et «&nbsp;Rouge&nbsp;» comme mot
    33.     de passe.
    34.     <hr/>
    35. <?php
    36.    // retour dans le mode php (pour fermer le "else")
    37. }
    38. ?>
    39.   </body>
    40. </html>
    41.  

Pré-remplir un formulaire

  • Exercice 5 du Chapitre 7 (Calculatrice, deuxième version).
    calculatrice2.php
    [cacher les numéros de lignes]
    1. <!DOCTYPE html>
    2. <html>
    3.   <head lang="fr">
    4.     <meta charset="utf-8" />
    5.     <link rel="shortcut icon"
    6.           href="http://www.grappa.univ-lille3.fr/~gonzalez/images/dg.ico"
    7.           type="image/ico" />
    8.     <title>Calculatrice</title>
    9.   </head>
    10.   <body>
    11.     <?php
    12.      // récupération du nom du programme pour renseigner l'attribut "action"
    13.      $cettepage=basename($_SERVER["PHP_SELF"]);
    14.     ?>
    15.     <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    16.     avec liste déroulante :<br />
    17.     <form action="<?php echo $cettepage; ?>">
    18.       <input name="a" <?php if (isset($_GET["a"])) echo "value=\"".$_GET["a"]."\""; ?> />
    19.       <select name="par">
    20.         <option <?php if (isset($_GET["par"]) && ($_GET["par"]=="+")) echo "selected"; ?> >+</option>
    21.         <option <?php if (isset($_GET["par"]) && ($_GET["par"]=="-")) echo "selected"; ?> >-</option>
    22.         <option <?php if (isset($_GET["par"]) && ($_GET["par"]=="*")) echo "selected"; ?> >*</option>
    23.         <option <?php if (isset($_GET["par"]) && ($_GET["par"]=="/")) echo "selected"; ?> >/</option>
    24.       </select>
    25.       <input name="b" <?php if (isset($_GET["b"])) echo "value=\"".$_GET["b"]."\""; ?> />
    26.       <input type="submit" value="=" />
    27.     </form>
    28.     <hr />
    29.     <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    30.     avec boutons radios :<br />
    31.     <form action="<?php echo $cettepage; ?>">
    32.       <input name="a" <?php if (isset($_GET["a"])) echo "value=\"".$_GET["a"]."\""; ?> />
    33.       <input type="radio" name="par" value="+"
    34.              <?php if (isset($_GET["par"]) && ($_GET["par"]=="+")) echo "checked"; ?> />+
    35.       <input type="radio" name="par" value="-"
    36.              <?php if (isset($_GET["par"]) && ($_GET["par"]=="-")) echo "checked"; ?> />-
    37.       <input type="radio" name="par" value="*"
    38.               <?php if (isset($_GET["par"]) && ($_GET["par"]=="*")) echo "checked"; ?> />*
    39.       <input type="radio" name="par" value="/"
    40.           <?php if (isset($_GET["par"]) && ($_GET["par"]=="/")) echo "checked"; ?> />/
    41.       <input name="b" <?php if (isset($_GET["b"])) echo "value=\"".$_GET["b"]."\""; ?> />
    42.       <input type="submit" value="=" />
    43.     </form>
    44.     <hr />
    45.     <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    46.     <?php
    47.     if (isset($_GET["par"])) {
    48.       $a=$_GET["a"];
    49.       $b=$_GET["b"];
    50.       $par=$_GET["par"];
    51.       echo "le résultat du calcul précédent est : $a$par$b=";
    52.       switch ($par) {       /* ******************************* */
    53.         case "+":           /*  On aurait pu aussi écrire :    */
    54.           echo $a+$b;       /*                                 */
    55.           break;            /*   if ($par=="+") {              */
    56.         case "-":           /*       echo $a+$b;               */
    57.           echo $a-$b;       /*   } elseif ($par=="-") {        */
    58.           break;            /*       echo $a-$b;               */
    59.         case "*":           /*   } elseif ($par=="*") {        */
    60.           echo $a*$b;       /*       echo $a*$b;               */
    61.           break;            /*   } else {                      */
    62.         default:            /*       echo $a/$b;               */
    63.           echo $a/$b;       /*   }                             */
    64.       }                     /* ******************************* */
    65.     }
    66.     ?>
    67.   </body>
    68. </html>
    69.  
Dernière modification : 20/4/2017

Semaine du lendi 6 môrs 2017 : TD n°8 (Cumul=14h)

Formulaires et HTML5

HTML5 ajoute un certain nombre de contrôles pour les formulaires. (Vous pouvez les tester.)
Les navigateurs qui ne savent pas les utiliser correctement se contenteront de les traiter comme un input de type text.
Sauf mention contraire les versions récentes de Opera, Chrome et Firefox savent les utiliser correctement.
  1. Message d'invite dans un input :
    <input name="c0" placeholder="Veuillez remplir SVP">
  2. Autofocus sur n'importe quel contrôle :
    <input name="c1" autofocus>
  3. Saisie d'un email, avec contrôle (simple) de saisie :
    <input name="c2" type="email">
  4. Saisie d'une URL, avec contrôle (simple) de saisie :
    <input name="c3" type="URL">
  5. Saisir un nombre dans un certain intervalle :
    <input name="c4" type="number" min="0" max="10" step="2" value="6">
  6. Saisir un nombre avec un curseur :
    <input name="c5" type="range" min="0" max="10" step="2" value="6">
  7. Saisie d'une date :
    Plusieurs versions :

    <input name="c6" type="date">
    <input name="c7" type="datetime">
    <input name="c8" type="month">
    <input name="c9" type="week">
    <input name="c10" type="time">
    Fonctionne avec les versions récentes deOpéra, Chrome. Ne fonctionne pas pour l'instant avecFirefox.
  8. Choisir une couleur :
    <input name="c11" type="color">
  9. Champ obligatoire :
    <input name="c12" required>

Exercices

Dernière modification : 20/4/2017

Semaine du lendi 6 môrs 2017 : CM n°8 (Cumul=12h)

Tableaux

Dernière modification : 20/4/2017

Semaine du lendi 13 môrs 2017 : TD n°9 (Cumul=16h)

Tableaux

Dernière modification : 20/4/2017

Semaine du lendi 20 môrs 2017 : TD n°10 (Cumul=18h)

Et si je veux faire du PHP chez moi ?

Avec linux

Si vous avez la chance (ou la volonté) d'avoir un ordinateur fonctionnant sous linux, il suffit d'installer les paquets PHP (s'ils ne sont pas déjà installés d'origine).

Faire du PHP sur le web

Il existe de nombreux sites qui vous permettent de faire du PHP sur le web. Choisissez celui qui vous plaît le plus. Par exemple :
  • phptester (résultat tel que vu dans le navigateur)
  • codepad (résultat sous la forme du code HTML produit)
  • syframework (résultat sous la forme du code HTML produit)

Installer PHP sous Windows

Si vous voulez développer un site web complet, il faut en passer par là...
Deux solutions plutôt faciles à utiliser WampServer et EasyPHP .
Si vous êtes plus technique, vous pouvez aussi lire cette page.

Tableaux

  • Correction de l'exercice 4 du Chapitre 9.
    ex4ch9.php
    [cacher les numéros de lignes]
    1. <!DOCTYPE html>
    2. <html lang="fr">
    3.   <head>
    4.     <meta charset="utf-8"> <!-- encodage -->
    5.     <link rel="shortcut icon"
    6.           href="http://grappa.univ-lille3.fr/~gonzalez/images/dg.ico"
    7.           type="image/ico" /> <!-- "favicon" -->
    8.     <title>Annuaire (ex 4, chapitre 9)</title>
    9.   </head>
    10.     <?php
    11.     /* ****************************
    12.        * RÉCUPÉRATION DES DONNÉES *
    13.        **************************** */
    14.       $liste=file("ex4ch9.txt");  // Lecture du fichier de données
    15.       foreach ($liste as $personne) { // Pour chaque ligne...
    16.         $parties=explode(";",$personne); // ... découper la ligne
    17.         $annuaire[$parties[0]] = array(  // En utilisant son code comme clef,...
    18.                                          // ... ajouter la personne dans l'annuaire
    19.                                        "prenom" => $parties[1],
    20.                                        "nom" => $parties[2],
    21.                                        "mdp" => trim($parties[3]) // trim : pas de retour à la ligne
    22.                                       );
    23.       }
    24.     /* ****************************
    25.        * NOM DE LA PAGE EN COURS *
    26.        **************************** */
    27.        // Plus d'info à http://php.net/reserved.variables.server
    28.        // et à http://www.php.net/basename
    29.       $cettepage = basename($_SERVER["PHP_SELF"]);
    30.     ?>
    31.   <body>
    32.     <form action="<?=$cettepage?>"
    33.           method="post">
    34.              <?php /* <?=XX?> est un raccourci de <?php echo XX; ?>
    35.                       Formulaire et traitement dans la même page */ ?>
    36.       <select name="qui">
    37.       <?php
    38.     /* ******************
    39.        * REMPLIR SELECT *
    40.        ****************** */
    41.         foreach ($annuaire as $clef => $unepersonne) {
    42.            echo "\t\t<option value=\"$clef\"",     // Chaque personne est repérée par son code
    43.                 ( isset($_POST["qui"]) && ($_POST["qui"]==$clef) // Si la personne est...
    44.                    ? " selected" // ... celle qui a été choisie, elle est pré-sélectionnée
    45.                    : ""),
    46.                 ">",$unepersonne["prenom"], " ",
    47.                 strtoupper($unepersonne["nom"]), // Nom en majuscules
    48.                 "</option>\n";
    49.         }
    50.       ?>
    51.       </select>
    52.       <input type="submit" value="Quel mot de passe ?" />
    53.     </form>
    54.     <?php
    55.     /* **************
    56.        * TRAITEMENT *
    57.        ************** */
    58.     if (isset($_POST["qui"])) { // Si on a sélectionné quelqu'un...
    59.       $qui = $annuaire[$_POST["qui"]] ;  // ... on récupère ses informations...
    60.       echo "<br /><hr />Le mot de passe de ", $qui["prenom"], " ", // ... et on les affiche
    61.            strtoupper($qui["nom"]), " est « ", $qui["mdp"], " »";
    62.     }
    63.     ?>
    64.   </body>
    65. </html>
    66.  

Sessions

Le texte qui suit est une partie de la page consacrée aux sessions sur le site de http://fr.php.net :
Le support des sessions de PHP est un moyen de préserver des données entre plusieurs accès. Cela vous permet de créer des applications personnalisées, et d'augmenter l'attrait de votre site.
Chaque visiteur accédant à votre page web se voit assigner un identifiant unique, appelé "identifiant de session". Il peut être stocké soit dans un cookie, soit propagé dans l'URL.
Le support des sessions vous permet d'enregistrer un nombre illimité de variables qui doivent être préservées entre les requêtes. Lorsqu'un visiteur accède à votre site, PHP va vérifier automatiquement (si session.auto_start est activé) ou sur demande (explicitement avec session_start() ou implicitement avec session_register()) s'il existe une session du même nom. Si c'est le cas, l'environnement précédemment sauvé sera recréé.
La seule fonction nécessaire pour un usage simple des sessions est session_start(), mais je ne peux que vous encourager à aller voir les autres.

Application des sessions : identification des visiteurs

Principe :
  • Deux variables de session contiennent le login et le mot de passe du visiteur (variables vides si le visiteur n'est pas identifié).
  • Si le visiteur n'est pas identifié, le menu propose un choix Se connecter qui envoie sur un formulaire de saisie (on peut aussi inclure ce formulaire directement dans le menu). Si le visiteur est identifié, le menu propose un choix Se déconnecter qui vide les variables de session qui contiennent le login et le mot de passe du visiteur.
  • Chaque page commence par quelque chose qui ressemblera à :
          if (le visiteur n'a pas le bon niveau d'autorisation pour cette page) {
              message de refus
              fin de page
              return ;
          }
  • L'évaluation du niveau d'autorisation peut se faire de plusieurs manières :
    • Mauvais, car complique les modifications : coder en dur le test sur chaque possibilité  :
              if ((nom=="bidule") && (mot de passe=="truc")) {
      
                      ...
      
              } elseif ((nom=="chose") && (mot de passe=="n'importe quoi")) {
      
                      ...
      
              } else
      
                      etc
            
    • Mieux : ranger les noms et mots de passe dans un tableau, et parcourir le tableau pour faire la vérification.
    • (Parfait : la même chose, mais créer une table spéciale dans une base de données au lieu d'utiliser un tableau.)
  • Pour être parfait ce serait bien que ce soit une fonction qui affiche le menu, et que cette fonction décide d'elle-même des choix disponibles en fonction du niveau d'autorisation du visiteur.
  • Exemple d'utilisation des sessions : http://www.grappa.univ-lille3.fr/~gonzalez/session_php.

Espionner vos visiteurs

Informations sur leur navigateur, informations sur leur origine, les suivre à la trace (cookies).
Les informations que vous pouvez obtenir sans douleur sur vos visiteurs.
  1. Les informations sur leur navigateur :
    • Le navigateur que vous utilisez : CCBot.
    • La version de votre navigateur : 2.0.
    • Votre système d'exploitation : unknown.
    La fonction à utiliser est get_browser().
    La liste des informations qu'on peut obtenir est la suivante  :
    • browser_name_regex (^ccbot/2\.0.*$)
    • browser_name_pattern (CCBot/2.0*)
    • parent (CCBot)
    • version (2.0)
    • majorver (2)
    • comment (CCBot)
    • browser (CCBot)
    • browser_maker (CommonCrawl Foundation)
    • crawler (true)
    • minorver (0)
    • platform (unknown)
    • ismobiledevice (false)
    • istablet (false)
    • device_type (unknown)
    • device_pointing_method (unknown)
    Remarque :
    La fonction get_browser() nécessite que la directive de configuration browscap dans le fichier php.ini pointe vers le fichier browscap.ini de votre système. Ce fichier contient les caractéristiques des navigateurs, et il doit bien entendu être à jour.
    S'il vous est impossible de vous en assurer, vous pouvez vous rabattre sur la variable $_SERVER['HTTP_USER_AGENT'] qui contient un sous-ensemble de ces informations, mais d'une manière moins lisible. Pour vous on obtient « CCBot/2.0 (http://commoncrawl.org/faq/) ».
    Vous pouvez aussi utiliser la bibliothéque php-local-browscap.
  2. Les informations sur l'origine de vos visiteurs :
    • l'adresse de la machine de vos visiteurs, avec $_SERVER['REMOTE_ADDR'] pour l'adresse IP (pour vous il s'agit de « 54.224.121.67 »), et avec gethostbyaddr($_SERVER['REMOTE_ADDR']) pour son adresse domainisée (pour vous il s'agit de « ec2-54-224-121-67.compute-1.amazonaws.com »).
      En plus le nom de la machine permet peut-être de deviner votre pays.
  3. Les cookies :
    Les cookies doivent être vus comme des variables qui peuvent être conservées entre deux exécutions de la page. Ils sont enregistrés sur la machine cliente. La seule restriction est qu'ils doivent être enregistrés avant l'envoi de tout texte, donc en début de page.
    La fonction qui s'en charge est setcookie().
    Une utilisation pourrait être par exemple de mettre en tête de ce programme :
    1. <?php
    2.   $compteurdevisites = $_COOKIE['compteurdevisites']+1;
    3.   $dernierevisite = $_COOKIE['dernièrevisite'];
    4.   setcookie("compteurdevisites", "$compteurdevisites");
    5.   setcookie("dernièrevisite", time());
    6. ?>
    et il suffirait d'utiliser dans votre page
    1. <?php
    2.   echo "C'est votre <em>$compteurdevisites</em>° visite";
    3.   if ($dernierevisite != "") {
    4.       echo ", la dernière c'était le <em>"
    5.           .strftime("%A %e %B %Y", $dernierevisite)
    6.           ."</em>, à <em>"
    7.           .strftime("%Hh %Mm %Ss", $dernierevisite)
    8.           ."</em>";
    9.   }
    10.   echo ".";
    11. ?>
    pour obtenir cet affichage :
    C'est votre 1° visite.
  4. En tant qu'internaute, ces indiscrétions sont-elles dangereuses ?
    Elles permettent en tout cas pas mal de choses :
    • N'importe quel site marchand peut vous pister ainsi, et garder l'historique de vos connexions. Il lui suffit d'enregistrer un identifiant sur votre machine, et d'enregistrer dans ses bases de données l'historique de vos actions dans ses pages (vos clics, vos déplacements, ce que vous remplissez dans les formulaires, le temps passé sur chaque page que vous visitez, etc.).
    • N'oubliez pas que votre fournisseur d'accès connaît toutes les pages que vous avez consultées par son intermédaire.
    Il y a quand même des bonnes nouvelles dans tout ça :
    • Si vous vous connectez à internet par l'intermédiaire d'un fournisseur d'accès, votre adresse IP (54.224.121.67) change à chaque connexion... Votre machine devient beaucoup moins facilement identifiable, en tout cas sans la complicité de votre fournisseur d'accès (qui, lui, sait toujours à tout moment à quel utilisateur correspond chaque adresse IP).
      Il faut remarquer que les adresses changent de moins en moins avec les connexions par cable ou ADSL.
    • Grâce aux cookies, un site est en effet capable de savoir si vous êtes déjà venu le voir, MAIS :
      • Il ne sait pas réellement qui vous êtes : il sait seulement que vous êtes l'utilisateur n°X ; cela lui permet de savoir ce que vous avez fait d'autre chez lui, en tant qu'utilisateur n°X, mais c'est tout.
        Il n'est pas capable de deviner ce que vous n'avez pas dit : votre nom, votre numéro de carte de crédit, votre numéro de téléphone, l'endroit où vous vivez (bien que l'adresse IP de votre machine lui permette sans doute de deviner votre pays, voir plus haut).
        Attention : si vous donnez ce genre de renseignements (nom, numéro de carte de crédit, numéro de téléphone, endroit où vous vivez) quelque part, ne vous étonnez pas qu'on s'en souvienne...
      • Il suffit de les désactiver, pour que les cookies deviennent inoffensifs (voir ci-dessous).
  5. Comment s'en protéger ?
    • Il est facile de se protéger des cookies. Vous pouvez, au choix :
      • régler votre navigateur pour qu'il refuse les cookies ; cependant certains sites ne vous laissent pas entrer si vous avez désactivé l'option Cookies. Vous allez peut-être avoir envie de laisser les cookies actifs pour visiter ces sites ; si vous êtes vraiment certain que cela en vaut la peine, vous avez peut-être intérêt à regarder les deux points suivants ;
      • régler votre navigateur pour qu'il accepte les cookies, mais qu'il les efface à chaque nouvelle session ;
      • effacer vous-même à la main les cookies ; par exemple dans Firefox, vous allez dans la suite de menus Édition/Préférences/Vie privée, et vous pouvez effacer les cookies (et d'autres choses).
    • Le reste fait partie de la norme HTML. C'est ce qui concerne l'identification de votre machine, de son système d'exploitation et de son navigateur, des pages qui ont été visitées, de votre provenance, la protection est beaucoup plus difficile.
  6. Plus de lecture : la CNIL avec en particulier leurs pages intitulées « Découvrez comment vous êtes pistés sur internet ».
Dernière modification : 20/4/2017

Semaine du lendi 27 môrs 2017 : TD n°11 (Cumul=20h)

On récapitule...

Nous allons profiter des trois derniers TD pour nous plonger dans un récapitulatif « grandeur nature ». Vous allez réaliser un site web qui va vous permettre de mettre en œuvre toutes les notions vues au cours du semestre (et même certaines que vous n'avez pas encore vues) : HTML, CSS, PHP, sessions, cookies, etc.
Ce travail sera basé sur le site « Girafes » vu au cours des TD 3 & 4.
Si vous n'aviez pas fini l'exercice vous pouvez récupérer la totalité des fichiers HTML et CSS dans cette archive ZIP.

Rappels...

Les notions qui vous manquent peut-être (ou que vous avez peut-être oubliées) :
  • On peut mettre à la main des variables GET dans une URL : on a le droit d'écrire dans du HTML « <a href="truc.php?x=45&nom=marcel">bla bla</a> ». (Et ça marche...)
  • Les fonctions require et include.
  • La fonction basename.
  • La variable $_SERVER.
Et ce que vous n'avez pas le droit d'avoir oublié : les tableaux, les sessions, les cookies.

Girafes 2.0 : passer au PHP

Vous pouvez voir ici ce qu'on attend de vous.

Pour cette version, on ne va ajouter aucune fonctionnalité au site, et on va se contenter d'utiliser PHP pour se simplifier la vie (si si) :

  • il n'y a qu'un seul fichier PHP, une seule adresse : le fichier index.php ;
  • le reste du contenu est inclus à la demande grâce aux fonctions require ou include ; le fichier index.php sera le seul fichier à contenir les en-têtes de page ; vous pouvez récupérer la totalité des fichiers débarrassés de leurs en-têtes dans cette archive ZIP ;
  • le choix de ce qui est affiché dépend des informations passées dans l'URL ;
  • le menu est créé par programme, à partir d'un tableau des fichiers disponibles ; les titres (<h1> et <title>) également.
Dernière modification : 20/4/2017

Semaine du lendi 3 averil 2017 : TD n°12 (Cumul=22h)

On récapitule, la suite

Rappel : première version, Girafes 2.0

Vous pouvez voir ici ce qu'on attend de vous.

Pour cette version, on ne va ajouter aucune fonctionnalité au site, et on va se contenter d'utiliser PHP pour se simplifier la vie (si si) :

  • il n'y a qu'un seul fichier PHP, une seule adresse : le fichier index.php ;
  • le reste du contenu est inclus à la demande grâce aux fonctions require ou include ; le fichier index.php sera le seul fichier à contenir les en-têtes de page ; vous pouvez récupérer la totalité des fichiers débarrassés de leurs en-têtes dans cette archive ZIP ;
  • le choix de ce qui est affiché dépend des informations passées dans l'URL ;
  • le menu est créé par programme, à partir d'un tableau des fichiers disponibles ; les titres (<h1> et <title>) également.
Ébauche de corrigé

Vous trouverez ci-dessous le code source d'une version bêta, basée sur ce que beaucoup d'entre vous ont fini lors du dernier TD.
Il manque l'écriture du menu par une boucle PHP.

  1. <!DOCTYPE html>
  2. <html>
  3.   <head lang="fr">
  4.     <meta charset="utf-8">
  5.     <link rel="shortcut icon" href="dg.ico" type="image/ico" />
  6.     <link rel="stylesheet"  href="style.css" />
  7.     <title>Les girafes de savane</title>
  8.     <!--[if lt IE 9]>
  9.         <script src="html5shiv.js"></script>
  10.         <script src="html5shiv-printshiv.js"></script>
  11.     <![endif]-->        
  12.   </head>
  13.   <body>
  14.    
  15.     <nav class="menu">
  16.       Menu&nbsp;:
  17.       <div class="eltmenu">
  18.         <a href="index.php?p=accueil">Accueil</a>
  19.         <span class="infobulle">Présentation du site</span>
  20.       </div>
  21.       <div class="eltmenu">
  22.         <a href="index.php?p=particularites">Particularités</a>
  23.         <span class="infobulle">Les particularités physiques des girafes</span>
  24.       </div>
  25.       <div class="eltmenu">
  26.         <a href="index.php?p=defense">Systèmes de défense</a>
  27.         <span class="infobulle">Les girafes ne sont pas aussi fragiles qu'elles en ont l'air</span>
  28.       </div>
  29.       <div class="eltmenu">
  30.         <a href="index.php?p=pasfacile">Pas facile d'être une girafe</a>
  31.         <span class="infobulle">Les girafes ont de nombreux problèmes à résoudre pour survivre</span>
  32.       </div>
  33.       <div class="eltmenu">
  34.         <a href="index.php?p=vie">Vie quotidienne</a>
  35.         <span class="infobulle">La vie un peu monotone des girafes</span>
  36.       </div>
  37.       <div class="eltmenu">
  38.         <a href="index.php?p=amour">Vive l'amour</a>
  39.         <span class="infobulle">Les rituels amoureux chez les girafes</span>
  40.       </div>
  41.       <div class="eltmenu"
  42.            ><a href="index.php?p=stats">Quelques chiffres</a>
  43.         <span class="infobulle">Surtout quelques démonstrations de CSS&nbsp;!!</span>
  44.       </div>
  45.     </nav>
  46.    
  47.     <main>
  48. <?php
  49.    $lespages = array(
  50.                      "accueil"=>"Accueil",
  51.                      "particularites"=>"Particularités",
  52.                      "defense"=>"Des systèmes de défense efficaces",
  53.                      "pasfacile"=>"Pas facile d'être une girafe !",
  54.                      "vie"=>"Vie quotidienne",
  55.                      "amour"=>"Vive l'amour",
  56.                      "stats"=>"Quelques chiffres",
  57.    ) ;
  58.    if (isset($_GET["p"]) && isset($lespages[$_GET["p"]]))
  59.        $lapage=$_GET["p"] ;
  60.    else
  61.        $lapage="accueil";
  62.    $titre=$lespages[$lapage] ;
  63.    $fichier=$lapage.".php" ;
  64.   echo "\t\t<h1>Les girafes de savane - $titre</h1>\n";
  65.   require($fichier) ;
  66. ?>      
  67.     </main>
  68.     <footer>
  69.       Version PHP n°2.0 bêta (passage à PHP en cours)
  70.     </footer>
  71.   </body>
  72. </html>
  73.  
  1. <blockquote>
  2.   Les textes de ce site ont été empruntés à un
  3.   <a href="http://girafe.de.savane.free.fr/">projet d'étudiant</a>
  4.  datant de l'année 2000.
  5. </blockquote>
  6.  
  7. <p>
  8.   Les légendes du Moyen Âge rapportaient l'existence d'une étrange
  9.   créature peuplant les côtes d'Afrique. Certains faisaient état d'un
  10.   corps démesuré, avec des sabots de vache, un air de chameau, et une
  11.   peau tâchetée de léopard. D'autres précisaient même comment cette
  12.  créature était née du croisement d'un léopard et d'une
  13.  chamelle. Longtemps d'ailleurs, on a appelé cet être étrange le
  14.   &laquo;&nbsp;kamélopard&nbsp;&raquo;. Les arabes l'appelaient eux
  15.  &laquo;&nbsp;zeraffa&nbsp;&raquo;. Son nom lui est resté. C'est
  16.   ainsi que le <em>kamélopard</em> est devenu la <em>girafe</em>.
  17. </p>
  18.  
  1. <p>
  2.   La période des amours est précédée de luttes entre mâles au cours
  3.   desquelles chacun tente de prendre l'ascendant sur l'autre. Chez les
  4.   girafes, elles sont rarement violentes. Les joutes se limitent à des
  5.   enlacements de cous et à des chocs flanc contre flanc. La violence
  6.   de l'affrontement s'estompe souvent dans la lenteur pour se
  7.   transformer en étranges chorégraphies. Parfois l'intensité du combat
  8.  pousse les deux rivaux à utiliser leurs cornes pour porter des coups
  9.  encore plus forts. De telles joutes peuvent se poursuivre pendant
  10.  des heures, et puis suivant des codes mystérieux, un vainqueur est
  11.  désigné et les deux lutteurs quittent ensemble le champ de
  12.  bataille. Comme tous ses pairs, un mâle dominant est un solitaire
  13.  sans cesse à la recherche de femelles en chaleur.
  14. </p>
  15. <p>
  16.  Pour déterminer si une belle est disposée à répondre à leurs
  17.  avances, les girafes mâles ont leur technique&nbsp;: lèvres
  18.  retroussées, l'urine de la femelle est humée et immédiatement
  19.   analysée. Si elle est en état, très vite il faut faire valoir son
  20.   statut de mâle dominant et écarter tous ses rivaux. Seuls, les
  21.   rituels peuvent commencer. Des heures et parfois même des jours
  22.   durant, il va la suivre sans la quitter d'un sabot. Face à une telle
  23.  persévérence, la femelle finit par céder et par se préparer à
  24.  l'assaut de son soupirant. Pour lui, quelques minutes de
  25.   concentration sont indispensables avant de prendre son élan. Avec
  26.   deux adultes approchant ensemble les deux tonnes, la moindre
  27.   hésitation peut s'avérer lourde de conséquences.
  28. </p>
  29.  
  1. <p>
  2.   Pour se protéger des appétits de la savane, certaines plantes ont
  3.   trouvé la parade. Les épines des acacias par exemple suffisent à
  4.   faire renoncer beaucoup d'herbivores, mais la girafe passe
  5.  outre. Ses lèvres velues et l'épaisseur de sa langue et de son
  6.   palais lui permettent de tout avaler sans craindre de se
  7.   blesser. L'acacia a beau se retrancher derrière de véritables
  8.  barbelés, la robe de la girafe tout comme ses conduits digestifs
  9.  sont insensibles à ses piqûres. De sa bouche à ses déjections où on
  10.  les retrouve intactes, ils travèrsent son corps sans l'érafler.
  11. </p>
  12. <p>
  13.   Dans la guerre qui les oppose aux herbivores, les systèmes de
  14.   défense élaborés par des plantes jouent sur tous les
  15.   tableaux. Certaines ont opté pour la discrétion. Indétectables à
  16.   l'&oelig;il nu, leurs armes n'en sont pas moins redoutables. En
  17.   effet, certaines feuilles peuvent à l'occasion devenir des tueuses
  18.  redoutables. Au cours de leur croissance, les cellules de leurs
  19.  feuilles se gorgent de tanin, une substance chimique communément
  20.  répendue parmi les plantes. Ingéré en grande quantité, le tanin peut
  21.  devenir toxique et tuer.
  22. </p>
  23. <p>
  24.  L'organisme de la girafe sait répondre aux ruses de la plante. Grâce
  25.   à l'antidote contenu dans sa salive, elle peut consommer ces
  26.  feuilles sans modération. La seule condition est de saliver le plus
  27.  possible pour neutraliser l'action du poison.
  28. </p>
  29.  
  1. <p>
  2.   Culminant à plus de 5 mètres, la girafe est le plus grand de tous
  3.   les animaux. En plus de cela, elle a un cou de 2 mètres de longueur,
  4.   des pattes élancées et une tête au port de reine qui allie toujours
  5.   grâce et finesse. En revanche la démarche de son corps est bien
  6.   souvent gauche. Mais très vite, cette maladresse peut
  7.   disparaître. Grâce à leur exceptionnelle acuité visuelle, leur tête
  8.   haut perchée tient de la tour de guet. Ainsi elles restent en
  9.   contact les unes avec les autres, même à plusieurs kilomètres de
  10.   distance. Voyageuses et incapables de rester seules plus de 24
  11.   heures, ce contact visuel est primordial.
  12. </p>
  13. <p>
  14.   Leurs troupeaux sont clairsemés, et parfois se mélangent. Si chacun
  15.   d'eux est régi par une hiérarchie bien précise, les girafes sont
  16.  libres de se nouer d'amitié avec qui elles veulent, même avec des
  17.   individus appartenant à d'autres troupeaux.
  18. </p>
  19. <p>
  20.  On rencontre trois types de girafes dans la savane : d'Ouganda,
  21.   Massaï, ou réticulées. Elles se différencient par le dessin de leur
  22.   robe. Non seulement chaque sous-espèce mais aussi chaque individu
  23.   possède le sien : une véritable marque d'identité.
  24. </p>
  25. <p>
  26.  N'est pas girafe qui veut. Pour compléter cet édifice, deux
  27.   vertèbres dorsales formant une bosse dans le dos de la girafe sont
  28.   particulièrement développées. Elles servent de point d'ancrage aux
  29.  muscles chargés de soutenir la tête et le cou.
  30. </p>
  31. <p>
  32.  Outre sa taille record qui lui assure l'exclusivité sur la
  33.   végétation la plus haute, pour se nourir la girafe dispose d'une
  34.  ralonge essentielle : une langue préhensile longue de 46
  35.  centimètres. En plus de celle-ci, grâce à ses canines qui agissent
  36.  comme de véritables peignes, la girafe peut choisir ses aliments.
  37. </p>
  38.  
  1. <p>
  2.   Son cou sur-dimensionné lui vaut un c&oelig;ur phénoménal. Il doit
  3.   envoyer trois mètres plus haut le sang nécessaire à l'irrigation de
  4.  son cerveau. Pour remplir cette mission,11 kg de muscles cardiaques
  5.  assurent la circulation de 60 litres de sang en une seule minute. La
  6.  girafe enregistre ainsi des pressions artérielles record jamais
  7.  rencontrées chez d'autres mammifères. Si cette pression est assez
  8.   élevée en haut de sa tête, tout en bas de son corps, elle est
  9.   ultra-forte. En toute logique la girafe devrait avoir les chevilles
  10.   qui emflent. Mais grâce à la rigidité de ses pattes, elle échappe à
  11.   ce désagrément. En comprimant ses vaisseaux, sa peau agit comme de
  12.   véritables bas à varices.
  13. </p>
  14. <p>
  15.   Autre problème auquel est confrontée la girafe&nbsp;: lorsqu'elle
  16.  baisse ou relève la tête, elle soumet son cerveau à des changements
  17.  de pression considérables, susceptibles de provoquer des maux de
  18.  tête. Mais la girafe a la solution pour les éviter&nbsp;: l'afflux
  19.   de sang vers le cerveau est contrôlé par un système de valvules qui,
  20.   lorsqu'elle baisse la tête, renvoie énergiquement le sang vers le
  21.  c&oelig;ur.
  22. </p>
  23. <p>
  24.  De la même façon, quand elle relève le cou, elle devrait craindre
  25.  les étourdissements, voire même les évanouissements. Dans ce cas là,
  26.  son c&oelig;ur joue les garde-fous. Il augmente très momentanément
  27.  son rythme cardiaque et envoie le supplément de sang nécessaire au
  28.  cerveau. Ainsi, quelle que soit sa position, le cerveau de la girafe
  29.  bénéficie d'une pression sanguine constante.
  30. </p>
  31.  
  1. <blockquote>
  2.   Les chiffres figurant sur cette page sont totalement fantaisistes et
  3.   sans aucun rapport avec la réalité. Ils ont été inventés de toutes
  4.   pièces pour l'exercice.
  5. </blockquote>
  6.      
  7. <h2>Évolution du nombre de girafes ces dernières années</h2>
  8.      
  9. <table>
  10.  <tr>
  11.    <td class="vide"></td>
  12.    <th>1995</th>
  13.    <th>2000</th>
  14.    <th>2005</th>
  15.    <th>2010</th>
  16.    <th>2015</th>
  17.  </tr><tr>
  18.    <th>Burundi</th>
  19.    <td>309</td>
  20.    <td>557</td>
  21.    <td>797</td>
  22.    <td>969</td>
  23.    <td>274</td>
  24.  </tr><tr>
  25.    <th>Djibouti</th>
  26.    <td>102</td>
  27.    <td>43</td>
  28.    <td>881</td>
  29.    <td>589</td>
  30.    <td>8</td>
  31.  </tr><tr>
  32.    <th>Kenya</th>
  33.    <td>528</td>
  34.    <td>577</td>
  35.    <td>308</td>
  36.    <td>54</td>
  37.    <td>921</td>
  38.  </tr><tr>
  39.    <th>Ouganda</th>
  40.    <td>199</td>
  41.    <td>329</td>
  42.    <td>777</td>
  43.    <td>621</td>
  44.    <td>376</td>
  45.  </tr><tr>
  46.    <th>Rwanda</th>
  47.    <td>278</td>
  48.    <td>69</td>
  49.    <td>539</td>
  50.    <td>717</td>
  51.    <td>790</td>
  52.  </tr><tr>
  53.    <th>Seychelles</th>
  54.    <td>488</td>
  55.    <td>731</td>
  56.    <td>900</td>
  57.    <td>624</td>
  58.    <td>33</td>
  59.  </tr><tr>
  60.    <th>Somalie</th>
  61.    <td>937</td>
  62.    <td>824</td>
  63.    <td>392</td>
  64.    <td>702</td>
  65.    <td>417</td>
  66.  </tr><tr>
  67.    <th>Tanzanie</th>
  68.    <td>942</td>
  69.    <td>228</td>
  70.    <td>271</td>
  71.    <td>890</td>
  72.    <td>275</td>
  73.  </tr><tr>
  74.    <th>Érythrée</th>
  75.    <td>66</td>
  76.    <td>309</td>
  77.    <td>691</td>
  78.    <td>989</td>
  79.    <td>217</td>
  80.  </tr><tr>
  81.    <th>Éthiopie</th>
  82.    <td>625</td>
  83.    <td>974</td>
  84.    <td>806</td>
  85.    <td>819</td>
  86.    <td>412</td>
  87.  </tr>
  88. </table>
  89.  
  90. <h2>Le salut dans la fuite</h2>
  91.  
  92. <div class="piste">
  93.  <span class="coureur">
  94.    <span class="texte1">Attrapez moi.</span>
  95.    <span class="texte2">Perdu, je suis parti.</span>
  96.  </span>
  97. </div>
  98.  
  1. <p>
  2.   Elle passe l'essentiel de son temps à ruminer debout. Mais quand il
  3.  fait très chaud, certaines choisissent de ruminer à ras de
  4.  terre. Les girafes restées debout sont alors chargées de monter la
  5.  garde&nbsp;: une présence indispensable quand le temps nécessaire à
  6.  se relever les rend vulnérables. Les girafes dorment peu. Elles se
  7.  contentent de 20 minutes de sommeil profond. Elles s'y abandonnent
  8.   par tranches de 5 minutes, leur cou arc-bouté et la tête calée tout
  9.   contre les tibias de leurs pattes arrières. Pour se relever, elles
  10.   doivent se balancer quelques secondes&nbsp;: un mouvement nécessaire
  11.   afin de trouver l'élan pour se remettre à la verticale.
  12. </p>
  13. <p>
  14.  La saison des pluies est celle de tous les risques. Si l'eau est
  15.   enfin abondante, encore faut-il pouvoir y accéder. Approcher leur
  16.   tête du sol les oblige à d'incontournables numéros
  17.  d'équilibristes. Heureusement que les girafes peuvent se priver
  18.   d'eau pendant plusieurs jours&nbsp;: un atout quand étancher sa soif
  19.  par terrain glissant peut friser la catastrophe. Si elles redoutent
  20.  la boue humide, elles peuvent parfois tout faire pour humidifier de
  21.  la boue séchée&nbsp;: elles raclent le sol avec leur langue afin de
  22.  collecter les sels minéraux et oligoéléments absents de leur
  23.  nourriture et pourtant indispensables à leur équilibre
  24.  alimentaire. En matière de diététique, tout est bon à manger, même
  25.  les vieux os&nbsp;: une fois dans la bouche, elles peuvent les
  26.  mâchouiller debout.
  27. </p>
  28.  
  1. /* =================================================== */
  2. /*    Présentation générale                            */
  3. /* =================================================== */
  4. body {
  5.   background:rgb(80%,80%,80%);
  6.   font-family:sans-serif;
  7.   text-align:justify;
  8. }
  9. /* =================================================== */
  10. /*    Version, en bas à droite                         */
  11. /* =================================================== */
  12. footer {
  13.   position:fixed;
  14.   bottom:1em;
  15.   right:1em;
  16.   color:rgb(35%,35%,35%);
  17.   font-size:70%;
  18.   font-style:oblique;
  19. }
  20. /* =================================================== */
  21. /*    Menu                                             */
  22. /* =================================================== */
  23. nav.menu {
  24.   position:fixed;
  25.   left:1%;
  26.   top:10%;
  27.   width:17%;
  28.   background:white;
  29.   border:thin silver solid;
  30. }
  31. div.eltmenu, div.eltmenuactif  {
  32.   display:none;
  33. }
  34. nav.menu:hover div.eltmenu {
  35.   display:block;
  36.   padding:3px;
  37.   border: 2px outset rgb(230,230,255);
  38. }
  39. nav.menu:hover div.eltmenu:hover {
  40.   border-style: inset;
  41. }
  42. nav.menu:hover div.eltmenuactif {
  43.   display:block;
  44.   background:rgb(70%,70%,70%);
  45.   padding:3px;
  46.   border: 1px solid rgb(70%,70%,70%);
  47. }
  48. nav.menu a:link {
  49.   text-decoration:none;
  50. }
  51. a:link,a:hover,a:visited,a:visited:hover {
  52.   color:black;
  53. }
  54. /* =================================================== */
  55. /*    Infobulles dans le menu                          */
  56. /* =================================================== */
  57. span.infobulle {
  58.   display:none;
  59. }
  60. div.eltmenuactif:hover span.infobulle,
  61. div.eltmenu:hover span.infobulle {
  62.   display:inline;
  63.   position:absolute;
  64.   top:-2em;
  65.   left:2em;
  66.   border:thin solid blue;
  67.   background:yellow;
  68.   color:blue;
  69.   font-size:80%;
  70.   padding:2px;
  71.   text-align:left;
  72. }
  73. /* =================================================== */
  74. /*    Corps du texte                                   */
  75. /* =================================================== */
  76. main {
  77.   position:absolute;
  78.   left:20%;
  79.   right:3%;
  80.   top:1em;
  81. }
  82. h1 {
  83.   text-align:right;
  84.   margin:0 2em 2em;
  85.   padding:1.5em;
  86.   border:thin solid silver;
  87.   background:url(taches.png);
  88.   font-family:serif;
  89.   font-variant:small-caps;
  90. }
  91. p {
  92.   text-indent:1em;
  93. }
  94. p:first-letter {
  95.   font-size:200%;
  96.   color:rgb(20%,20%,20%);
  97.   font-family:serif;
  98. }
  99. p:first-line {
  100.   font-weight: bold;  
  101.   color:rgb(20%,20%,20%);
  102. }
  103. blockquote {
  104.   font-size:90%;
  105.   font-style:italic;
  106. }
  107. blockquote:before {  
  108.   content:"Remarque. ";
  109.   font-style:normal;
  110.   font-weight:bold;
  111. }
  112. /* =================================================== */
  113. /*    Tableau dans la page des statistiques            */
  114. /* =================================================== */
  115. table {
  116.   border-collapse:collapse;
  117. }
  118. td,th {
  119.   border:thin solid black;
  120.   text-align:right;
  121.   padding:2px 5px;
  122. }
  123. th{  
  124.   color:rgb(90%,90%,90%);
  125.   background:rgb(25%,25%,25%);
  126.   animation: changecouleur 3s infinite;
  127.   /* voir http://www.w3schools.com/cssref/css_animatable.asp */
  128.   /* ou http://www.creativejuiz.fr/blog/tutoriels/quelques-idees-danimations-simples-en-css3 */
  129. }
  130. @keyframes changecouleur {
  131.   from {background-color: blue;}
  132.   to {background-color: orange;}
  133. }
  134. td.vide {
  135.   border:none;
  136.   background:inherit;
  137. }
  138. tr:hover th {
  139.   color:black;
  140. }
  141. tr:hover {
  142.   height:3em;
  143. }
  144. /* =================================================== */
  145. /*    Le salut dans la fuite                           */
  146. /* =================================================== */
  147. .texte1 {
  148.   display:inline;
  149. }
  150. .texte2 {
  151.   display:none;
  152. }
  153. div.piste {
  154.   padding-bottom:5em;
  155. }
  156. div.piste:hover .texte1 {
  157.   display:none;
  158. }
  159. div.piste:hover .texte2 {
  160.   display:inline;
  161.   color:red;
  162. }
  163. .coureur {
  164.   background:rgb(75%,75%,75%);
  165.   padding:0em;
  166.   border:black thin solid;
  167. }
  168. div.piste:hover .coureur {
  169.   position:relative;
  170.   top:-10em;
  171.   left:75%;
  172. }
  173. /* =================================================== */
  174.  
Corrigé final
Seule est donnée la page index.php, qui est la seule à avoir été modifiée depuis la version précédente.
  1. <?php
  2.    $cettepage = basename($_SERVER["PHP_SELF"]);
  3.    $lespages = array(
  4.              "acc"=>array(
  5.                  "fichier"=>"accueil.php",
  6.                  "titre"=>"Accueil",
  7.                  "infobulle"=>"Présentation du site",
  8.                 ),
  9.              "par"=>array(
  10.                  "fichier"=>"particularites.php",
  11.                  "titre"=>"Particularités",
  12.                  "infobulle"=>"Les particularités physiques des girafes",
  13.                 ),
  14.              "def"=>array(
  15.                  "fichier"=>"defense.php",
  16.                  "titre"=>"Des systèmes de défense efficaces",
  17.                 "infobulle"=>"Les girafes ne sont pas aussi fragiles qu'elles en ont l'air",
  18.                 ),
  19.              "pas"=>array(
  20.                  "fichier"=>"pasfacile.php",
  21.                  "titre"=>"Pas facile d'être une girafe !",
  22.                  "infobulle"=>"Les girafes ont de nombreux problèmes à résoudre pour survivre",
  23.                 ),
  24.              "vie"=>array(
  25.                  "fichier"=>"vie.php",
  26.                  "titre"=>"Vie quotidienne",
  27.                  "infobulle"=>"La vie un peu monotone des girafes",
  28.                 ),
  29.              "amo"=>array(
  30.                  "fichier"=>"amour.php",
  31.                  "titre"=>"Vive l'amour",
  32.                  "infobulle"=>"Les rituels amoureux chez les girafes",
  33.                 ),
  34.              "sta"=>array(
  35.                  "fichier"=>"stats.php",
  36.                  "titre"=>"Quelques chiffres",
  37.                  "infobulle"=>"Surtout quelques démonstrations de CSS&nbsp;!!",
  38.                 ),
  39.    );
  40.    if (isset($_GET["p"]) && isset($lespages[$_GET["p"]]))
  41.        $page=$_GET["p"];
  42.    else
  43.        $page="acc";
  44.    $titre=$lespages[$page]["titre"];
  45.    $fichier=$lespages[$page]["fichier"];
  46. ?>
  47. <!DOCTYPE html>
  48. <html>
  49.   <head lang="fr">
  50.     <meta charset="utf-8">
  51.     <link rel="shortcut icon" href="dg.ico" type="image/ico" />
  52.     <link rel="stylesheet"  href="style.css" />
  53.     <title>Les girafes de savane - <?=$titre?></title>
  54.     <!--[if lt IE 9]>
  55.         <script src="html5shiv.js"></script>
  56.         <script src="html5shiv-printshiv.js"></script>
  57.     <![endif]-->        
  58.   </head>
  59.   <body>
  60.    
  61.     <nav class="menu">
  62.       Menu&nbsp;:
  63. <?php
  64.   foreach ($lespages as $code => $unepage) {
  65.       $letitre = $unepage["titre"];
  66.       $infobulle = $unepage["infobulle"];
  67.  
  68.       echo "\t<div class=\"eltmenu".($page==$code?"actif":"")
  69.           ."\">\n\t\t<a href=\"$cettepage?p=$code\">$letitre</a>\n"
  70.           ."\t\t<span class=\"infobulle\">$infobulle</span>\n\t</div>\n";
  71.   }
  72.   echo "\t</nav>\n\t<main>\n";
  73.   echo "\t\t<h1>Les girafes de savane - $titre</h1>\n";
  74.   require($fichier);
  75. ?>      
  76.     </main>
  77.     <footer>
  78.       Version PHP n°2.0 (passage à PHP)
  79.     </footer>
  80.   </body>
  81. </html>
  82.  

Girafes 2.1 : cookies

Vous pouvez voir ici ce qu'on attend de vous.

Une seule amélioration depuis la version précédente, l'utilisation d'un cookie qui se souvient de la dernière page visitée : quand on revient sur le site, c'est cette page qui s'ouvre.

Un corrigé
Seule est donnée la page index.php, qui est la seule à avoir été modifiée depuis la version précédente.
  1. <?php
  2.    $cettepage = basename($_SERVER["PHP_SELF"]);
  3.    $lespages = array(
  4.              "acc"=>array(
  5.                  "fichier"=>"accueil.php",
  6.                  "titre"=>"Accueil",
  7.                  "infobulle"=>"Présentation du site",
  8.                 ),
  9.              "par"=>array(
  10.                  "fichier"=>"particularites.php",
  11.                  "titre"=>"Particularités",
  12.                  "infobulle"=>"Les particularités physiques des girafes",
  13.                 ),
  14.              "def"=>array(
  15.                  "fichier"=>"defense.php",
  16.                  "titre"=>"Des systèmes de défense efficaces",
  17.                  "infobulle"=>"Les girafes ne sont pas aussi fragiles qu'elles en ont l'air",
  18.                 ),
  19.              "pas"=>array(
  20.                  "fichier"=>"pasfacile.php",
  21.                  "titre"=>"Pas facile d'être une girafe !",
  22.                  "infobulle"=>"Les girafes ont de nombreux problèmes à résoudre pour survivre",
  23.                 ),
  24.              "vie"=>array(
  25.                  "fichier"=>"vie.php",
  26.                  "titre"=>"Vie quotidienne",
  27.                  "infobulle"=>"La vie un peu monotone des girafes",
  28.                 ),
  29.              "amo"=>array(
  30.                  "fichier"=>"amour.php",
  31.                  "titre"=>"Vive l'amour",
  32.                  "infobulle"=>"Les rituels amoureux chez les girafes",
  33.                 ),
  34.              "sta"=>array(
  35.                  "fichier"=>"stats.php",
  36.                  "titre"=>"Quelques chiffres",
  37.                  "infobulle"=>"Surtout quelques démonstrations de CSS&nbsp;!!",
  38.                 ),
  39.    );
  40.    if (isset($_GET["p"]) && isset($lespages[$_GET["p"]]))
  41.        $page=$_GET["p"];
  42.    elseif (isset($_COOKIE["dernièrepage"]))
  43.        $page=$_COOKIE["dernièrepage"];
  44.    else
  45.        $page="acc";
  46.  
  47.    setcookie("dernièrepage", "$page");
  48.    $titre=$lespages[$page]["titre"];
  49.    $fichier=$lespages[$page]["fichier"];
  50. ?>
  51. <!DOCTYPE html>
  52. <html>
  53.   <head lang="fr">
  54.     <meta charset="utf-8">
  55.     <link rel="shortcut icon" href="dg.ico" type="image/ico" />
  56.     <link rel="stylesheet"  href="style.css" />
  57.     <title>Les girafes de savane - <?=$titre?></title>
  58.     <!--[if lt IE 9]>
  59.         <script src="html5shiv.js"></script>
  60.         <script src="html5shiv-printshiv.js"></script>
  61.     <![endif]-->        
  62.   </head>
  63.   <body>
  64.    
  65.     <nav class="menu">
  66.       Menu&nbsp;:
  67. <?php
  68.   foreach ($lespages as $code => $unepage) {
  69.       $letitre = $unepage["titre"];
  70.       $infobulle = $unepage["infobulle"];
  71.  
  72.       echo "\t<div class=\"eltmenu".($page==$code?"actif":"")
  73.           ."\">\n\t\t<a href=\"$cettepage?p=$code\">$letitre</a>\n"
  74.           ."\t\t<span class=\"infobulle\">$infobulle</span>\n\t</div>\n";
  75.   }
  76.   echo "\t</nav>\n\t<main>\n";
  77.   echo "\t\t<h1>Les girafes de savane - $titre</h1>\n";
  78.   require($fichier);
  79. ?>      
  80.     </main>
  81.     <footer>
  82.       Version PHP n°2.1 (<em>cookie</em>)
  83.     </footer>
  84.   </body>
  85. </html>
  86.  

Girafes 3.0 bêta : identifier vos visiteurs, première ébauche

Vous pouvez voir ici ce qu'on attend de vous.

Il y a trois niveaux d'autorisation : faible, moyen, élevé.
Le niveau d'autorisation influe sur le nombre de pages accessibles :

  • Au niveau faible, correspondant à l'absence d'identification, seules quelques pages sont accessibles.
  • Au niveau moyen, correspondant au login hardelpic (mot de passe : haha), quelques pages supplémentaires sont accessibles.
  • Au niveau élevé, correspondant au login abiback (mot de passe : abab), toutes les pages sont accessibles.
Un corrigé
Seule est donnée la page index.php, qui est la seule à avoir été modifiée depuis la version précédente.
  1. <?php
  2.    // ===================================================
  3.    //     IDENTIFICATION
  4.    // ===================================================
  5.    // début de session
  6.    // nouvel utilisateur ??
  7.    if (isset($_POST["login"])) {
  8.      $_SESSION["login"]=$_POST["login"];
  9.      $_SESSION["mdp"]=$_POST["mdp"];
  10.    }  
  11.    // Déconnexion
  12.    if ( isset($_POST["off"])) {
  13.       $qui=NULL;
  14.       $niveau=0;
  15.    } elseif (   isset($_SESSION["login"])) {    // identification
  16.       if ( ($_SESSION["login"]=="hardelpic")&&($_SESSION["mdp"]=="haha") ) {
  17.          $qui="Helmut HARDELPIC";
  18.          $niveau=2;
  19.       } elseif ( ($_SESSION["login"]=="abiback")&&($_SESSION["mdp"]=="abab") ) {
  20.          $qui="Al BIBACK";
  21.          $niveau=1;
  22.       } else {
  23.         $qui=NULL;
  24.         $niveau=0;
  25.       }
  26.    }
  27.    // ===================================================
  28.    //     GESTION DES PAGES À AFFICHER
  29.    // ===================================================
  30.    $cettepage = basename($_SERVER["PHP_SELF"]);
  31.    $lespages = array(
  32.              "acc"=>array(
  33.                  "fichier"=>"accueil.php",
  34.                  "titre"=>"Accueil",
  35.                  "infobulle"=>"Présentation du site",
  36.                  "niveau"=>0,
  37.                 ),
  38.              "par"=>array(
  39.                  "fichier"=>"particularites.php",
  40.                  "titre"=>"Particularités",
  41.                  "infobulle"=>"Les particularités physiques des girafes",
  42.                  "niveau"=>0,
  43.                 ),
  44.              "def"=>array(
  45.                  "fichier"=>"defense.php",
  46.                  "titre"=>"Des systèmes de défense efficaces",
  47.                 "infobulle"=>"Les girafes ne sont pas aussi fragiles qu'elles en ont l'air",
  48.                  "niveau"=>0,
  49.                 ),
  50.              "pas"=>array(
  51.                  "fichier"=>"pasfacile.php",
  52.                  "titre"=>"Pas facile d'être une girafe !",
  53.                  "infobulle"=>"Les girafes ont de nombreux problèmes à résoudre pour survivre",
  54.                  "niveau"=>1,
  55.                 ),
  56.              "vie"=>array(
  57.                  "fichier"=>"vie.php",
  58.                  "titre"=>"Vie quotidienne",
  59.                  "infobulle"=>"La vie un peu monotone des girafes",
  60.                  "niveau"=>1,
  61.                 ),
  62.              "amo"=>array(
  63.                  "fichier"=>"amour.php",
  64.                  "titre"=>"Vive l'amour",
  65.                  "infobulle"=>"Les rituels amoureux chez les girafes",
  66.                  "niveau"=>2,
  67.                 ),
  68.              "sta"=>array(
  69.                  "fichier"=>"stats.php",
  70.                  "titre"=>"Quelques chiffres",
  71.                  "infobulle"=>"Surtout quelques démonstrations de CSS&nbsp;!!",
  72.                  "niveau"=>2,
  73.                 ),
  74.    );
  75.    if (isset($_GET["p"]) && isset($lespages[$_GET["p"]])) // on vient du menu
  76.        $page=$_GET["p"];
  77.    elseif (isset($_POST["p"]) && isset($lespages[$_POST["p"]])) // on vient du formulaire de (dé)connexion
  78.        $page=$_POST["p"];
  79.    elseif (isset($_COOKIE["dernièrepage"])) // on se souvient d'une visite précédente
  80.        $page=$_COOKIE["dernièrepage"];
  81.    else // page par défaut
  82.        $page="acc";
  83.    // éviter de rester sur une page non autorisée
  84.    if ($niveau < $lespages[$page]["niveau"])
  85.        $page="acc";
  86.  
  87.    setcookie("dernièrepage", "$page");
  88.    $titre=$lespages[$page]["titre"];
  89.    $fichier=$lespages[$page]["fichier"];
  90. ?>
  91. <!DOCTYPE html>
  92. <html>
  93.   <head lang="fr">
  94.     <meta charset="utf-8">
  95.     <link rel="shortcut icon" href="dg.ico" type="image/ico" />
  96.     <link rel="stylesheet"  href="style.css" />
  97.     <title>Les girafes de savane - <?=$titre?></title>
  98.     <!--[if lt IE 9]>
  99.         <script src="html5shiv.js"></script>
  100.         <script src="html5shiv-printshiv.js"></script>
  101.     <![endif]-->        
  102.   </head>
  103.   <body>
  104.    
  105.     <nav class="menu">
  106.       Menu&nbsp;:
  107. <?php
  108.   // ===================================================
  109.   //     MENU
  110.   // ===================================================
  111.   foreach ($lespages as $code => $unepage) {
  112.       $letitre = $unepage["titre"];
  113.       $infobulle = $unepage["infobulle"];
  114.       $leniveau= $unepage["niveau"];
  115.       if ($leniveau <= $niveau) {
  116.          echo "\t<div class=\"eltmenu".($page==$code?"actif":"")
  117.             ."\">\n\t\t<a href=\"$cettepage?p=$code\">$letitre</a>\n"
  118.             ."\t\t<span class=\"infobulle\">$infobulle</span>\n\t</div>\n";
  119.       }
  120.   }
  121.   // ===================================================
  122.   //     FORMULAIRE DE (DÉ)CONNEXION
  123.   // ===================================================
  124.   echo "\t<div class=\"eltmenu\">\n";
  125.   if (isset($qui)) {
  126.     // Bienvenue si identifié
  127.     echo "<span class=\"bienvenue\">Bienvenue $qui.</span><br/>";
  128.     // Formulaire de déconnexion
  129.     echo "<form action=\"$cettepage\" method=\"post\">\n";
  130.     echo "<input type=\"hidden\" value=\"1\" name=\"off\">\n";
  131.     echo "<input type=\"hidden\" value=\"$page\" name=\"p\">\n";
  132.     echo "<input type=\"submit\" value=\"Déconnexion\">\n";
  133.     echo "</form>\n";
  134.   } else {
  135.     // Formulaire de connexion
  136.     echo "<form action=\"$cettepage\" method=\"post\">\n";
  137.     echo "<input name=\"login\" placeholder=\"login\"><br/>\n";
  138.     echo "<input name=\"mdp\" type=\"password\" placeholder=\"mot de passe\"><br/>\n";
  139.     echo "<input type=\"hidden\" value=\"$page\" name=\"p\">\n";
  140.     echo "<input type=\"submit\" value=\"Connexion\">\n";
  141.     echo "</form>\n";
  142.   }
  143.   echo "</div>\n\t</nav>\n\t<main>\n";
  144.   // ===================================================
  145.   //     TITRE ET INCLUSION DU FICHIER SÉLECTIONNÉ
  146.   // ===================================================
  147.   echo "\t\t<h1>Les girafes de savane - $titre</h1>\n";
  148.   require($fichier);
  149. ?>      
  150.     </main>
  151.     <footer>
  152.       Version PHP n°3.0 <em>bêta</em> (sessions et identification)
  153.     </footer>
  154.   </body>
  155. </html>
  156.  

Girafes 3.0 : identifier vos visiteurs

Vous pouvez voir ici ce qu'on attend de vous.

Le problème est identique au précédent, mais cette fois les utilisateurs autorisés ne sont plus seulement deux, codés dans le programme, mais sont listés dans un fichier texte (liste.txt) dont la structure est :

  • un utilisateur par ligne ;
  • les informations sont séparées par un double-point ;
  • les informations sont, dans cet ordre : identifiant de connexion (login), mot de passe, niveau d'autorisation (1 pour ceux qui ont un niveau d'autorisation élevé, ou 2 pour ceux qui ont un niveau d'autorisation moyen), nom de famille, prénom.

Exemple d'une ligne :

tblaire:xnwvic:1:Blaireur:Terry
Un corrigé
Seules sont données la page index.php, qui est la seule à avoir été modifiée depuis la version précédente, et le fichier liste.txt qui contient les identifiants de connexion des utilisateurs.
  1. <?php
  2.    // ===================================================
  3.    //     IDENTIFICATION
  4.    // ===================================================
  5.    // début de session
  6.    // lecture du fichier et création de la liste des utilisateurs
  7.    $f = file("liste.txt");
  8.    $utilisateurs = array();
  9.    foreach ($f as $ligne) { // pour toutes les lignes du fichier
  10.      $user = explode(":",trim($ligne)) ; // exloser la loignes selon les deux-points
  11.      $utilisateurs[$user[0]]= array( // la clef est le login
  12.                                      "mdp" => $user[1], // mot de passe
  13.                                      "niv" => $user[2], // niveau d'autorisation
  14.                                      "nom" => $user[3], // nom de famille
  15.                                      "pre" => $user[4], // prénom
  16.                                   );
  17.    }
  18.    // au sortir de cette boucle, pour chaque $utilisateurs[$k]:
  19.    //  *  $k                        est  le login d'un utilisateur
  20.    //  *  $utilisateurs[$k]["mdp"]  est  son mot de passe
  21.    //  *  $utilisateurs[$k]["niv"]  est  son niveau d'autorisation
  22.    //  *  $utilisateurs[$k]["nom"]  est  est son nom de famille
  23.    //  *  $utilisateurs[$k]["pre"]  est  son prénom
  24.  
  25.    if (isset($_POST["login"])) { // on vient du formulaire de connexion : on redéfinit les variables de session
  26.      $_SESSION["login"]=$_POST["login"];
  27.      $_SESSION["mdp"]=$_POST["mdp"];
  28.    }  
  29.    // Déconnexion
  30.    if (
  31.            isset($_POST["off"])        // on vient du formulaire de déconnexion
  32.        || !isset($_SESSION["login"])  // aucune session en cours
  33.       ) { //  ->  utilisateur inconnu
  34.       $qui=NULL;
  35.       $niveau=0;
  36.    } elseif (isset($_SESSION["login"])) {   // une session est cours (nouvelle ou ancienne)
  37.       if (
  38.            isset($utilisateurs[$_SESSION["login"]])   // l'utilisateur existe
  39.         && ( $_SESSION["mdp"]==$utilisateurs[$_SESSION["login"]]["mdp"] ) // le login et le mot de passe correspondent
  40.          ) { // identification réussie - on récupère les informations
  41.            $u = $utilisateurs[$_SESSION["login"]] ; // pour alléger les écritures suivantes
  42.            $qui=$u["pre"]." <span style=\"font-variant:small-caps;\">".$u["nom"]."</span>" ;
  43.            $niveau=$u["niv"];
  44.       } else {  // échec de la connexion -> utilisateur inconnu
  45.         $qui=NULL;
  46.         $niveau=0;
  47.       }
  48.    }
  49.    // ===================================================
  50.    //     GESTION DES PAGES À AFFICHER
  51.    // ===================================================
  52.    $cettepage = basename($_SERVER["PHP_SELF"]);
  53.    $lespages = array(
  54.              "acc"=>array(
  55.                  "fichier"=>"accueil.php",
  56.                  "titre"=>"Accueil",
  57.                  "infobulle"=>"Présentation du site",
  58.                  "niveau"=>0,
  59.                 ),
  60.              "par"=>array(
  61.                  "fichier"=>"particularites.php",
  62.                  "titre"=>"Particularités",
  63.                  "infobulle"=>"Les particularités physiques des girafes",
  64.                  "niveau"=>0,
  65.                 ),
  66.              "def"=>array(
  67.                  "fichier"=>"defense.php",
  68.                  "titre"=>"Des systèmes de défense efficaces",
  69.                 "infobulle"=>"Les girafes ne sont pas aussi fragiles qu'elles en ont l'air",
  70.                  "niveau"=>0,
  71.                 ),
  72.              "pas"=>array(
  73.                  "fichier"=>"pasfacile.php",
  74.                  "titre"=>"Pas facile d'être une girafe !",
  75.                  "infobulle"=>"Les girafes ont de nombreux problèmes à résoudre pour survivre",
  76.                  "niveau"=>1,
  77.                 ),
  78.              "vie"=>array(
  79.                  "fichier"=>"vie.php",
  80.                  "titre"=>"Vie quotidienne",
  81.                  "infobulle"=>"La vie un peu monotone des girafes",
  82.                  "niveau"=>1,
  83.                 ),
  84.              "amo"=>array(
  85.                  "fichier"=>"amour.php",
  86.                  "titre"=>"Vive l'amour",
  87.                  "infobulle"=>"Les rituels amoureux chez les girafes",
  88.                  "niveau"=>2,
  89.                 ),
  90.              "sta"=>array(
  91.                  "fichier"=>"stats.php",
  92.                  "titre"=>"Quelques chiffres",
  93.                  "infobulle"=>"Surtout quelques démonstrations de CSS&nbsp;!!",
  94.                  "niveau"=>2,
  95.                 ),
  96.    );
  97.    if (isset($_GET["p"]) && isset($lespages[$_GET["p"]])) // on vient du menu
  98.        $page=$_GET["p"];
  99.    elseif (isset($_POST["p"]) && isset($lespages[$_POST["p"]])) // on vient du formulaire de (dé)connexion
  100.        $page=$_POST["p"];
  101.    elseif (isset($_COOKIE["dernièrepage"])) // on se souvient d'une visite précédente
  102.        $page=$_COOKIE["dernièrepage"];
  103.    else // page par défaut
  104.        $page="acc";
  105.    // éviter de rester sur une page non autorisée
  106.    if ($niveau < $lespages[$page]["niveau"])
  107.        $page="acc";
  108.  
  109.    setcookie("dernièrepage", "$page");
  110.    $titre=$lespages[$page]["titre"];
  111.    $fichier=$lespages[$page]["fichier"];
  112. ?>
  113. <!DOCTYPE html>
  114. <html>
  115.   <head lang="fr">
  116.     <meta charset="utf-8">
  117.     <link rel="shortcut icon" href="dg.ico" type="image/ico" />
  118.     <link rel="stylesheet"  href="style.css" />
  119.     <title>Les girafes de savane - <?=$titre?></title>
  120.     <!--[if lt IE 9]>
  121.         <script src="html5shiv.js"></script>
  122.         <script src="html5shiv-printshiv.js"></script>
  123.     <![endif]-->        
  124.   </head>
  125.   <body>
  126.    
  127.     <nav class="menu">
  128.       Menu&nbsp;:
  129. <?php
  130.   // ===================================================
  131.   //     MENU
  132.   // ===================================================
  133.   foreach ($lespages as $code => $unepage) {
  134.       $letitre = $unepage["titre"];
  135.       $infobulle = $unepage["infobulle"];
  136.       $leniveau= $unepage["niveau"];
  137.       if ($leniveau <= $niveau) {
  138.          echo "\t<div class=\"eltmenu".($page==$code?"actif":"")
  139.             ."\">\n\t\t<a href=\"$cettepage?p=$code\">$letitre</a>\n"
  140.             ."\t\t<span class=\"infobulle\">$infobulle</span>\n\t</div>\n";
  141.       }
  142.   }
  143.   // ===================================================
  144.   //     FORMULAIRE DE (DÉ)CONNEXION
  145.   // ===================================================
  146.   echo "\t<div class=\"eltmenu\">\n";
  147.   if (isset($qui)) {
  148.     // Bienvenue si identifié
  149.     echo "<span class=\"bienvenue\">Bienvenue $qui.</span><br/>";
  150.     // Formulaire de déconnexion
  151.     echo "<form action=\"$cettepage\" method=\"post\">\n";
  152.     echo "<input type=\"hidden\" value=\"1\" name=\"off\">\n";
  153.     echo "<input type=\"hidden\" value=\"$page\" name=\"p\">\n";
  154.     echo "<input type=\"submit\" value=\"Déconnexion\">\n";
  155.     echo "</form>\n";
  156.   } else {
  157.     // Formulaire de connexion
  158.     echo "<form action=\"$cettepage\" method=\"post\">\n";
  159.     echo "<input name=\"login\" placeholder=\"login\"><br/>\n";
  160.     echo "<input name=\"mdp\" type=\"password\" placeholder=\"mot de passe\"><br/>\n";
  161.     echo "<input type=\"hidden\" value=\"$page\" name=\"p\">\n";
  162.     echo "<input type=\"submit\" value=\"Connexion\">\n";
  163.     echo "</form>\n";
  164.   }
  165.   echo "</div>\n\t</nav>\n\t<main>\n";
  166.   // ===================================================
  167.   //     TITRE ET INCLUSION DU FICHIER SÉLECTIONNÉ
  168.   // ===================================================
  169.   echo "\t\t<h1>Les girafes de savane - $titre</h1>\n";
  170.   require($fichier);
  171. ?>      
  172.     </main>
  173.     <footer>
  174.       Version PHP n°3.0 (identification des utilisateurs dans une liste)
  175.     </footer>
  176.   </body>
  177. </html>
  178.  
  1. uidekki:pqxcza:1:Idekkilahula:Ulrich
  2. hvrante:oxwdea:1:Vrante:Hélèna
  3. cbansyl:vgixka:2:Bansyla:Carry
  4. ypalafe:ojdipb:1:Palafer:Yvon
  5. jantoud:hwmgjb:1:Antoudrol:James
  6. atabani:inhhjc:2:Tabaniol:Alphonse
  7. tchmonf:vwrxcc:1:Chmonfisse:Thierry
  8. tblaire:xnwvic:1:Blaireur:Terry
  9. dsmoilp:yxmxgd:1:Smoilplancher:Debora
  10. pinhouv:yldcid:2:Inhouvonleichoz:Piotr
  11. sfonfec:edwpyf:1:Fonfec:Sophie
  12. astanma:bouixf:2:Stanmaime:Alain
  13. rlandem:fnkdxg:2:Landemin:Roméo
  14. tabouce:zjqqih:1:Aboucepartou:Thècle
  15. ohotdeu:bkbzxh:1:Hotdeugou:Olaf
  16. cdeuner:iikfuh:2:Deunère:Chris
  17. ades_ha:rffpri:1:Des Hartisses:André
  18. menfail:inijxj:2:Enfaillite:Mélusine
  19. erivenb:fuenij:2:Rivenbusse:Elsa
  20. tornot_:viozlj:1:Ornot Toby:Tobbie
  21. tfairan:cpulmk:1:Fairant:Teddy
  22. straibi:jhqgxk:2:Traibien:Samira
  23. yakpour:ywgrpk:1:Akpourli:Yann
  24. joultan:cfllgl:2:Oultan:Judith
  25. adurine:zwvqxl:1:Durine:Anne-Alice
  26. cmayard:xmxsul:1:Mayard:Colin
  27. azeublo:kyqyvm:2:Zeublouze:Agathe
  28. apatamo:gvvlrm:2:Patamob:Adhémar
  29. tassicm:qmanjn:1:Assicmonpote:Thècle
  30. jmontou:snqhcn:1:Montour:Jonathan
  31. podlavi:zlmron:2:Odlavieille:Pacôme
  32. oeurktu:xqubro:1:Eurktumeme:Odile
  33. lde_hur:lvjcbo:1:De Hurlevent:Léo
  34. jairien:obvpqp:2:Airien Kompry:Johnny
  35. yanchie:eefgdp:1:Anchier:Yvon
  36. hpeursc:bnupop:2:Peursconla:Humphrey
  37. yadroui:ztiqpp:2:Adrouille-Toultan:Yves
  38. wklozet:hklloq:1:Klozett:Walter
  39. adanleu:wbesjr:2:Danleubrouyar:Alphonse
  40. akuzbid:sdbkpr:1:Kuzbidon:Alex
  41. hardelp:fcuoys:1:Ardelpic:Helmut
  42. tajerre:osotms:2:Ajerre:Tex
  43. tphotot:rwiqht:2:Phototetedemort:Thomas
  44. xkaecou:desujt:1:Kaécouté:Xavier
  45. dzoudan:rfbssv:2:Zoudanlkou:Debbie
  46. pleglas:czkjvw:1:Leglas:Parkinson
  47. rnissan:pvskww:2:Nissance:Rémi
  48. svigott:wiorow:1:Vigott:Sarah
  49. ktartin:exxtjx:2:Tartinn:Kimberley
  50. qamarta:ewqmjx:2:Amartakaldire:Quentin
  51. jchopin:tteugy:2:Chopine:Justine
  52. ttaloni:rzqzmz:2:Talonion:Thomas
  53.  
Dernière modification : 20/4/2017

Semaine du lendi 24 averil 2017 : TD n°13 (Cumul=24h)

Le contrôle n°2 aura lieu le vendredi 12 mai, de 9h à 10h30, dans les conditions suivantes :
  • sur feuille,
  • tous documents PAPIER autorisés,
  • aucun document électronique (liseuse, tablette, ordinateur, téléphone, etc.).

JavaScript

Présentation

Une grande partie de ce texte provient des pages citées dans les liens ci-dessous.

Javascript a été créé par Netscape (le nom était livescript au départ) pour développer des applications internet et, par la même occasion, pour étendre les possibilités du HTML.
Il s'agit d'un langage léger et orienté objet, permettant d'écrire des scripts.
Attention : il ne faut pas confondre Java et Javascript ! Java est un langage de programmation développé par SUN et non un langage de script comme Javascript. De plus, les scripts écrits avec Javascript sont interprétés par le navigateur et incorporés dans le code HTML, ce qui n'est pas le cas du langage Java.

Quelques bonnes lectures :

Plus loin :

Les événements

Exemple avec les événements de base :

  1. <input type="button"
  2.        value="au départ..."
  3.        id="monbouton"
  4.        onMouseOver="this.value='souris présente'"
  5.        onMouseOut="this.value='souris absente'"
  6.        onFocus="this.value='focus'"
  7.        onBlur="this.value='j\'ai perdu le focus'"
  8.        onClick="this.value='ça chatouille...'" >
Ce que cela donne
Il existe d'autres événements :
  • onChange : on quitte une zone que l'utilisateur a modifiée (un champ d'un formulaire par exemple) ;
  • onLoad : une page est chargée ;
  • onSelect : sélectionner un champ d'un formulaire ;
  • onSubmit : soumettre un formulaire (envoyer) ;
  • onUnload : quitter la page.

On pourra accéder à un élément par getElementById(identifiant).

Ainsi on pourra modifier le texte du bouton de l'exemple précédent par :

  1. <span onMouseOver="getElementById('monbouton').value='Je suis au dessus...';"
  2.       onMouseOut="getElementById('monbouton').value='Je n\'y suis plus';">
  3.    <em>Passer au dessus de cette phrase et regardez le bouton précédent</em>
  4. </span>
Ce que cela donne
Passer au dessus de cette phrase et regardez le bouton précédent

Conséquence : une action quelque part peut sans difficulté avoir un effet ailleurs.

Plusieurs actions

Il possible d'exécuter plusieurs actions lors de l'activation d'un événement :
  1. <input type="button" id="deuxA" value="Passez ici..."
  2.        onMouseOver="this.value='Une action...';getElementById('deuxB').value='Une autre action...';"
  3.        onMouseOut="this.value='Passez ici...';getElementById('deuxB').value='Celui-ci n\'a pas d\'effet';" />
  4. <input type="button" id="deuxB" value="Celui-ci n'a pas d'effet">
Ce que cela donne

Exercices

  1. Réaliser une page HTML contenant quatre boutons :
    • si on clique sur le premier, un message s'affiche dans le deuxième ;
    • si on clique sur le deuxième, un message s'affiche dans le troisième ;
    • si on clique sur le troisième, un message s'affiche dans le quatrième ;
    • si on clique sur le quatrième, un message s'affiche dans le premier.
    (Une solution, ou une autre.)
  2. Les événements onClick, onMouseOut, onMouseOver, etc. peuvent s'appliquer à autre chose que des boutons.
    Écrire une page HTML comportant 2 boutons (appelés 1 et 2) et un texte (appelé 3). Utiliser les différents événements pour modifier le texte des boutons au clic et au survol des boutons et du texte. (Solution.)

Écrire dans le texte

  1. <script>
  2.   document.write('Ce texte n\'est pas dans le code source HTML, et ce calcul non plus : '+(5+8));
  3. </script>
Ce que cela donne

Bien entendu, en jouant sur les mots, le texte peut quand même être considéré comme « étant dans le code source HTML », puisqu'il a bien fallu écrire le code JavaScript dans la page HTML. Ce qu'il faut comprendre dans cette phrase c'est qu'on n'a pas écrit la ligne telle quelle dans le code HTML, mais que c'est bien le programme JavaScript qui a fait le travail. On pourait imaginer un programme (plus complexe, et hors de nos capacités pour l'instant) qui va chercher des données ailleurs (base de données, fichier, etc.) et les utilise pour écrire de lui-même le code HTML.

Attention, la fonction document.write ne peut pas modifier une page déjà affichée (on verra plus tard la fonction innerHtml qui permet de réaliser cela).

Des boîtes : un bouton

  1. <span onMouseOver="alert('Quelqu\'un est passé par là...');"><em>Passer au dessus de cette phrase</em></span>
Ce que cela donne
Passer au dessus de cette phrase

Des boîtes : saisie

  1. <input type="button" value="Cliquez ici..." name="unbouton"
  2.         onClick="this.value='Vous avez tapé : '+prompt('Tapez quelque chose');">
Ce que cela donne

Des boîtes : deux boutons

  1. <input type="button" value="Cliquez ici..." name="unbouton"
  2.         onClick="this.value='Cliquez ici... (Votre choix&nbsp;: '+confirm('Êtes vous d\'accord avec ça')+')';">
Ce que cela donne

Exercices

  1. Créer une alerte qui affiche « Hello World ! » en utilisant alert(). (Solution.)
  2. Utiliser la fonction prompt() pour demander son prénom à l'utilisateur et afficher dans une boîte alerte « Bonjour ….. » avec le prénom entré. (Solution.)
  3. Demander à l'utilisateur deux nombres et afficher leur somme avec prompt() et alert() (vous devrez convertir le nombre entré en entier avec parseInt()). (Solution.)
  4. Un champ input de type text (c'est-à-dire <input type="text" ...>) est en fait une zone de saisie. Utiliser de tels champs pour construire une calculatrice élémentaire. (Solution.)

Variables

En JavaScript les noms des variables doivent obligatoirement commencer par une lettre ou le symbole « _ », suivi d'une suite de lettres, de chiffres ou du symbole « _ ».

En JavaScript comme dans de nombreux autres langages, l’opération d’affectation est représentée par le signe « = ».

Pour utiliser la valeur d'une variable il suffit de l'appeler par son nom.

Vous pouvez aussi aller lire le cours de Fabien Torre.

Exemple récapitulatif

demoJS-01.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html>
  3.   <head lang="fr">
  4.     <meta charset="utf-8">
  5.     <title>JavaScript, exemple n°1</title>
  6.   </head>
  7.   <body>
  8.     <h1>JavaScript, exemple n°1</h1>
  9.    
  10.     <script>
  11.       document.writeln("Hello world<br/>");
  12.            
  13.       // pour marquer une séparation sur la page vue dans le navigateur
  14.       document.writeln ("\n<hr/>\n");
  15.      
  16.       prenom = 'Toto';
  17.       document.write("salut ");
  18.       document.writeln(prenom);
  19.       document.writeln("<p>ça va aujourd'hui ?</p>");
  20.       document.writeln('<p>oui, ça va aujourd\'hui !</p>');
  21.      
  22.       // pour marquer une séparation sur la page vue dans le navigateur
  23.       document.writeln ("\n<hr/>\n");
  24.  
  25.       prenom = 'Marcel';
  26.       document.writeln("salut "+prenom+"<p>ça va aujourd'hui ?</p>\n<p>oui, ça va aujourd\'hui !</p>");
  27.  
  28.       // pour marquer une séparation sur la page vue dans le navigateur
  29.       document.writeln ("\n<hr/>\n");
  30.  
  31.       x = 5 ;
  32.       document.writeln ("Le carré de " + x + " est " + (x*x) + ".<br/>") ;
  33.       x = 7 ;
  34.       document.writeln ("Le carré de " + x + " est " + (x*x) + ".<br/>") ;
  35.       x = 12 ;
  36.       document.writeln ("Le carré de " + x + " est " + (x*x) + ".<br/>") ;
  37.  
  38.     </script>
  39.   </body>
  40. </html>
  41.  

Fonctions

Une fonction peut renvoyer un résultat...
  1. <script>
  2. function carre (x) {
  3.    return x*x;
  4. }
  5. </script>
... ou pas (c'est ce qu'on appelle une procédure dans d'autres langages) :
  1. <script>
  2. function afficher (prenom) {
  3.    document.write("salut ");
  4.    document.writeln(prenom);
  5.    document.writeln("<p>ça va aujourd'hui ?</p>");
  6.    document.writeln('<p>oui, ça va aujourd\'hui !</p>');
  7.    document.writeln();
  8. }
  9. </script>

Plus d'informations sur le cours de Fabien Torre.

Autre version de l'exemple récapitulatif

demoJS-02.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html>
  3.   <head lang="fr">
  4.     <meta charset="utf-8">
  5.     <title>JavaScript, exemple n°2</title>
  6.   </head>
  7.   <body>
  8.     <h1>JavaScript, exemple n°2</h1>
  9.    
  10.     <script>
  11.       // ===================================================
  12.       // Pour marquer une séparation sur la page vue dans le navigateur
  13.       function ligne () {
  14.         document.writeln ("\n<hr/>\n");
  15.       }
  16.       // ===================================================
  17.       // Afficher pour un prénom
  18.       function afficher (prenom) {
  19.         document.write("salut ");
  20.         document.writeln(prenom);
  21.         document.writeln("<p>ça va aujourd'hui ?</p>");
  22.         document.writeln('<p>oui, ça va aujourd\'hui !</p>');
  23.         document.writeln();
  24.       }
  25.       // ===================================================
  26.       function carre (x) {
  27.         return 'Le carré de ' + x + ' est ' + (x*x) + '.<br/>' ;
  28.       }
  29.       // ===================================================
  30.  
  31.       afficher ('Toto');
  32.       ligne ();
  33.       lui = 'Marcel';
  34.       afficher (lui)
  35.       ligne ();
  36.       Georges = 'Henri';
  37.       afficher (Georges);
  38.       ligne ();
  39.       document.writeln( carre(2) );
  40.       document.writeln( carre(5), carre(10), carre(3) );
  41.     </script>
  42.   </body>
  43. </html>
  44.  

Modifier le code HTML avec Javascript

La fonction innerHTML permet de modifier le code HTML à l'intérieur de la page.

demoJS-03.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html>
  3.   <head lang="fr">
  4.     <meta charset="utf-8">
  5.     <title>JavaScript, exemple n°3</title>
  6.   </head>
  7.   <body>
  8.     <h1>JavaScript, exemple n°3</h1>
  9.  
  10.     <div id="unDiv"></div>  
  11.    
  12.     <input type="button" value="Cliquez ici pour ajouter un tableau"
  13.             onClick="getElementById('unDiv').innerHTML='<table><tr><th>xx</th><td>yy</td></table>';"><br/>
  14.  
  15.     <input type="button" value="Cliquez ici pour ajouter une image"
  16.             onClick="getElementById('unDiv').innerHTML='<img src=\'13.jpg\' alt=\'une image\'>';"><br/>
  17.  
  18.     <input type="button" value="Cliquez ici pour vider la zone"
  19.             onClick="getElementById('unDiv').innerHTML='';">
  20.  
  21.   </body>
  22. </html>
  23.  

Interaction de Javascript avec les CSS

  1. <script>
  2. function change(elt) {
  3.   if (document.body.style.color=='blue') {
  4.      document.body.style.color='orange';
  5.      document.body.style.backgroundImage='none';
  6.      document.body.style.backgroundColor='#aaaaff';
  7.   } else  {
  8.      document.body.style.color='blue';
  9.      document.body.style.backgroundColor='yellow';
  10.      document.body.style.backgroundImage='none';
  11.   }
  12.   elt.value='Cliquer ici : '+document.body.style.color+'/'+document.body.style.backgroundColor;
  13. }
  14. </script>
  15. Un peu de couleurs...
  16. <input type="button" id="boutonCSS" value="cliquer ici..." onClick="change(this)">
Ce que cela donne
Un peu de couleurs...

Exercices

  1. Changer la couleur de fond et la couleur de texte sur un cycle de trois en appuyant sur un bouton (Solution.)
  2. Construire une page dont certains objets changent de couleur de texte et de fond quand on passe dessus. (Solution.)
  3. Changer une image au survol. (Solution.)
  4. Écrire un nuancier hexadécimal (Solution.)

Timer en Javascript

  1. <script>
  2. function changeCouleur () {
  3.   if (document.body.style.backgroundColor=='orange') {
  4.     document.body.style.backgroundImage='none';
  5.     document.body.style.backgroundColor='yellow';
  6.   } else  {
  7.     document.body.style.backgroundImage='none';
  8.     document.body.style.backgroundColor='orange';
  9.   }
  10.   document.getElementById('off').value='Arrêter : '+document.body.style.backgroundColor;
  11. }
  12. </script>
  13. <input value="Démarrer" type="button" id="on"
  14.        onClick="monTimer=setInterval(changeCouleur,1000);">
  15. <input value="Arrêter" type="button" id="off"
  16.        onClick="clearInterval(monTimer);">
Ce que cela donne

Exercice

  1. La fonction suivante calcule l'heure à l'instant où elle est appelée :
    function mon_heure() {
    	var d = new Date();
    	var heure = d.getHours();
    	var minute = d.getMinutes();
    	var seconde = d.getSeconds();
    	var t = heure + ":" + minute + ":" + seconde;
    	document.leform.monheure.value = t;
        }
    Utilisez-la pour créer une zone qui indique l'heure en permanence à la seconde près. (Solution.)

Un exemple récapitulatif

demoJS-recap.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html>
  3.   <head lang="fr">
  4.     <meta charset="utf-8" />
  5.     <title>Calcul de factorielle</title>
  6.     <script>
  7.        function factorielle (n) {
  8.          if(n<0) {
  9.            alert("Valeur inférieure à 0 !");
  10.          } else {
  11.            if (n==0) {
  12.              return 1;
  13.            } else {
  14.             return n*factorielle(n-1);
  15.            }
  16.          }
  17.        }
  18.  
  19.        function affiche_factorielle() {
  20.          var k = parseInt(document.getElementById('valeur').value);
  21.          document.getElementById('resultat').innerHTML = factorielle(k);
  22.        }
  23.     </script>
  24.   </head>
  25.   <body>
  26.     <input type="button" value="Factorielle" onclick="affiche_factorielle();">
  27.     <input type="text" id="valeur"> = <span id="resultat"></span>
  28.   </body>
  29. </html>
  30.  

La balise canvas

La balise canvas (HTML5) représente une zone de dessin pouvant afficher des graphiques qu'on réalisera en utilisant JavaScript.

Un cours complet est disponible à https://www.alsacreations.com/tuto/lire/1484-introduction.html.

Premier essai : des traits

On commence par définir la zone du dessin, en précisant si on veut la largeur (width) et la hauteur (height).
On lui attribue un identifiant (id) pour que JavaScript puisse y accéder par la suite pour les dessins.

C'est getElementById() qui va permettre d'aller chercher et cibler l'élément canvas identifié par son attribut id unique (ici mon_canvas), puis la méthode getContext() de l'élément ainsi récupéré pour savoir dans quel contexte de dessin (2D ou 3D) le script va pouvoir agir (nous nous contenterons de 2D), et de quelles fonctions il pourra disposer. Le contexte sera l'élément central de gestion de canvas.

Dans ce premier exemple on explore les dessins simples : tracer des segments de droite...

Vous pourrez trouver des explications sur le système de coordonnées à https://www.alsacreations.com/tuto/lire/1484-introduction.html.

canvas01.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3.   <head>
  4.     <meta charset="utf-8">
  5.     <title>Canvas-01</title>
  6.   </head>
  7.   <body>
  8.     <h1>Canvas-01</h1>
  9.  
  10.     <canvas id="mon_canvas"
  11.             width="350"
  12.             height="350"
  13.             style="border:red thin solid;">
  14.       Votre navigateur ne supporte malheureusement pas la balise
  15.       &lt;canvas&gt;. Vous ne pouvez pas voir ce qui est prévu.
  16.     </canvas>
  17.  
  18.     <script>
  19.       var c = document.getElementById("mon_canvas");
  20.       var ctx = c.getContext("2d");
  21.      
  22.       ctx.beginPath();      // Début du chemin
  23.       ctx.moveTo(50,50);    // Le tracé part du point 50,50
  24.       ctx.lineTo(200,200);  // Un segment est ajouté vers 200,200
  25.       ctx.moveTo(200,50);   // Puis on saute jusque 200,50
  26.       ctx.lineTo(50,200);   // Puis on trace jusque 50,200
  27.       ctx.closePath();      // Fermeture du chemin (facultative)
  28.       ctx.stroke();
  29.     </script>
  30.  
  31.   </body>
  32. </html>
  33.  

Premiers exercices

  1. Dessiner un cadre à 50 pixels du bord. (Solution.)
  2. Idem, mais chaque tracé d'un trait est déclenché par un bouton. (Solution, ou mieux, avec une fonction.)
  3. Construire un télécran élémentaire.
    Remarques :
    • Pour trouver les symboles en forme de flèche, demandez « entités HTML » à votre moteur de recherche préféré.
    • Pour effacer le contenu du canvas, utilisez « ctx.clearRect(0,0,350,350) ».
    (Solution.)

Contours et remplissage

On agit sur les couleurs de contour et de remplissage avec fill() et stroke().

Les propriétés du dessin sont definies par fillStyle et strokeStyle (sans parenthèses, ce ne sont pas des fonctions mais des propriétés).

canvas05.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3.   <head>
  4.     <meta charset="utf-8">
  5.     <title>Canvas-05</title>
  6.   </head>
  7.   <body>
  8.     <h1>Canvas-05</h1>
  9.  
  10.     <canvas id="mon_canvas"
  11.             width="350"
  12.             height="350"
  13.             style="border:red thin solid;">
  14.       Votre navigateur ne supporte malheureusement pas la balise
  15.       &lt;canvas&gt;. Vous ne pouvez pas voir ce qui est prévu.
  16.     </canvas>
  17.  
  18.     <br/>
  19.    
  20.     <script>
  21.       var c = document.getElementById("mon_canvas");
  22.       var ctx = c.getContext("2d");
  23.    
  24.       ctx.lineJoin = "round";      //  Pour des jointures arrondies
  25.       ctx.lineCap = "round";       //  Pour des fins de ligne arrondies
  26.      
  27.       // Voile du bateau
  28.       ctx.beginPath();             //  Début du chemin
  29.       ctx.moveTo(150,80);          //  Le tracé part du point 150,80
  30.       ctx.lineTo(300,230);         //  Un segment est ajouté vers 300,230
  31.       ctx.lineTo(150,230);         //  Un segment est ajouté vers 150,230
  32.       ctx.closePath();             //  Fermeture du chemin
  33.       ctx.fillStyle = "lightblue"; //  Définition de la couleur de remplissage
  34.       ctx.fill();                  //  Remplissage du dernier chemin tracé
  35.      
  36.       // Coque du bâteau
  37.       ctx.beginPath();             //  Début pour un autre chemin
  38.       ctx.moveTo(50,250);
  39.       ctx.lineTo(100,300);
  40.       ctx.lineTo(250,300);
  41.       ctx.lineTo(300,250);
  42.       ctx.fillStyle = "peru";
  43.       ctx.strokeStyle = "sienna";  //  Définition de la couleur de contour
  44.       ctx.lineWidth = 5;           //  Définition de la largeur de ligne
  45.       ctx.fill();                  //  Application du remplissage
  46.       ctx.stroke();                //  Application du contour
  47.      
  48.       //  Mât
  49.       ctx.beginPath();
  50.       ctx.moveTo(140,50);
  51.       ctx.lineTo(140,250);
  52.       ctx.lineWidth = 10;
  53.       ctx.stroke();
  54.     </script>
  55.   </body>
  56. </html>
  57.  

La souris

Ce premier exemple vous permet de voir comment récupérer les coordonnées d'un clic.

Remarque : event est un objet qui contient les caractéristiques du dernier événement qui s'est produit (clic de souris, appui sur une touche, etc.).

canvas06.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3.   <head>
  4.     <meta charset="utf-8">
  5.     <title>Canvas-06</title>
  6.   </head>
  7.   <body>
  8.     <h1>Canvas-06</h1>
  9.  
  10.     <canvas id="mon_canvas"
  11.             width="350"
  12.             height="350"
  13.             style="border:red thin solid;"
  14.             onmousedown="clicSouris(event);" >
  15.       Votre navigateur ne supporte malheureusement pas la balise
  16.       &lt;canvas&gt;. Vous ne pouvez pas voir ce qui est prévu.
  17.     </canvas>
  18.  
  19.     <script>
  20.       function clicSouris(e) {
  21.         document.getElementById("resultats").innerHTML ="Clic en X="+e.clientX+" et en Y="+e.clientY;
  22.       }
  23.     </script>
  24.    
  25.     <div id="resultats"></div>  <!-- pour afficher les coordonnées du clic -->
  26.   </body>
  27. </html>
  28.  

Vous pouvez remarquer qu'il y a un décalage. En fait on obtient les coordonnées du clic par rapport à la page, et non pas dans le canvas. Il va falloir convertir le résultat en récupérant la position du canvas.

canvas07.html
[cacher les numéros de lignes]
  1. <!DOCTYPE html>
  2. <html lang="fr">
  3.   <head>
  4.     <meta charset="utf-8">
  5.     <title>Canvas-07</title>
  6.   </head>
  7.   <body>
  8.     <h1>Canvas-07</h1>
  9.  
  10.     <canvas id="mon_canvas"
  11.             width="350"
  12.             height="350"
  13.             style="border:red thin solid;"
  14.             onmousedown="clicSouris(this,event);" >
  15.       Votre navigateur ne supporte malheureusement pas la balise
  16.       &lt;canvas&gt;. Vous ne pouvez pas voir ce qui est prévu.
  17.     </canvas>
  18.  
  19.     <script>
  20.       function clicSouris(c,e) {
  21.         var c = document.getElementById("mon_canvas");
  22.         var ctx = c.getContext("2d");
  23.         // Position absolue du clic (par rapport à la page)
  24.         xAbs = e.clientX ;
  25.         yAbs = e.clientY ;
  26.         // Position du canvas
  27.         xCan = c.offsetLeft ;
  28.         yCan = c.offsetTop ;
  29.         // Position relative du clic (par rapport au canvas)
  30.         xRel = e.clientX-c.offsetLeft ;
  31.         yRel = e.clientY-c.offsetTop ;
  32.         // Affichage des coordonnées
  33.         document.getElementById("resultats").innerHTML =
  34.                          "Clic en X="+xAbs+" et en Y="+yAbs+".<br/>"
  35.                        + "Le canvas  est en X="+xCan+" et en Y="+yCan+".<br/>"
  36.                        + "Position relative du clic en X="+xRel+" et en Y="+yRel+".";
  37.         // Dessin au clic
  38.         ctx.arc(xRel, yRel, 2, 0, 2*Math.PI, false);
  39.         ctx.fill();
  40.         ctx.closePath();
  41.  
  42.       }
  43.     </script>
  44.    
  45.     <div id="resultats"></div>  <!-- pour afficher les coordonnées du clic -->
  46.   </body>
  47. </html>
  48.  

Exercices

  1. Dessiner à la souris dans le canvas. (Solution.)
  2. Space Invaders, première version.
    Les instructions suivantes permettent de construire l'image d'un alien (alien) positionné en (x,y) :
    1. ctx.fillRect(x,y+4,1,3);
    2.  
    3. ctx.fillRect(x+1,y+2,1,2);
    4.  
    5. ctx.fillRect(x+2,y,1,1);
    6. ctx.fillRect(x+2,y+2,1,5);
    7.  
    8. ctx.fillRect(x+3,y+1,1,2);
    9. ctx.fillRect(x+3,y+4,1,2);
    10. ctx.fillRect(x+3,y+7,1,1);
    11.  
    12. ctx.fillRect(x+4,y+2,1,4);
    13. ctx.fillRect(x+4,y+7,1,1);
    14.  
    15. ctx.fillRect(x+5,y+2,1,4);
    16.  
    17. ctx.fillRect(x+6,y+2,1,4);
    18. ctx.fillRect(x+6,y+7,1,1);
    19.  
    20. ctx.fillRect(x+7,y+1,1,2);
    21. ctx.fillRect(x+7,y+4,1,2);
    22. ctx.fillRect(x+7,y+7,1,1);
    23.  
    24. ctx.fillRect(x+8,y,1,1);
    25. ctx.fillRect(x+8,y+2,1,5);
    26.  
    27. ctx.fillRect(x+9,y+2,1,2);
    28.  
    29. ctx.fillRect(x+10,y+4,1,3);
    Utilisez-les pour produire un alien dans un canvas. (Solution.)
  3. Space Invaders, deuxième version.
    Transformez les instructions en une fonction dont les paramètres sont x et y, et utilisez-la pour dessiner plusieurs aliens. (Solution.)
  4. Space Invaders, troisième version.
    Transformez la fonction pour qu'elle puisse afficher des aliens à différentes échelles. (Solution.)
  5. Space Invaders, quatrième version.
    Utilisez un timer pour faire déplacer des aliens. (Solution.)
  6. Space Invaders, cinquième version.
    Améliorez le programme pour que les aliens n'aient pas tous la même couleur et pour qu'ils ne se déplacent pas tous dans le même sens. (Solution.)
Dernière modification : 25/4/2017
Dernière modification : 20/4/2017