Cours Développement Web 2

Post on 19-Jan-2016

104 views 2 download

Transcript of Cours Développement Web 2

. . . . . .

Développement Web 2

Bertrand Estellon

Aix-Marseille Université

April 26, 2013

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 1 / 423

. . . . . .

PHP Bases du langage Introduction

“Web Dynamique”

▶ Génération automatique des pages par le serveur :▶ Le contenu dépend du visiteur▶ Parfois, on trouve un système d’authentification (ex : ENT)▶ Langages : PHP (Hypertext Preprocessor), JSP etc.▶ Utilisation d’une base de données pour générer les pages

▶ Pages web dynamiques :▶ Exécution de scripts sur le client▶ Présentation et réorganisation dynamiques des données coté client▶ Langages : JavaScript, VBScript, etc.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 2 / 423

. . . . . .

PHP Bases du langage Introduction

“Web 2.0”

▶ Combinaison des deux aspects du Web dynamique▶ Les scripts exécutés sur le client échangent des informations avec un

serveur (AJAX, Flash, SilverLight)▶ Mise à jour dynamique d’une partie de la page Web▶ Permet de créer des Applications Web Riches (RIA) :

▶ Gmail, Google Maps, Flickr, Deezer, etc.▶ Permet d’organiser des réseaux sociaux :

▶ Facebook, Myspace, etc.▶ Permet de créer des Wiki, blogs et travaux collaboratifs :

▶ Wikipedia, etc.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 3 / 423

. . . . . .

PHP Bases du langage Introduction

Le Web “statique”

Protocole HTTP

Client Serveur1. Je veux toto.html

2. Contenu de toto.html

Requête :GET /toto.html HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>page d’exemple.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 4 / 423

. . . . . .

PHP Bases du langage Introduction

Le Web “dynamique”

Protocole HTTP

Client Serveur1. Je veux toto.html

2. Contenu de toto.html

Requête :GET /toto.html HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>page d’exemple.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 5 / 423

. . . . . .

PHP Bases du langage Introduction

Le Web “dynamique”

Protocole HTTP

Client Serveur1. Je veux toto.php

2. Sortie de l'exécution de toto.html

Requête :GET /toto.php?n1=10&n2=15 HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>Résultat : 25.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 6 / 423

. . . . . .

PHP Bases du langage Introduction

Le Web “dynamique”

Protocole HTTP

Client Serveur1. Je veux toto.php

2. Sortie de l'exécution de toto.html

Requête :POST /toto.php HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4n1=10&n2=15

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>Résultat : 25.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 7 / 423

. . . . . .

PHP Bases du langage Introduction

Pourquoi PHP ?

▶ Besoin d’un langage simple :▶ pour générer du HTML▶ pour communiquer avec une base de données▶ Langages : PHP (Hypertext Preprocessor), JSP etc.▶ pour gérer les sessions des utilisateurs

▶ Une solution :▶ 1994 : Invention de PHP par Rasmus Lerdorf▶ Il est interprété (PHP 3) ou compilé (PHP 4 et 5)▶ Il a une syntaxe proche du C (et de Perl)▶ Open-source et multi-plateforme

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 8 / 423

. . . . . .

PHP Bases du langage Introduction

Premier programme

▶ Un premier programme “index.php” :<html><head><title>Ma page PHP</title>

</head><body><?echo "Bonjour,";echo "On est le ".date('d/M/Y');

?></body></html>

▶ La balise <? permet d’entrer dans du code PHP▶ La balise ?> permet de sortir du code PHP

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 9 / 423

. . . . . .

PHP Bases du langage Introduction

Inclusion de fichiers

index.php :<html><head><title>Titre</title>

</head><body><?require("tete.inc.php");include("corps.html");require("pied.inc.php");?>

</body></html>

Mais aussi :include_once et require_once

tete.inc.php :<?echo "Bienvenue<br>";

?>

corps.html :Corps du site<br>

pied.inc.php :<?echo date('d/M/Y');

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 10 / 423

. . . . . .

PHP Bases du langage Introduction

Commentaires

<html><head><title>Titre</title>

</head><body><?echo "Bonjour"; // commentaireecho "Salut"; /* commentairesur plusieurs lignes. */

echo "Coucou"; # commentaire?><!-- commentaire -->

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 11 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Instructions, opérations et fonctions

<?print(3+6*strlen("toto"));

?>

print

+

3 *

6 strlen

"toto"

retourne 1

retourne 27

retourne 24

retourne 4

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 12 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Variables

▶ En C ou en Java, à une variable sont associés :▶ Un nom (ou identifiant);▶ Un type;▶ Une zone mémoire (désignée par une adresse).

int a;a = 2;

▶ En PHP, à une variable sont associés :▶ Un nom (ou identifiant) commençant par $;▶ Un conteneur d’une valeur.

<?$a = 2;?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 13 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Les types des valeurs

▶ Les variables ne sont pas typées mais les valeurs ont un type :▶ integer : 7, 14, 255, 0xFF▶ boolean : TRUE, FALSE▶ double : 1.95, 1.12e4▶ string : "bonjour", 'bonjour'▶ array : array(1,2,3)▶ object : new maclasse▶ ressource : mysql_connect("localhost", "moi", "")▶ null : null, NULL

<?$a = 2;var_dump($a); // affiche int(2)?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 14 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateur d’assignation

▶ En PHP, on ne déclare pas les variables▶ L’opérateur = affecte la valeur d’une expression à une variable :

<?$a = expression;?>

▶ L’opérateur = retourne la valeur de l’expression assignée à la variable

$a = $b = 2

1. affecte la valeur 2 à la variable $b

et retourne la valeur 2

2. affecte la valeur 2 à la variable $a

et retourne la valeur 2

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 15 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de valeur

<?$variable = 12;$variable2 = "toto";$variable2 = $variable;$variable = 12.12+3;

?>

$variable

12

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 16 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de valeur

<?$variable = 12;$variable2 = "toto";$variable2 = $variable;$variable = 12.12+3;

?>

$variable

12

$variable2

"toto"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 17 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de valeur

<?$variable = 12;$variable2 = "toto";$variable2 = $variable;$variable = 12.12+3;

?>

$variable

12

$variable2

12

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 18 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de valeur

<?$variable = 12;$variable2 = "toto";$variable2 = $variable;$variable = 12.12+3;

?>

$variable

15.12

$variable2

12

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 19 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateur d’assignation de référence

▶ Affectation de référence : l’opérande de droite est une variableprécédée du caractère '&' :$var2 = &$var1;

▶ Ici, l’opérateur = retourne la valeur présente dans le conteneur de lavariable $var1.

▶ Après l’affectation, la variable $var2 ne fait que référencer leconteneur associé à la variable $var1.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 20 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de référence

<?$variable = 12;$variable2 = &variable;$variable2 = "toto";$variable = 12.12;

?>

$variable

12

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 21 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de référence

<?$variable = 12;$variable2 = &variable;$variable2 = "toto";$variable = 12.12;

?>

$variable

12

$variable2

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 22 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de référence

<?$variable = 12;$variable2 = &variable;$variable2 = "toto";$variable = 12.12;

?>

$variable

"toto"

$variable2

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 23 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Affectations de référence

<?$variable = 12;$variable2 = &variable;$variable2 = "toto";$variable = 12.12;

?>

$variable

12.12

$variable2

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 24 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

État d’une variable

▶ La fonction isset($var) retourne :▶ FALSE si la variable n’est pas initialisée ou a la valeur NULL;▶ TRUE sinon.

▶ La fonction empty($var) retourne :▶ TRUE si une des conditions suivantes est vérifiée :

▶ la variable n’est pas initialisée▶ la variable a la valeur "" (chaîne vide)▶ la variable a la valeur 0 (entier)▶ la variable a la valeur 0.0 (flottant)▶ la variable a la valeur "0"▶ la variable a la valeur NULL▶ la variable a la valeur FALSE▶ la variable a la valeur array() (tableau vide)

▶ FALSE sinon.▶ La fonction unset($var) détruit une variable.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 25 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Type d’une variable

▶ Pour connaître le type de la valeur contenue dans le conteneur d’unevariable $var :

▶ gettype($var) retourne une chaîne de caractères contenant le typede la valeur (ex : "integer")

▶ is_integer($var) ou is_int($var), is_double($var),is_scalar($var), is_string($var), is_bool($var) ,is_array($var) , is_object($var), is_ressource($var),is_numeric($var)

<?$var = 12;if (is_integer($var)) {

echo "je suis un entier";}

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 26 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Conversion de type

▶ Opérateur de Cast :▶ $var2 = (nouveau_type)$var▶ ou même $var = (nouveau_type)$var

<?$var = "4.34 litre";$var = (double)$var;echo $var; // affiche 4.34$var = (integer)$var;echo $var; // affiche 4$var = (boolean)$var;echo $var; // affiche 1

?>▶ On peut aussi utiliser la fonction settype($var, "nouveau_type")

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 27 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Les constantes

▶ Pour définir une constante :define("MA_CONSTANTE", 12.76, TRUE);↪→ si le dernier paramètre vaut TRUE, le nom est insensible à la casse

▶ Pour savoir si une constante existe :defined("MA_CONSTANTE")↪→ retourne TRUE si la constante existe, FALSE sinon

▶ Utilisation d’une constante :<?

define("TOTO", 12.45, TRUE);echo TOTO, "<br/>";echo ToTo, "<br/>";if (defined("TOTO")) echo "ok";

?>Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 28 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateurs numériques

Négation -$a Opposé de $aAddition $a + $b Somme de $a et $bSoustraction $a - $b Différence de $a et $bMultiplication $a * $b Produit de $a et $bDivision $a / $b Quotient de $a et $bModulo $a % $b Reste de $a divisé par $b

Pre-incrémente ++$a Incrémente $a de 1, puis retourne $aPost-incrémente $a++ Retourne $a, puis incrémente $a de 1Pré-décrémente --$a Décrémente $a de 1, puis retourne $aPost-décrémente $a-- Retourne $a, puis décrémente $a de 1

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 29 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateurs logiques

et $a and $b TRUE si $a et $b valent TRUEou $a or $b TRUE si $a ou $b valent TRUEou exclusif $a xor $b TRUE si $a ou $b est égal TRUE

mais pas les deux en même tempsnon !$a TRUE si $a n’est pas égal à TRUEet $a && $b TRUE si $a et $b sont égaux TRUEou $a || $b TRUE si $a ou $b est égal TRUE

▶ Attention à la précédence des opérateurs :<?$e = false || true; // (e = (false || true))$e = false or true; // ((e = false) or true)$e = false && true; // (e = (false && true))$e = false and true; // ((e = false) and true)

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 30 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateurs de comparaison

égal $a == $b TRUE si $a est égal à $b

identique $a === $b TRUE si $a et $b sont égauxet ont le même type

différent $a != $b TRUE si $a est différent de $bdifférent a <> b+ TRUE si $a est différent de $b

non identique $a !== $b TRUE si $a et $b sont différentsou n’ont pas le même type

plus petit $a < $b TRUE si $a est strictement plus petit que $bplus grand $a > $b TRUE si $a est strictement plus grand que $binférieur ou égal $a <= $b TRUE si $a est plus petit ou égal à $bsupérieur ou égal $a >= $b TRUE si $a est plus grand ou égal à $b

<?var_dump(0 == "a"); // bool(true)var_dump(0 === "a"); // bool(false)

?>Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 31 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateurs de chaînes

▶ L’opérateur . permet de concaténer deux chaînes de caractères(comme le + en Java) :<?var_dump("Bonj"."our");// string(7) "Bonjour"var_dump(1 . 2); // string(2) "12"var_dump(1.2); // float(1.2)$a = "Bonj";$a = $a . "our";var_dump($a); // string(7) "Bonjour"$a = "Bonj";$a .= "our";var_dump($a); // string(7) "Bonjour"?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 32 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateurs de commande

▶ L’opérateur ` (guillements obliques) permet d’exécuter descommandes shell :<?$output = `ls -al`;echo "<pre>$output</pre>";

?>▶ Remarque : cet opérateur n’est pas actif lorsque le “safemode” est

activé ou lorsque la fonction shell_exec() est désactivée.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 33 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Opérateurs d’affectation combinée

addition $a += $b additionne $a et $b puis affecte le résultat à $asoustraction $a -= $b soustrait $a et $b puis affecte le résultat à $amultiplication $a *= $b multiplie $a et $b puis affecte le résultat à $adivision $a /= $b divise $a et $b puis affecte le résultat à $amodulo $a %= $b divise $a et $b puis affecte le reste à $aconcaténation $a .= $b concatène $a et $b puis affecte le résultat à $a

<?$a = 13;$a += 12;echo $a; // affiche 25

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 34 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Block d’instructions

▶ Comme en C ou en Java, on définit un block d’instructions à l’aidedes accolades ouvrantes et fermantes { } :<?

if ($a == 2) {echo "instruction 1";echo "instruction 2";

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 35 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

if, boucles while et do...while

▶ On utilise le if, du while et le do...while de la même façon qu’en Cou qu’en Java :<?$a = 1;if ($a == 2) echo "oui"; else echo "non";while ($a < 4) {echo $a;$a++;

}do {echo $a;$a--;

} while ($a>0);?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 36 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

boucle for

▶ La syntaxe du for est la même qu’en C ou qu’en Java :for (expression; expression; expression) instruction;

<?for ($a=0; $a<10; $a++) {

echo $a.":";for ($b=0; $b<10; $b+=2)echo ($a+$b)." ";echo "<br/>";

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 37 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

break et continue

▶ la commande break arrête l’exécution de la boucle :<?for ($i = 0; $i < 5; $i++) {if ($tab[$i]=="bonjour") break;echo $tab[$i];}?>

TrucTotoBonjourBipSalut

▶ la commande continue arrête l’itération en cours de la boucle :<?for ($i = 0; $i < 5; $i++) {if ($tab[$i]=="bonjour") continue;echo $tab[$i];}?>

TrucTotoBonjourBipSalut

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 38 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

switch

<?switch ($a) {case 0 :echo '0';break;

case 1 :echo '1';break;

default :echo 'default';}?>

<?switch ($a) {case "a" :echo 'a';break;

case "b" :echo 'b';break;

default :echo 'default';}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 39 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Fonctions

<?function ajouter(&$a /* 1 */ , $b=5 /* 2 */) {$a+=$b;

}

$n = 12;ajouter($n, 2);var_dump($n); // affiche int(14)ajouter($n);var_dump($n); // affiche int(19)

?>

...1 Passage d’un paramètre par référence.

...2 La valeur par défaut du paramètre est 5.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 40 / 423

. . . . . .

PHP Bases du langage Instructions, opérations, variables

Portée des variables

<?function modif() {$var = "salut";

}

$var = "toto";var_dump($var); // 1modif();var_dump($var); // 2?>

<?function modif() {global $var;$var = "salut";

}

$var = "toto";var_dump($var); // 3modif();var_dump($var); // 4

?>

...1 string(4) "toto"

...2 string(4) "toto"

...3 string(4) "toto"

...4 string(5) "salut"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 41 / 423

. . . . . .

PHP Bases du langage Chaînes de caractères

Affichage des chaînes

<?$a = "bonjour";$b = "salut";$c = 2;

echo "$a $b\n"; // 1echo '$a $b\n'; // 2echo "\n";echo "$a $b{$c}\n"; // 3echo date('d')."\n"; // 4echo "date('d')\n"; // 5?>

...1 bonjour salut

...2 $a $b\n

...3 bonjour l

...4 18

...5 date('d')

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 42 / 423

. . . . . .

PHP Bases du langage Chaînes de caractères

Les caractères

<?$chaine="ABCDEF";for ($i = 0; $i<strlen($chaine); $i++) {

echo ord($chaine{$i})."\n"; // 1}

$chaine="";for ($i = 0; $i<6; $i++) {$c = rand(65,90);$chaine.=chr($c);}echo "$chaine\n"; // 2

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 43 / 423

...1

656667686970

...2 GZXNIY

. . . . . .

PHP Bases du langage Chaînes de caractères

Affichage formaté<?$chaine = "Bonjour";$nombre = "65";$valeur = "65535";$flotant = "12.2345";printf("%s\n", $chaine); // 1printf("%c %d\n", $nombre, $nombre); // 2printf("%x %o\n", $valeur, $valeur); // 3printf("%'#8.3f\n", $flotant); // 4$a = sprintf("%'#8.3f", $flotant);var_dump($a); // 5$a = array("65", "66","67");vprintf("%c %c %c\n", $a); // 6$b = vsprintf("%c %c %c", $a);var_dump($b); // 7?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 44 / 423

...1 Bonjour

...2 A 65

...3 ffff 177777

...4 ##12.235

...5 string(8)”##12.235”

...6 A B C

...7 string(5) ”A B C”

. . . . . .

PHP Bases du langage Chaînes de caractères

Modification de la casse

<?$chaine = "PHP est super bien !\n";echo strtolower($chaine); /* 1 */echo strtoupper($chaine); /* 2 */echo ucwords($chaine); /* 3 */echo ucfirst($chaine); /* 4 */?>

...1 php est super bien !

...2 PHP EST SUPER BIEN !

...3 PHP Est Super Bien !

...4 PHP est super bien !

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 45 / 423

. . . . . .

PHP Bases du langage Chaînes de caractères

Gestion des espaces

<?$a=" ...Salut././.";echo "[".ltrim($a)."]\n"; /* 1 */echo "[".ltrim($a," .")."]\n"; /* 2 */echo "[".rtrim($a,"./")."]\n"; /* 3 */echo "[".trim($a," ./")."]\n"; /* 4 */?>

...1 [...Salut././.]

...2 [Salut././.]

...3 [ ...Salut]

...4 [Salut]

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 46 / 423

. . . . . .

PHP Bases du langage Chaînes de caractères

Caractères spéciaux dans les URL et en XHTML

<?$a="<b>d£é£truire</b>";$b=htmlentities($a);echo $b."\n"; /* 1 */$c=html_entity_decode($b);echo $c."\n"; /* 2 */$b=strip_tags($a);echo $b."\n"; /* 3 */$b=urlencode($a);echo $b."\n"; /* 4 */$c=urldecode($b);echo $c."\n"; /* 5 */

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 47 / 423

...1 &lt;b&gt;d&eacute;truire&lt;b&gt;

...2 <b>détruire</b>

...3 détruire

...4 %3Cb%3Ed%E9truire%3C%2Fb%3E

...5 <b>détruire</b>

. . . . . .

PHP Bases du langage Chaînes de caractères

Recherche de sous-chaînes

<?$ch = "bonjour salut bonjour";$nb = substr_count($ch, "bonjour");var_dump($nb); /* 1 */$ch2 = str_replace("bonjour", "salut", $ch);var_dump($ch2); /* 2 */$pos = strpos($ch,"salut");var_dump($pos); /* 3 */$pos = strpos($ch,"Salut");var_dump($pos); /* 4 */$pos = stripos($ch,"Salut");var_dump($pos); /* 5 */$ch3 = substr($ch,8,5);var_dump($ch3); /* 6 */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 48 / 423

...1 int(2)

...2 string(17) "salut salut salut"

...3 int(8)

...4 bool(false)

...5 int(8)

...6 string(5) "salut"

. . . . . .

PHP Bases du langage Chaînes de caractères

Comparaison de chaînes de caractères

<?$ch1=11;$ch2="11toto";var_dump($ch1); /* 1 */var_dump($ch2); /* 2 */var_dump($ch1==$ch2); /* 3 */var_dump($ch1===$ch2); /* 4 */var_dump("$ch1"==$ch2); /* 5 */var_dump($ch1*$ch2); /* 6 */var_dump("$ch1"*$ch2); /* 7 */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 49 / 423

...1 int(11)

...2 string(6) "11toto"

...3 bool(true)

...4 bool(false)

...5 bool(false)

...6 int(121)

...7 int(121)

. . . . . .

PHP Bases du langage Chaînes de caractères

Comparaison de chaînes de caractères

<?var_dump(strcmp("toto2","toto2"));var_dump(strcmp("toto12","toto2"));var_dump(strcmp("toto2","toto12"));var_dump(strcasecmp("toto","ToTo"));var_dump(strnatcmp("toto12","toto2"));?><?$ch1 = "abc";$ch2 = "bcd";if ($ch1 < $ch2) echo "<"; else echo ">";?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 50 / 423

→ int(0) ...1→ int(-1) ...2→ int(1) ...3→ int(0) ...4→ int(1) ...5

. . . . . .

PHP Bases du langage Tableaux

Tableaux

▶ On peut indicer les tableaux avec des entiers ou des chaînes decaractères;

▶ La fonction count($tab) retourne le nombre d’éléments présentsdans le tableau.

<?$a[2] = 12;$a[4] = 23;$a["toto"] = 12.13;var_dump($a); /* 1 */$b = count($a);var_dump($b); /* 2 */?>

...1

array(3) {[2] => int(12)[4] => int(23)[”toto”] => float(12.13)[clé] => valeur

}

...2 int(3)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 51 / 423

. . . . . .

PHP Bases du langage Tableaux

Tableaux

▶ Le mot clé array : Il prend un nombre variable de paramètres sous laforme ”clé => valeur” (ou simplement ”valeur”) :<?$a = array(12=>3, "a"=>12.12, 15, "c", "1"=>2);var_dump($a); /* 1 */$a = array(1,2,3,4);var_dump($a); /* 2 */?>

...1

array(5) {[12] => int(3)[”a”] => float(12.12)[13] => int(15)[14] => string(1) ”c”[1] => int(2)

}

...2

array(4) {[0] => int(1)[1] => int(2)[2] => int(3)[3] => int(4)

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 52 / 423

. . . . . .

PHP Bases du langage Tableaux

Intervalles

<?$a=range(1,4);var_dump($a); /* 1 */$a=range(0,30,10);var_dump($a); /* 2 */$a=range('d','g');var_dump($a); /* 3 */?>

...1

array(4) {[0] => int(1)[1] => int(2)[2] => int(3)[3] => int(4)

}

...2

array(4) {[0] => int(0)[1] => int(10)[2] => int(20)[3] => int(30)

}

...3

array(4) {[0] => string(1) ”d”[1] => string(1) ”e”[2] => string(1) ”f”[3] => string(1) ”g”

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 53 / 423

. . . . . .

PHP Bases du langage Tableaux

Ré-indexation

<?$a = array(1,"a"=>2);$a[] = 3;var_dump($a); /* 1 */unset($a[1]);$a[] = 4;var_dump($a); /* 2 */$a = array_values($a);var_dump($a); /* 3 */?>

...1

array(3) {

[0] => int(1)[”a”] => int(2)[1] => int(3)

}

...2

array(3) {

[0] => int(1)[”a”] => int(2)[2] => int(4)

}

...3

array(3) {

[0] => int(1)[1] => int(2)[2] => int(4)

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 54 / 423

. . . . . .

PHP Bases du langage Tableaux

Tableaux multidimensionnels

<?$a = array(12=>array(1,15=>2), 15=>2);var_dump($a); /* 1 */var_dump($a[12][15]); /* 2 */$a[12][20] = 2;var_dump($a[12]); /* 3 */

?>

...1

array(2) {[12]=> array(3) {

[0]=> int(1)[15]=> int(2)

}[15]=> int(2)

}

...3

array(4) {

[0] => int(1)[15] => int(2)[20] => int(2)

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 55 / 423

...2 int(2)

. . . . . .

PHP Bases du langage Tableaux

foreach

▶ La boucle foreach parcourt tous les couples ”clé ⇒ valeur” contenusdans un tableau :<?$a = array(1=>12, "a"=>12.12, "c"=>3, 4);foreach ($a as $k=>$v)

echo $k."=>".$v."\n"; /* 1 */foreach ($a as $v)

echo $v."\n"; /* 2 */?>

...1

1=>12a=>12.12c=>32=>4

...2

1212.1234

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 56 / 423

. . . . . .

PHP Bases du langage Tableaux

reset et each

<?$a = array(1=>12, "a"=>12.12, "c"=>3, 4);reset($a);while ($tab=each($a))

echo $tab[0]."=>".$tab[1]."\n"; /* 1 */reset($a);while ($tab=each($a))

echo $tab["key"]."=>".$tab["value"]."\n"; /* 1 */?>

...1

1=>12a=>12.12c=>32=>4

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 57 / 423

. . . . . .

PHP Bases du langage Tableaux

list

▶ la fonction list affecte plusieurs variables simultanément :<?$a = array("a", 12, "c");list($x,$y,$z)=$a;var_dump($x); /* 1 */var_dump($y); /* 2 */var_dump($z); /* 3 */list($i,,$j)=$a;var_dump($i); /* 4 */var_dump($j); /* 5 */list($i,$j)=$a;var_dump($i); /* 6 */var_dump($j); /* 7 */

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 58 / 423

...1 string(1) ”a”

...2 int(12)

...3 string(1) ”c”

...4 string(1) ”a”

...5 string(1) ”c”

...6 string(1) ”a”

...7 int(12)

. . . . . .

PHP Bases du langage Tableaux

list et each

<?$a = array(1=>12, "a"=>12.12, "c"=>3, 4);reset($a);while (list($k,$v)=each($a))

echo $k."=>".$v."\n"; /* 1 */?>

...1

1=>12a=>12.12c=>32=>4

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 59 / 423

. . . . . .

PHP Bases du langage Tableaux

Manipulation d’un tableau▶ array_push($tab, $var, $var2, …) :

empile des valeurs à la fin du tableau▶ $var = array_pop($tab) :

dépile une valeur située à la fin du tableau▶ array_unshift($tab, $var, $var2, …) :

ajoute des valeurs au début du tableau▶ $var = array_shift($tab) :

supprime et retourne la première valeur du tableau

array_unshift

array_shift

array_push

array_pop

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 60 / 423

. . . . . .

PHP Bases du langage Tableaux

Manipulation d’un tableau

<?$a=array(1, "a"=>2, 3);array_push($a, 12.12);array_unshift($a, "toto");var_dump($a); /* 1 */$b = array_pop($a);var_dump($b); /* 2 */$c = array_shift($a);var_dump($c); /* 3 */?>

...1

array(5) {[0] => string(4) ”toto”[1] => int(1)[”a”] => int(2)[2] => int(3)[3] => float(12.12)

}

...2 float(12.12)

...3 string(4) ”toto”

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 61 / 423

. . . . . .

PHP Bases du langage Tableaux

Fusion de tableaux

<?$a=array(1,"a"=>2, 3, "b"=>4, 4=>5);$b=array("c"=>6, 1=>7, 8, "b"=>9);$c=array_merge($a,$b);print_r($c); /* 1 */$c=array_merge_recursive($a,$b);print_r($c); /* 2 */?>

...1

Array ([0] => 1[a] => 2[1] => 3[b] => 9[2] => 5[c] => 6[3] => 7[4] => 8

)

...2

Array ([0] => 1[a] => 2[1] => 3[b] => Array ( [0] => 4 [1] => 9 )[2] => 5[c] => 6[3] => 7[4] => 8

)Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 62 / 423

. . . . . .

PHP Bases du langage Tableaux

Intersection et différence de tableaux

<?$a=array(1,"a"=>2, 3=>3, "b"=>4, 4=>5);$b=array("c"=>1, 1=>3, 4);$c=array_intersect($a,$b);print_r($c); /* 1 */$c=array_diff($a,$b);print_r($c); /* 2 */

?>

...1

Array ([0] => 1[3] => 3[b] => 4

)

...2

Array ([a] => 2[4] => 5

)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 63 / 423

. . . . . .

PHP Bases du langage Tableaux

Tri de tableaux indicés<?$a=array("a10", "b11", "b"=>"a9", "C12", "c12");sort($a);print_r($c); /* 1 */rsort($a);print_r($c); /* 2 */natsort($a);print_r($c); /* 3 */natcasesort($a);print_r($c); /* 4 */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 64 / 423

...1

Array ([0] => C12[1] => a10[2] => a9[3] => b11[4] => c12

)

...2

Array ([0] => c12[1] => b11[2] => a9[3] => a10[4] => C12

)

...1

Array ([4] => C12[2] => a9[3] => a10[1] => b11[0] => c12

)

...2

Array ([2] => a9[3] => a10[1] => b11[0] => c12[4] => C12

)

. . . . . .

PHP Bases du langage Tableaux

Tri personalisé

<?function comparaison($a, $b) {

return ($a[0]+$a[1]) - ($b[0]+$b[1]);}

$c = array(array(1,5),array(2,2), array(1,4));usort($c, "comparaison");print_r($c); /* 1 */

?>

...1

Array ([0] => Array ([0] => 2 [1] => 2)[1] => Array ([0] => 1 [1] => 4)[2] => Array ([0] => 1 [1] => 5)

)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 65 / 423

. . . . . .

PHP Bases du langage Tableaux

Tri de tableaux associatifs<?$a = array("a"=>"c", "b"=>"a", "c"=>"d");asort($a);print_r($a); /* 1 */arsort($a);print_r($a); /* 2 */sort($a);print_r($a); /* 3 */

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 66 / 423

...1

Array ([b] => a[a] => c[c] => d

)

...2

Array ([c] => d[a] => c[b] => a

)

...3

Array ([0] => a[1] => c[2] => d

)

. . . . . .

PHP Bases du langage Tableaux

Tri de tableaux associatifs

<?$a = array("a"=>"c", "b"=>"a", "c"=>"d");ksort($a);print_r($a); /* 1 */krsort($a);print_r($a); /* 2 */

?>

...1

Array ([a] => c[b] => a[c] => d

)

...2

Array ([c] => d[b] => a[a] => c

)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 67 / 423

. . . . . .

PHP Bases du langage Tableaux

Tri de tableaux associatifs

<?function compar1($a,$b) {return ($a[0]+$a[1])-($b[0]+$b[1]);}

function compar2($a,$b) {return strlen($a) - strlen($b);}

$a = array("aa"=>array(0,1),"aaa"=>array(2,2),"a"=>array(1,2));

uasort($a,"compar1");print_r($a); /* 1 */uksort($a,"compar2");print_r($a); /* 2 */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 68 / 423

...1

Array ([aa] => Array([0] => 0 [1] => 1)[a] => Array([0] => 1 [1] => 2)[aaa] => Array([0] => 2 [1] => 2)

)

...2

Array ([a] => Array([0] => 1 [1] => 2)[aa] => Array([0] => 0 [1] => 1)[aaa] => Array([0] => 2 [1] => 2)

)

. . . . . .

PHP Bases du langage Tableaux

Tri de tableaux associatifs<?function filtre($a) {return ($a[0] <= $a[1]);}

$a = array("a"=>array(0,1),"b"=>array(3,2),"c"=>array(1,2),"d"=>array(1,0));

$selection = array_filter($a, "filtre");print_r($selection); /* 1 */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 69 / 423

...1

Array ([a] => Array([0] => 0 [1] => 1)[c] => Array([0] => 1 [1] => 2)

)

. . . . . .

PHP Bases du langage Tableaux

Appliquer une fonction à un tableau

<?function affichage($a) {echo "<b>".$a[0]."</b> : ".$a[1]."<br/>\n"; /* 1 */}

$a = array(array(0,1),array(3,2),array(1,2),array(1,0));

array_walk($a, "affichage");?>

...1

<b>0</b> : 1<br/><b>3</b> : 2<br/><b>1</b> : 2<br/><b>1</b> : 0<br/>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 70 / 423

. . . . . .

PHP Bases du langage Tableaux

Chaînes et tableaux

<?$ch = "J'aime le PHP. Vive le web!";$tab = explode(' ',$ch);print_r($tab); /* 1 */$tab = explode('.',$ch);print_r($tab); /* 2 */$tab = array("J'aime", "le", "PHP.");$ch = implode(" ",$tab);echo $ch."\n"; /* 3 */$ch = implode("--",$tab);echo $ch."\n"; /* 4 */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 71 / 423

...1

Array ([0] => J’aime[1] => le[2] => PHP.[3] => Vive[4] => le[5] => web!

)

...2

Array ([0] => J’aime le PHP[1] => Vive le web!

)...3 J’aime le PHP. ...4 J’aime- -le- -PHP.

. . . . . .

PHP Bases du langage Tableaux

Autres fonctions utiles sur les tableaux

▶ La fonction array_unique($tab) supprime les valeurs en doubledans le tableau (une seule clé est conservée).

▶ La fonction $slice = array_slice($t, $p, $n) extrait les $néléments du tableau $t à partir de la position $p.(voir la documentation pour les autres utilisations)

▶ La fonction shuffle($a) mélange les éléments d’un tableau etrenumérote les éléments.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 72 / 423

. . . . . .

PHP Formulaires Introduction

GET

Protocole HTTP

Client Serveur1. Je veux toto.php

2. Sortie de l'exécution de toto.html

Requête :GET /toto.php?n1=10&n2=15 HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>Résultat : 25.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 73 / 423

. . . . . .

PHP Formulaires Introduction

POST

Protocole HTTP

Client Serveur1. Je veux toto.php

2. Sortie de l'exécution de toto.html

Requête :POST /toto.php HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4?n1=10&n2=15

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>Résultat : 25.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 74 / 423

. . . . . .

PHP Formulaires Introduction

Les formulaires en HTML

<input type="reset"... />

<input type="file"... />

<input type="checkbox".../>

<label>...</label>

<input type="radio".../>

<input type="text".../>

<textarea>...</textarea>

<input type="submit"... />

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 75 / 423

. . . . . .

PHP Formulaires Introduction

Les formulaires en HTML<html><body><form action="page.php" method="post"><fieldset>

<legend>Qui etes-vous ?</legend><label>Nom :</label><input type="text" name="nom" value="votre nom"/><label>Prenom :</label><input type="text" name="prenom" value="votre prenom"/><input type="radio" name="sexe" value="homme"/>Homme<input type="radio" name="sexe" value="femme"/>Femme<label>Photo :</label><input type="file" name="photo" accept="image/jpeg" />

</fieldset><fieldset><legend>Votre commentaire</legend><textarea name="commentaire">votre commentaire</textarea>

</fieldset><center><input type="checkbox" name="valid" value="valid"/>J accepte...<input type="reset" value="Effacer"><input type="submit" value="Envoyer">

</center></form></body>

</html>

▶ Envoi des données au serveur par la méthode POST sur la pagepage.php lorsque l’utilisateur clique sur le bouton Envoyer.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 76 / 423

. . . . . .

PHP Formulaires Variables $_POST et $_GET

Variables “super-globales”

▶ Les variables super-globales sont accessibles dans tous les contextes

Fichier test.php :<?function toto() {

echo $_SERVER["PHP_SELF"]."\n"; /* 1 */}

toto();

echo $_SERVER["PHP_SELF"]."\n"; /* 1 */?>

...1 ”test.php”

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 77 / 423

. . . . . .

PHP Formulaires Variables $_POST et $_GET

Variable $_POST

▶ Fichier index.html<html><body><form method="post" action="traitement.php"><label>Nom : </label><input type="text" name="nom"/><input type="submit" value="Envoyer"/>

</form></body></html>

▶ Fichier traitement.php<html><body>Bonjour <? echo $_POST['nom']; ?>.</br></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 78 / 423

Requête :

Réponse :

POST traitement.php...nom=Superman

...Bonjour Superman....

. . . . . .

PHP Formulaires Variables $_POST et $_GET

Variable $_POST

GET index.php

contenu de index.php

POST traitement.php ...nom=Superman

Bonjour Superman

Client Serveur

Saisie du nomClic sur "Envoyer"

Génération de la page par PHP

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 79 / 423

. . . . . .

PHP Formulaires Variables $_POST et $_GET

Variable $_GET

▶ Fichier index.html<html><body><form method="get" action="traitement.php"><label>Nom : </label><input type="text" name="nom"/><input type="submit" value="Envoyer"/></form></body></html>

▶ Fichier traitement.php<html><body>Bonjour <? echo $_GET['nom']; ?>.</br></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 80 / 423

Requête :

Réponse :

GET traitement.php?nom=superman...

...Bonjour Superman....

. . . . . .

PHP Formulaires Variables $_POST et $_GET

Variable $_GET

GET index.php

contenu de index.php

GET traitement.php?nom=Superman ...

Bonjour Superman

Client Serveur

Saisie du nomClic sur "Envoyer"

Génération de la page par PHP

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 81 / 423

. . . . . .

PHP Formulaires Applications

Bouton radio▶ Fichier index.html :

<html><body><form method="post" action="traitement.php"><input type="radio" name="sexe" value="homme">Homme</br><input type="radio" name="sexe" value="femme">Femme</br><input type="submit" value="Envoyer"/></form></body></html>

▶ Fichier traitement.php :<html><body><? if ($_POST['sexe']==='homme') { ?>Bonjour, vous etes un homme.

<?} else {?>Bonjour, vous etes une femme.

<? } ?></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 82 / 423

. . . . . .

PHP Formulaires Applications

Avec un seul fichier

<html><body><? if (isset($_POST['nom'])) {?>

Bonjour <? echo $_POST['nom']; ?><?} else {?><form method="post" action="<? echo $_SERVER["PHP_SELF"]; ?>" ><label>Nom : </label><input type="text" name="nom"/><input type="submit" value="Envoyer"/></form><?}?></body></html>

Bonjour Superman

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 83 / 423

. . . . . .

PHP Formulaires Applications

Valeurs multiples et checkboxes▶ Fichier index.html :

<html><body><form method="post" action="traitement.php"><input type="checkbox" name="choix[]" value="A">A</br><input type="checkbox" name="choix[]" value="B">B</br><input type="checkbox" name="choix[]" value="C">C</br><input type="submit" value="Envoyer"/></form></body></html>

▶ Fichier traitement.php :<html><body>Vous avez coche :<? foreach ($_POST['choix'] as $v)

echo "$v "; ?><br/></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 84 / 423

Vous avez coché : A C

. . . . . .

PHP Formulaires Applications

Maintient de l’état du formulaire<html><body><form method="post" action="<? echo $_SERVER["PHP_SELF"]; ?>"><input type="text" name="a" /><input type="text" name="b" /><input type="submit" value="Envoyer"/></form><? if (isset($_POST['a']) && isset($_POST['b'])) {?>

Resultat : <? echo $_POST['a']+$_POST['b']; ?><?}?></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 85 / 423

. . . . . .

PHP Formulaires Applications

Maintient de l’état du formulaire<html><body><form method="post" action="<? echo $_SERVER["PHP_SELF"]; ?>"><input type="text" name="a" value="<? echo $_POST['a'];?>" /><input type="text" name="b" value="<? echo $_POST['b'];?>" /><input type="submit" value="Envoyer"/></form><? if (isset($_POST['a']) && isset($_POST['b'])) {?>

Resultat : <? echo $_POST['a']+$_POST['b']; ?><?}?></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 86 / 423

. . . . . .

PHP Formulaires Transfert de fichiers

Transfert de fichiers<html><body><form enctype="multipart/form-data" method="post"

action="<? echo $_SERVER["PHP_SELF"]; ?>"><input type="file" name="fichier" /><input type="submit" value="Envoyer" /></form>

<? var_dump($_FILES); /* 1 */ ?></body></html>

...1

array(1) {[”fichier”]=> array(5) {

[”name”]]=> string(3) ”a.c”[”type”]=> string(10) ”text/plain”[”tmp_name”]=> string(14) ”/tmp/phpi5JOt8”[”error”]=> int(0)[”size”]=> int(185)

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 87 / 423

. . . . . .

PHP Formulaires Transfert de fichiers

Transfert de fichiers

<html><body><form enctype="multipart/form-data" method="post"

action="<? echo $_SERVER["PHP_SELF"]; ?>"><input type="file" name="fichier" /><input type="submit" value="Envoyer" /></form>

<? if (isset($_FILES['fichier'])) {$tmpname = $_FILES['fichier']['tmp_name'];$newname = "fichier_".$_FILES['fichier']['name'];echo $tmpname." ".$newname."<br/>";$result = move_uploaded_file($tmpname, $newname);if ($result==TRUE) echo "transfert ok !<br/>";else echo "erreur : ".$_FILES['fichier']['error'];

}?></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 88 / 423

. . . . . .

PHP Formulaires Transfert de fichiers

Transfert de fichiers

Les erreurs possibles :▶ UPLOAD_ERR_OK (valeur 0) :

↪→ pas d’erreur▶ UPLOAD_ERR_INI_SIZE (valeur 1) :

↪→ la taille du fichier dépasse la valeur présente dans le fichier php.ini.▶ UPLOAD_ERR_FORM_SIZE (valeur 2) :

↪→ la taille du fichier dépasse celle fixée dans le formulaire(champ caché MAX_FILE_SIZE).

▶ UPLOAD_ERR_PARTIAL (valeur 3) :↪→ le fichier a été partiellement téléchargé.

▶ UPLOAD_ERR_NO_FILE (valeur 4) :↪→ aucun fichier n’a été téléchargé.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 89 / 423

. . . . . .

PHP Fichiers Ouverture

Ouverture d’un fichier

<?$id = fopen("toto.txt", "w");var_dump($id); /* 1 */fclose($id);var_dump($id); /* 2 */

$id = tmpfile();var_dump($id); /* 3 */fclose($id);var_dump($id); /* 4 */

?>

▶ Une bonne façon de faire :<?$id = fopen("toto.txt", "w");if ($id===FALSE) die("Erreur");$r = fclose($id);if ($r===FALSE) die("Erreur");

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 90 / 423

...1 resource(5) of type (stream)

...2 resource(5) of type (Unknown)

...3 resource(6) of type (stream)

...4 resource(6) of type (Unknown)

. . . . . .

PHP Fichiers Ouverture

Ouverture d’un fichier

r : ouverture en lecture seule et la lecture commence au début du fichier.Le fichier doit exister.

r+ : le fichier est ouvert en lecture et écriture, les opérations commencentau début. Le fichier doit exister.

w : le fichier est ouvert en écriture et l’écriture commence au début dufichier. Le fichier est créé s’il n’existe pas.

w+ : le fichier est ouvert en écriture et en lecture et les opérationscommencent au début du fichier. Le fichier est créé s’il n’existe pas.

a : le fichier est ouvert en écriture et l’écriture commence à la fin dufichier. Le fichier est créé s’il n’existe pas.

a+ : le fichier est ouvert en écriture et lecture. L’écriture commence à lafin et la lecture au début. Le fichier est créé s’il n’existe pas.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 91 / 423

. . . . . .

PHP Fichiers Verrouillage

Verrouillage de fichiers

▶ Problème de concurrence :Plusieurs clients demandent une page simultanément

⇒ deux scripts modifient un fichier en même temps⇒ Conflit

▶ Solution : verrouillage du fichier<?$id = fopen("toto.txt", "w");echo $id."\n";flock($id, LOCK_EX); // Verrouillage en lecture et en écriture....flock($id, LOCK_UN); // Déverrouillagefclose($id);?>

▶ LOCK_SH : Verrouillage en écriture seulement

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 92 / 423

. . . . . .

PHP Fichiers Écriture

Écriture dans un fichier

<?$id = fopen("toto.txt", "w");flock($id, LOCK_SH);fwrite($id, "mon texte\n"); // Écriture de "mon texte$\backslash${}n"$nb = 100;fwrite($id, $nb); // Écriture de "100"flock($id, LOCK_UN);fclose($id);?>

▶ Contenu du fichier toto.txt à la fin de l’exécution :

mon texte100

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 93 / 423

. . . . . .

PHP Fichiers Écriture

Exemple d’écriture dans un fichier<html><body><form action="<? echo $_SERVER['PHP_MYSELF']; ?>" method="post"><b>Nom :</b> <input type="text" name="nom"/><br/><b>Prenom :</b> <input type="text" name="prenom"/><br/><input type="submit" value="Envoyer"/></form><?if (isset($_POST['nom']) && isset($_POST['prenom'])) {$nom = $_POST['nom'];$prenom = $_POST['prenom'];$id = fopen("liste.txt", "a");if ($id===FALSE) die("erreur");flock($id, LOCK_SH);fwrite($id, "$nom;$prenom\n");flock($id, LOCK_UN);$r = fclose($id);if ($r===FALSE) die("erreur");

}?></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 94 / 423

jean;pascaldidier;julienpaul;jacquesmichel;jean

. . . . . .

PHP Fichiers Lecture

Lecture dans un fichier

▶ Contenu du fichier toto.txt avant l’exécution :

mon texte100

<?$id = fopen("toto.txt", "r");$s = fgets($id, 256);var_dump($s); // string(10) "mon texte$\backslash$n"$s = fgets($id, 256);var_dump($s); // string(4) "100$\backslash$n"fclose($id);?>

▶ La fonction fgets prend deux paramètres : une ressource pointantsur un fichier et le nombre maximum de caractères à lire

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 95 / 423

. . . . . .

PHP Fichiers Lecture

Exemple de lecture dans un fichier

<table border="1"><tr><th>Nom</th><th>Prenom</th></tr><?$id = fopen("liste.txt", "r");while ($ligne=fgets($id)) {$t = explode(";", $ligne);echo "<tr><td>$t[0]</td><td>$t[1]</td></tr>";}flcose($id);?></table>

jean;pascaldidier;julienpaul;jacquesmichel;jean

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 96 / 423

. . . . . .

PHP Fichiers Lecture

Lecture de données formatées

<table border="1"><tr><th>Nom</th><th>Prenom</th></tr><?$id = fopen("liste.txt", "r");while ($t=fgetcsv($id, 100 /* 1 */, ";" /* 2 */)) {echo "<tr><td>$t[0]</td><td>$t[1]</td></tr>";}flcose($id);?></table>

jean;pascaldidier;julienpaul;jacquesmichel;jean

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 97 / 423

...1 : nombre maximum de caractères à lire

...2 : caractère séparateur

. . . . . .

PHP Fichiers Lecture

Lecture de la totalité d’un fichier

<table border="1"><tr><th>Nom</th><th>Prenom</th></tr><?$f = file("liste.txt");foreach ($f as $ligne) {$t = explode(";", $ligne);echo "<tr><td>$t[0]</td><td>$t[1]</td></tr>";}?></table>

jean;pascaldidier;julienpaul;jacquesmichel;jean

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 98 / 423

. . . . . .

PHP Fichiers Manipulations de fichiers

Manipulations de fichiers

▶ Copie de fichiers :<?$res = copy("liste.txt", "liste2.txt");if ($res===FALSE) die("erreur");?>

▶ Renommer un fichier :<?$res = rename("liste.txt", "liste2.txt");if ($res===FALSE) die("erreur");?>

▶ Supprimer un fichier :<?$res = unlink("liste.txt");if ($res===FALSE) die("erreur");?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 99 / 423

. . . . . .

PHP Fichiers Manipulations de fichiers

Manipulations de fichiers

▶ Existence :<?if (file_exists("liste.txt"))echo "le fichier existe";

else echo "le fichier n'existe pas";?>

▶ Créer un fichier vide :<?if (!file_exists("liste.txt"))touch("liste.txt", time());

?>▶ Taille d’un fichier :

<?$nombre_octets = filesize("liste.txt");echo $nombre_octets;?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 100 / 423

. . . . . .

PHP Fichiers Autres fonctions utiles

Autres fonctions utiles

▶ is_file("fichier") = true s’il s’agit d’un fichier▶ is_readable("fichier") = true si le fichier est dispo en lecture▶ is_writable("fichier") = true si le fichier est dispo. en écriture▶ filetype("fichier) = le type du fichier▶ basename("img/truc/toto.php") = ”toto.php”▶ realpath("toto.php") = chemin complet du fichier▶ fseek($id, n) → se positionne sur le n-ème octet▶ rewind($id) → se positionne au début du fichier▶ ftell($id) = position courante du curseur dans le fichier▶ fgetc($id) = le prochain caractère du fichier

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 101 / 423

. . . . . .

PHP Headers Introduction

Headers

Protocole HTTP

Client Serveur1. Je veux toto.html

2. Contenu de toto.html

Requête :GET /toto.html HTTP/1.0Host: example.comReferer: http://example2.com/User-Agent: Mozilla/5.0 (X11; U; Linuxx86_64; fr; rv:1.9.0.4) Gecko/2008111217Fedora/3.0.4-1.fc10 Firefox/3.0.4

Réponse :HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTServer: Apache/0.8.4Content-Type: text/htmlContent-Length: 59Expires: Sat, 01 Jan 2000 00:59:59 GMTLast-modified: Fri, 09 Aug 1996 14:21:40GMT<TITLE>Exemple</TITLE><P>page d’exemple.</P>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 102 / 423

. . . . . .

PHP Headers Modification des headers

Modification des headers▶ La fonction header(...) permet d’ajouter (ou de modifier) des

informations présentes dans l’en-tête retourné au client :<?...if ($autorized) { ?><html><body>Bienvenue</br>

</body></html>

<? } elseheader('Location: http://www.google.fr');

?>▶ La fonction header doit être appelée avant que le moindre contenu

ne soit envoyéBertrand Estellon (AMU) Développement Web 2 April 26, 2013 103 / 423

. . . . . .

PHP Headers Page non trouvée

Error 404 : Page Not Found

▶ Pour simuler le fait qu’une page n’a pas été trouvée sur le serveur :<?header("HTTP/1.0 404 Not Found");exit; // Termine l'exécution du programme.echo "Bienvenue"; // Cette instruction

// n'est pas exécutée.?>

▶ Attention :<?header("HTTP/1.0 404 Not Found");echo "Bienvenue"; // "Bienvenue" est envoyé au client...exit; // trop tard !?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 104 / 423

. . . . . .

PHP Headers Redirection

Redirection

▶ Pour rediriger le client vers une autre page :<?if (!$autorized) {header('Location: http://www.google.fr');exit; // pour éviter que la suite

// ne soit envoyé au client...}...?>

▶ Pour rediriger le client après un certain délai :<?echo "Vous allez etre redirige...<br/>"header('Refresh:10; http://www.newsite.fr');?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 105 / 423

. . . . . .

PHP Headers Content-Type et Content-Disposition

Content-Type et Content-Disposition▶ Il est possible d’envoyer un fichier texte en PHP :

<?header('Content-Type: text/plain');header('Content-Disposition: attachement;filename="a.txt"');

?>contenu du fichier texte

▶ Il est également possible d’envoyer une image :<?header('Content-Type: image/jpeg');header('Content-Disposition: attachement;filename="a.jpg"');readfile("image.jpg"); // écrit le contenu du fichier ici !

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 106 / 423

. . . . . .

PHP Headers Content-Type et Content-Disposition

Application : restreindre l’accès à un fichier

▶ Il est possible de restreindre l’accès à un fichier :<?/* ... Initialisation de la variable "accespossible" */if ($accespossible) {header('Content-Type: application/pdf');header('Content-Disposition: attachement;filename="a.pdf"');readfile('doc.pdf');exit;} else { ?><html><body>Vous n'avez pas acces a ce fichier !<br/></body></html><? }

?>

▶ Attention : le fichier ne doit pas être accessible directement sur leserveur, c’est-à-dire, sans utiliser ce fichier php.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 107 / 423

. . . . . .

PHP Headers Content-Type et Content-Disposition

Types MIME (Multipurpose Internet Mail Extensions)▶ application/octet-stream : flux de données arbitraire▶ application/ogg : Ogg▶ application/pdf : PDF▶ application/xhtml+xml : XHTML▶ application/x-shockwave-flash : Flash▶ audio/mpeg : fichier MP3 ou MPEG▶ audio/x-ms-wma : fichier Windows Media Audio▶ audio/vnd.rn-realaudio : fichier RealAudio▶ audio/x-wav : fichier WAV▶ image/gif : image GIF▶ image/jpeg : image JPEG▶ image/png : image PNG▶ image/tiff : image TIFF▶ text/css : Feuille de style▶ text/html : fichier HTML▶ text/plain : Données textuelles▶ text/xml : fichier XML▶ video/mpeg : vidéo MPEG-1▶ video/mp4 : vidéo MP4▶ video/quicktime : vidéo QuickTime▶ video/x-flv : Vidéo Flash

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 108 / 423

. . . . . .

PHP Cookies et sessions Cookies

Les cookies

▶ Un cookie est un petit fichier placé sur l’ordinateur du visiteur▶ Les cookies servent à stocker de l’information chez le visiteur▶ PHP permet d’écrire et de lire les cookies sur l’ordinateur du visiteur▶ Le visiteur peut interdire ou supprimer les cookies▶ Le visiteur peut modifier les informations contenues dans les cookies▶ Chaque site peut écrire un nombre limité de cookies sur chaque client▶ Un cookie ne doit pas dépasser 4 Kio

Remarque : les cookies sont souvent utilisés pour stocker chez le visiteurses préférences (présentation personnalisée du site).

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 109 / 423

. . . . . .

PHP Cookies et sessions Cookies

Écriture des cookies▶ Pour écrire un cookie, il faut utiliser la fonction setcookie :

<?setcookie("nom", "valeur");?>

▶ Comme pour la fonction header, la fonction setcookie doit êtreappelée avant d’écrire sur la sortie standard.

▶ Par défaut, le cookie expire à la fermeture du navigateur et estaccessible par toutes les pages de votre domaine. Pour changer cela :<?setcookie("nom",

"valeur",time()+3600, // valable une heure"/chemin/","www.domaine.com");

?>Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 110 / 423

. . . . . .

PHP Cookies et sessions Cookies

Lecture des cookies

▶ La lecture des cookies se fait via la variable superglobale $_COOKIE :▶ Contenu de la page page1.php :

<?setcookie("nom1", "valeur1");setcookie("nom2", "valeur2");?><a href="page2.html">page2</a>

▶ Contenu de la page page2.php :<?echo $_COOKIE["nom1"]."</br>"; // affiche valeur1echo $_COOKIE["nom2"]."</br>"; // affiche valeur2?>

▶ Attention : Les cookies ne sont pas immédiatement accessibles par lapage qui vient de les créer.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 111 / 423

. . . . . .

PHP Cookies et sessions Cookies

Suppression du contenu d’un cookie

▶ Pour supprimer le contenu d’un cookie :<?setcookie("nom"); // affecte la chaîne vide au cookie?>

▶ Attention :La suppression du cookie est effective au rechargement de la page.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 112 / 423

. . . . . .

PHP Cookies et sessions Cookies

Tableaux associatifs et cookies

Exemple avec des tableaux associatifs :▶ Contenu de la page page1.php :

<?setcookie("tab['key1']", "valeur1");setcookie("tab['key2']", "valeur2");setcookie("tab['key3']", "valeur3");?><a href="page2.html">page2</a>

▶ Contenu de la page page2.php :<?foreach ($_COOKIE["tab"] as $cle=>$valeur) {echo $cle."=>".$valeur." "; // 1}?>

...1 key1=>valeur1 key2=>valeur2 key3=>valeur3

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 113 / 423

. . . . . .

PHP Cookies et sessions Cookies

Exemple d’utilisation des cookies▶ Fin du fichier index.php :

// Initialisation de la variable "couleur" (slide suivant) */<?function addColor($name, $label, $couleur) {

echo '<input type="radio" name="couleur" value="'.$name.'" ';if ($couleur===$name) echo 'checked="checked"';echo '/> '.$label;

}?><html><body><font style="color:<? echo $couleur; ?>">Bonjour</font><br/><form action="<? echo $_SERVER['PHP_SELF']; ?>" method="post"><fieldset><legend>Couleur de la police</legend><?addColor('red', 'Rouge', $couleur);addColor('blue', 'Bleu', $couleur);

?></fieldset><input type="submit"/>

</form></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 114 / 423

. . . . . .

PHP Cookies et sessions Cookies

Exemple d’utilisation des cookies

▶ Au début du fichier index.php :

<?$couleur = 'red'; // couleur par défautif (isset($_POST['couleur'])) { // traitement des données du formulaire$couleur=$_POST['couleur'];setcookie("couleur", $couleur); // sauvegarde de la préférence chez le visiteur} else if (isset($_COOKIE['couleur']))$couleur=$_COOKIE['couleur']; // lecture de la préférence chez le visiteur

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 115 / 423

. . . . . .

PHP Cookies et sessions Sessions

Le mécanisme des sessions

Objectif : Conserver des informations d’un même client entre les pages.

Les étapes du mécanisme des sessions :1. au début de chaque page, l’appel de session_start() crée une

session ou restaure la session trouvée sur le serveur via l’identifiant desession passé dans une requête GET, POST ou par un cookie.

2. Au moment de la création de la session, chaque utilisateur se voitattribuer un identifiant (de session) composé de 26 caractèresaléatoires. Il est transmit d’une page à l’autre par l’intermédiaire d’uncookie placé sur le poste du client, soit dans l’URL.

3. le tableau superglobal $_SESSION permet de stocker des données liéesà la session et accessibles sur toutes les pages du site.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 116 / 423

. . . . . .

PHP Cookies et sessions Sessions

Exemples avec cookies

index.php :<?session_start();$_SESSION['info']="moninformation";echo '<a href="pagesuivante.php">page suivante</a>';?>

pagesuivante.php :

<?session_start();echo $_SESSION['info']; // affiche moninformation?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 117 / 423

. . . . . .

PHP Cookies et sessions Sessions

Sans cookiesSans cookie, on peut transmettre l’identifiant de session via l’URL.

le contenu de $SID est de la forme ’PHPSESSID=identifiant de 26 car.’

index.php :<?session_start();$_SESSION['info']="moninformation";echo '<a href="pagesuivante.php?'.$ID.'">';echo 'page suivante'echo '</a>';?>

pagesuivante.php :<?session_start();echo $_SESSION['info']; // affiche moninformation?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 118 / 423

. . . . . .

PHP Cookies et sessions Mécanisme d’authentification

Mécanisme d’authentification

<?session_start();

if (isset($_POST['login'])&& isset($_POST['passwd'])&& verifierPassword($_POST['login'],

$_POST['passwd']))$_SESSION['login'] = $_POST['login'];

else if (isset($_GET['deconnexion']))$_SESSION['login']=null;

$login = null;if (isset($_SESSION['login']))

$login = $_SESSION['login'];if ($login===null) include("FormulaireConnexion.php");else include("FormulaireDeconnexion.php");?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 119 / 423

. . . . . .

PHP Cookies et sessions Mécanisme d’authentification

Mécanisme d’authentification

FormulaireConnexion.php :<form method="POST" action="index.php">login :<input type="text" name="login"/><br/>mot de passe :<input type="password" name="passwd"/><br/><input type="submit"/></form>

FormulaireDeconnexion.php :Bonjour <? echo $login; ?>,<br/>Pour vous deconnecter, cliquez<a href="index.php?deconnexion">ici</a>.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 120 / 423

. . . . . .

PHP Cookies et sessions Mécanisme d’authentification

Mécanisme d’authentification

image.php :<?session_start();

$login = null;if (isset($_SESSION['login']))$login = $_SESSION['login'];

if ($login===null) {header("Location:index.php");} else {header("Content-Type:image/jpeg");readfile("img/toto.jpg");}

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 121 / 423

. . . . . .

PHP Programmation Orientée Objet Introduction

Programmation Orientée Objet

La programmation orientée objet de PHP 5 est similaire à celle de Java.

Nous allons voir comment :▶ Définir une classe▶ Créer une instance▶ Accéder aux propriétés et invoquer des méthodes▶ Modifier l’accessibilité aux propriétés et aux méthodes▶ Définir un constructeur et un destructeur▶ Définir des interfaces, des classes abstraites▶ Utiliser l’héritage▶ Cloner des instances

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 122 / 423

. . . . . .

PHP Programmation Orientée Objet Classe et instance

Définition d’une classe

Pour définir une classe, on utilise le mot-clé class.<?

class uneClasse {

public $p1;public $p2 = 12;public $p3 = array("toto", 12);// public $p4 = strlen('toto'); (interdit !)public function maMethode($arg1, $arg2) {

...}

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 123 / 423

. . . . . .

PHP Programmation Orientée Objet Classe et instance

Création d’une instancePour créer une instance d’une classe, on utilise le mot-clé new.<?

class uneClasse {

public $p1;public $p2 = 12;public $p3 = array("toto", 12);// public $p4 = strlen('toto'); (interdit !)

public function maMethode($arg1, $arg2) {...}}

$i1 = new maClasse();$i2 = new maClasse();

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 124 / 423

. . . . . .

PHP Programmation Orientée Objet Classe et instance

Accès aux propriétés et invocation de méthodes

<?class UneClasse {public $p;public function maMethode($arg) { ... }}

$i = new UneClasse();

$i->p = 12; // pas de dollar dans le nom de la propriétéecho $i->p;$i->p = array(1,2);echo $i->p[1]; // idem avec les tableaux

$i->maMethode("toto"); // avec la -> comme en C++?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 125 / 423

. . . . . .

PHP Programmation Orientée Objet Classe et instance

$this<?class maClasse {

public $p = 0;

public function maMethode() {$this->p+=1;echo $this->p."\n";

}

public function maMethodeBis() {$this->maMethode();

}}$i = new maClasse();$i->maMethode(); // affiche 1}$i->maMethode(); // affiche 2}$i->maMethodeBis(); / affiche 3}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 126 / 423

. . . . . .

PHP Programmation Orientée Objet Classe et instance

Constantes – propriétés et méthodes statiques<?class maClasse {const c=2;public static $s = 4;

public static function maMethode() {self::$s*=self::c;echo self::$s."\n";}}

$i1 = new maClasse();$i2 = new maClasse();$i1->maMethode(); // affiche 6maClasse::maMethode(); // affiche 8$i2->maMethode(); // affiche 10echo maClasse::$s.' '.maClasse::c; // affiche 10 2?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 127 / 423

. . . . . .

PHP Programmation Orientée Objet Classe et instance

Constructeur et destructeur<?class maClasse {

private $nom;

function __construct($nom) {$this->nom = $nom;

}

function __destruct() {echo $this->nom." est mort.\n";

}}

$i1 = new maClasse("moi");$i2 = new maClasse("toi");

$i1 = null; // affichage de 'moi est mort.'

// affichage de 'toi est mort'?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 128 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Interface<?interface monInterface1 {

public function methode1();public function methode2($arg);

}

interface monInterface2 {public function methode3();

}

class maClasse implements monInterface1,monInterface2 {

public function methode1() {...}public function methode2($arg) {...}public function methode3() {...}

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 129 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Héritage<?class maClasse {

public $n;function __construct($n) { $this->n = $n; }function afficher() { echo $this->n."\n"; }

}

class maClasseHeritee extends maClasse {public $v;

function __construct($n, $v=2) {parent::__construct($n);$this->v = $v;

}

function afficher() {echo $this->n." ".$this->v."\n";

}}

$i1 = new maClasse("instance1");$i2 = new maClasseHeritee("instance2",12);$i1->afficher();$i2->afficher();?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 130 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Héritage

<?$i1 = new maClasse("instance1");$i2 = new maClasseHeritee("instance2",12);$i1->afficher(); // affiche 'instance1'$i2->afficher(); // affiche 'instance2 12'

var_dump($i1 instanceof maClasse); // bool(true)var_dump($i2 instanceof maClasse); // bool(true)var_dump($i1 instanceof maClasseHeritee); // bool(false)var_dump($i2 instanceof maClasseHeritee); // bool(true)

var_dump($i1);?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 131 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Late Static Bindings (Résolution statique à la volée)<?class maClasse {function afficher1() { self::afficher2(); }static function afficher2() {echo "maClasse\n";}}class maClasseHeritee extends maClasse {static function afficher2() {echo "maClasseHeritee\n";}}

$i1 = new maClasse();$i2 = new maClasseHeritee();$i1->afficher1(); // maClasse$i2->afficher1(); // maClasse?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 132 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Late Static Bindings (Résolution statique à la volée)<?class maClasse {function afficher1() { static::afficher2(); }static function afficher2() {echo "maClasse\n";}}class maClasseHeritee extends maClasse {static function afficher2() {echo "maClasseHeritee\n";}}

$i1 = new maClasse();$i2 = new maClasseHeritee();$i1->afficher1(); // maClasse$i2->afficher1(); // maClasseHeritee?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 133 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Classe abstraite

<?abstract class maClasseAbstraite {

abstract public function getName();

public function afficherNom() {echo $this->getName()."\n";

}}

class maClasse extends maClasseAbstraite {public function getName() { return "moi"; }

}

$i = new maClasse();$i->afficherNom(); // affiche 'moi'?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 134 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Visibilité▶ public : utilisable par n’importe quelle partie du programme.▶ protected : utilisable uniquement par les classes et parents hérités.▶ private : utilisable uniquement par la classe qui les a définis.

<?class maClasse {

public $pub;protected $pro;private $pri;public function methodePublique() { ... }protected function methodeProtegee() { ... }private function methodePrivee() { ... }

}

class maClasseHeritee extends maClasse {public function test() {

echo $this->pub; $this->methodePublique();echo $this->pro; $this->methodeProtegee();echo $this->pri; $this->methodePrivee(); // interdit !}

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 135 / 423

. . . . . .

PHP Programmation Orientée Objet Héritage et interface

Visibilité▶ public : utilisable par n’importe quelle partie du programme.▶ protected : utilisable uniquement par les classes et parents hérités.▶ private : utilisable uniquement par la classe qui les a définis.

<?class maClasse {

public $pub;protected $pro;private $pri;public function methodePublique() { ... }protected function methodeProtegee() { ... }private function methodePrivee() { ... }

}

class maClasse2 /* qui n'étend pas maClasse */ {public function test() {$i = new maClasse();echo $i->pub; $i->methodePublique();echo $i->pro; $i->methodeProtegee(); // interdit !echo $i->pri; $i->methodePrivee(); // interdit !}

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 136 / 423

. . . . . .

PHP Programmation Orientée Objet Clonage

Clonage

<?class maClasse {

public $nom;

function __construct($nom) {$this->nom = $nom;

}

function __clone() {$this->nom = "Clone de ".$this->nom;

}}

$i = new maClasse("moi");$c = clone $i;

echo $i->nom."\n"; // affiche 'moi'echo $c->nom."\n"; // affiche 'Clone de moi'

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 137 / 423

. . . . . .

PHP Programmation Orientée Objet Méthodes magiques

Méthodes magiques – Set et Get<?class maClasse {

private $props;

public function __set($prop, $val) {echo "$prop <- $val\n";$this->props[$prop] = $val;

}public function __get($prop) {

if (!isset($this->props[$prop])) return "erreur";else return $this->props[$prop];

}}$i = new maClasse();$i->toto = 2; // affiche 'toto <- 2'echo $i->toto."\n"; // affiche '2'echo $i->a."\n"; // affiche 'erreur'?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 138 / 423

. . . . . .

PHP Programmation Orientée Objet Méthodes magiques

Méthodes magiques – Isset et Unset<?class maClasse {

private $props;

/* avec les fonctions __set et __get définies avant */

public function __isset($prop) {return isset($this->props[$prop]);

}public function __unset($prop) {

echo "destruction de $prop\n"; unset($this->props[$prop]);}

}$i = new maClasse();$i->toto = 2; // affiche 'toto <- 2'var_dump(isset($i->toto)); // affiche 'bool(true)'unset($i->toto); // affiche 'destruction de toto'?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 139 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Introduction

Modèle-Vue-Contrôleur

Le Modèle-Vue-Contrôleur (MVC) est un méthode de conception utiliséepour organiser l’interface homme-machine (IHM) d’une application.Le modèle : les données de l’application.↪→ Exemple : gestion des interactions avec une base de données.La vue : est une interface avec laquelle l’utilisateur interagit. Elle présentedes parties du modèle à l’utilisateur et reçoit les actions de l’utilisateur.↪→ Exemple : code HTML/JavaScript présenté aux clients.Le controleur : analyse les requêtes des clients, décide les actions àeffectuer sur le modèle, et choisit les vues à envoyer aux clients.↪→ Exemple : analyse des informations passées dans l’URL

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 140 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Présentation du projet

Projet 1 – SondagesPrésentation du projet : Les utilisateurs postent des sondages constituésd’une question et de plusieurs réponses. Une fois le sondage posté, il estaccessible aux visiteurs du site qui pourront voter pour une des réponsesproposées. Les nombres de voix obtenues pour chaque réponse sontcomptabilisés et affichés sous la forme d’un graphique. Tous les visiteurspeuvent chercher parmi les sondages et voter.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 141 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Organisation générale

Organisation générale

Contrôleur Action Vue

Requête HTTP

Crée et exécute

Modèle

Consulte/modifie

Crée, initialise et affiche

Réponse HTTP

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 142 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Organisation générale

Organisation générale

Contrôleur Action Vue

Requête HTTP

Crée et exécute

Modèle

Consulte/modifie

Crée, initialise et affiche

Réponse HTTP

Consulte/observe

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 143 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Le contrôleur

Le contrôleur (index.php)Les fonctions du contrôleur :<?function getActionByName($name) {$name .= 'Action';require("actions/$name.inc.php");return new $name();

}

function getViewByName($name) { /* Factory */$name .= 'View';require("views/$name.inc.php");return new $name();

}

function getAction() { /* Factory */if (!isset($_REQUEST['action'])) $action = 'Default';else $action = $_REQUEST['action'];$actions = array('Default', 'SignUpForm', ...);if (!in_array($action, $actions)) $action = 'Default';return getActionByName($action);

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 144 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Le contrôleur

Le contrôleur (index.php)

Exécution du contrôleur :<?session_start();$action = getAction();$action->run();$view = $action->getView();$action->getView()->setLogin($action->getSessionLogin());$view->run();?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 145 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les actions

Les actions du projet

Les actions :▶ SignUpForm : affichage du formulaire d’inscription▶ SignUp : demande d’inscription▶ Login : connexion du visiteur▶ Logout : déconnexion du visiteur▶ UpdateUserForm : affichage du formulaire de modification de profil▶ UpdateUser : modification du profil▶ AddSurveyForm : affichage du formulaire d’ajout de sondage▶ AddSurvey : ajout d’un sondage▶ GetMySurveys : affichage des sondages du visiteur▶ Search : recherche▶ Vote : prise en compte d’un vote

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 146 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les actions

La classe Action

Toutes les actions sont définies en étendant la classe suivante :<?abstract class Action {

private $view;protected $database;

public function __construct(){$this->view = null;$this->database = new Database();

}

protected function setView($view) { $this->view = $view; }

public function getView() { return $this->view; }

/* ... */

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 147 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les actions

La classe ActionToutes les actions sont définies en étendant la classe suivante :<?abstract class Action {

/* ... */

public function getSessionLogin() {if (isset($_SESSION['login'])) $login = $_SESSION['login'];else $login = null;return $login;

}

protected function setSessionLogin($login) {$_SESSION['login'] = $login;

}

protected function setMessageView($message, $style="") {$this->setView(getViewByName("Message"));$this->getView()->setMessage($message, $style);

}

abstract public function run();}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 148 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les actions

Exemple : l’action UpdateUser<?class UpdateUserAction extends Action {

private function setUpdateUserFormView($message) {$this->setView(getViewByName("UpdateUserForm"));$this->getView()->setMessage($message, "alert-error");

}

public function run() {if ($this->getSessionLogin()===null) {$this->setMessageView("Vous devez être authentifié.");return;

}$updatePassword = $_POST['updatePassword'];$updatePassword2 = $_POST['updatePassword2'];if (!isset($updatePassword) || !isset($updatePassword2)) {$this->setUpdateUserFormView("Vous devez remplir le formulaire.");return;

}/* ... */

}

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 149 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les actions

Exemple : l’action UpdateUser

<?class UpdateUserAction extends Action {

public function run() {/* ... */

$res = $this->database->updateUser($this->getSessionLogin(),$updatePassword);

if ($res!==true) {$this->setUpdateUserFormView($res);return;

}

$this->setMessageView("Modification enregistrée.", "alert-success");}

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 150 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Le modèle

Le modèleLe modèle contient les classes permettant de manipuler les objets“métiers” du site et de modifier la base de données. Aucune fonctionnalitéde représentation des données n’est fournie par le modèle.La classe permettant de représenter un sondage est donnée ci-dessous :<?class Survey {

private $id;private $owner;private $question;private $responses;public function __construct($owner, $question) { /*...*/ }public function setId($id) { /*...*/ }public function getId() { /*...*/ }public function getOwner() { /*...*/ }public function getQuestion() { /*...*/ }public function &getResponses() { /*...*/ }public function setResponses($responses) { /*...*/ }public function addResponse($response) { /*...*/ }public function computePercentages() { /*...*/ }

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 151 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Le modèle

Le modèleVous avez également une classe représentant une réponse :<?class Response {

private $id;private $survey;private $title;private $count;private $percentage;public function __construct($survey, $title, $count = 0) { /*...*/ }public function setId($id) { /*...*/ }public function computePercentage($total) { /*...*/ }public function getId() { /*...*/ }public function getSurvey() { /*...*/ }public function getTitle() { /*...*/ }public function getCount() { /*...*/ }public function getPercentage() { /*...*/ }

}?>

Les interaction avec la base de données se feront via une instance de classeDababase (instanciée dans le constructeur de classe Action). Nousdétaillerons les fonctionnalités de cette classe plus tard.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 152 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

La classe View

Les différentes vues du projet sont définies en étendant la classe View :<?

abstract class View {protected $message = "";protected $style = "";protected $login = null;

public function run() { require("templates/page.inc.php"); }

public function setMessage($message, $style="") {$this->message = $message; $this->style = $style;

}

public function setLogin($login) { $this->login = $login; }

}

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 153 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

La classe View

<?

abstract class View {

/* ... */

private function displayLoginForm() { require("templates/loginform.inc.php"); }private function displayLogoutForm() { require("templates/logoutform.inc.php"); }private function displayCommands() { require("templates/commands.inc.php"); }private function displaySearchForm() { require("templates/searchform.inc.php"); }

protected abstract function displayBody();}

?>

Les vues définissent la méthode displayBody afin de générer le contenu dela page (en conservant les bordures, le formulaire de connexion, etc.).

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 154 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

La génération de la page – page.inc.php

<!DOCTYPE html><html lang="en"><head>

<meta charset="utf-8"><title>Sondages</title><link rel="stylesheet" type="text/css" href="bootstrap.min.css" />

</head><body><div class="navbar navbar-inverse navbar-fixed-top">

<div class="navbar-inner"><div class="container">

<? $this->displaySearchForm(); ?><? if ($this->login===null) $this->displayLoginForm();

else $this->displayLogoutForm(); ?></div>

</div></div>

<? $this->displayBody(); ?></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 155 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Les vues

Les différentes vues du projet :▶ DefaultView : page vide▶ MessageView : affiche un message à l’utilisateur▶ SignUpFormView : formulaire d’inscription▶ UpdateUserFormView : formulaire de modification de mot de passe▶ AddSurveyFormView : formulaire d’ajout de sondage▶ SurveysView : liste de sondages

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 156 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Exemple : la vue SurveysViewPar exemple, la vue suivante permet d’afficher une liste de sondages :<?class SurveysView extends View {

private $surveys;

public function displayBody() {if (count($this->surveys)===0) { ?><div class="container"><br>br><br><br>

<div style="text-align:center" class="alert">Aucun sondage ne correspond à votre demande.

</div></div>';<?return;

}require("templates/surveys.inc.php");

}

public function setSurveys($surveys) { $this->surveys = $surveys; }}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 157 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Exemple : la vue SurveysView

La vue précédente inclue le code du fichier surveys.inc.php :<?<div class="container"><br><br><br><div class="span7 offset2"><ul class="media-list">

<?foreach ($this->surveys as $survey) {

$survey->computePercentages();require("survey.inc.php");

}?>

</ul></div></div>?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 158 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Exemple : la vue SurveysView

La vue précédente inclue le code du fichier surveys.inc.php :<?<div class="container"><br><br><br><div class="span7 offset2"><ul class="media-list">

<?foreach ($this->surveys as $survey) {

$survey->computePercentages();require("survey.inc.php");

}?>

</ul></div></div>?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 159 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Exemple : la vue SurveysView

La page survey.inc.php doit générer un code HTML de la forme suivante :<li class="media well">

<div class="media-body"><h4 class="media-heading">Question</h4><div class="fluid-row">

<div class="span2">Réponse 1</div><div class="span2 progress progress-striped active">

<div class="bar" style="width: 20%"></div></div><span class="span1">(20%)</span><form class="span1" method="post" action="index.php?action=Vote">

<input type="hidden" name="responseId" value="1"><input type="submit" style="margin-left:5px"

class="span1 btn btn-small btn-danger" value="Voter"></form>

</div><!-- Les autres réponses possibles -->

</div></li>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 160 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Exemple : déroulement d’une inscription

▶ Le client demande la page index.php;▶ Le serveur affiche la vue par défaut (vide);▶ Le client clique sur Inscription;▶ Le navigateur demande index.php?action=SignUpForm;▶ Le serveur affiche la vue SignUpFormView;▶ L’utilisateur remplit le formulaire et l’envoie;▶ Le navigateur poste le formulaire vers index.php?action=SignUp;▶ Le serveur effectue l’inscription si aucune erreur ne s’est produite;▶ Le serveur affiche la vue MessageView (avec un message de

confirmation) ou SignUpFormView (avec un message d’erreur);▶ ...

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 161 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Framework PHPIl existe des frameworks PHP qui permettent de mettre en place plusfacilement le modèle MVC :

▶ Zend▶ Symfony▶ CodeIgniter▶ CakePHP...

Ces frameworks proposent :▶ Organisation (contrôleur/actions/vues);▶ Traitement des données des formulaires;▶ Base de données et persistance;▶ Gestion des tests unitaires;▶ Internationalisation;▶ Systèmes de “template”...

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 162 / 423

. . . . . .

PHP Modèle-Vue-Contrôleur Les vues

Systèmes de “template”

Exemple de template Swig :

<!DOCTYPE html><html>

<head><title>My Webpage</title>

</head><body>

<ul id="navigation">{% for item in navigation %}

<li><a href="{{ item.href }}">{{ item.caption }}</a></li>{% endfor %}</ul>

<h1>My Webpage</h1>{{ a_variable }}

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 163 / 423

. . . . . .

PHP Base de données PDO

PDO

PDO (PHP Data Objects) est une interface pour accéder à une base dedonnées depuis PHP. Elle gère la connexion, l’envoie des requêtes, ladéconnexion à la base de données. Elle permet de changer plus facilementde système de gestion de bases de données.Ouverture de la base :<?$dbHost = $_SERVER['dbHost']; $dbBd = $_SERVER['dbBd'];$dbPass = $_SERVER['dbPass']; $dbLogin = $_SERVER['dbLogin'];$url = 'mysql:host='.$dbHost.';dbname='.$dbBd;$db = new PDO($url, $dbLogin, $dbPass);if (!$db) die("impossible d'ouvrir la base de données.");$this->createDataBase();?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 164 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

PDOUne fois l’instance de PDO construite, vous effectuez des requêtes avec :

▶ $db->exec($request) : pour modifier la base de données▶ $db->query($request) : pour extraire des données de la base

Exemples :<?$db->exec("CREATE TABLE IF NOT EXISTS users (".

" nickname char(20),"." password char(50)".");");

?>

<?$res = $db->exec('UPDATE users SET password="'.

md5($password).'" WHERE nickname="'.$nickname.'";');echo "nombre de lignes modifiees = $res";

?>

<?$res = $db->query("select nickname from users;");

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 165 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

Injections SQLLe code suivant :<?$nickname = 'aa"; DELETE FROM users; '.

'SELECT * FROM users WHERE nickname="';$password = "truc";$res = $db->exec('UPDATE users SET password="'.

md5($password).'" WHERE nickname="'.$nickname.'";');?>

exécute la requête SQL suivante :UPDATE users SET password="...." WHERE nickname="aa";DELETE FROM users;SELECT * FROM users WHERE nickname="";

Protection contre les injections SQL :<?$r = $db->prepare('UPDATE users SET password = ? '.

'WHERE nickname = ?');$r->execute(array(md5($password), $nickname));

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 166 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

PDOPour faire une requête SQL :<?$res = $db->query("select * from sondages");var_dump($res);/* affiche 'object(PDOStatement)#2 (1) {

["queryString"]=> string(19) "select * from sondages" }' */?>

Pour connaître le nombre de lignes :<? echo "nombre de lignes : ".!+$res->rowCount()+!."\n"; ?>

Pour parcourir les lignes :<?$res = $db->query("select * from sondages");while ($ligne = !+$res->fetch()+!) {

echo $ligne['createur']." pose la question : ".$ligne['question']."\n";

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 167 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

PDO

Pour mettre toutes les lignes dans un tableau :<?$res = $db->query("select * from sondages");$lignes = !+$res->fetchAll();+!foreach ($lignes as $ligne) {echo $ligne['createur'].

" pose la question : ".$ligne['question']."\n";

}?>

Voir aussi, dans la classe PDOStatement, les méthodes:▶ bindColumn : attache une variable à une colonne▶ errorInfo : information d’erreur▶ fetchColumn : récupère la valeur dans une colonne donnée▶ closeCursor : ferme le curseur

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 168 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

PDOVoir aussi, dans la classe PDO, les méthodes:

▶ beginTransaction : démarre une transaction▶ commit : valide une transaction▶ rollback : annule une transaction▶ errorInfo : Retourne les informations associées à l’erreur▶ errorCode : Retourne le SQLSTATE associé avec la dernière opération▶ prepare : Prépare une requête à l’exécution et retourne un objet▶ quote : Protège une chaîne pour l’utiliser dans une requête SQL PDO

<?$string = 'Chaine \' particulière';print "non échappée : $string\n";print "échappée :" . $bd->quote($string) . "\n";?>

Chaine non échappée : Chaine ’ particulièreChaine échappée : ’Chaine ” particulière’

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 169 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

Base de données du projet

Les trois tables utilisées dans le projet :

users(nickname char(20), password char(50));

surveys(id integer primary key autoincrement,owner char(20), question char(255));

responses(id integer primary key autoincrement,id_survey integer,title char(255),count integer);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 170 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

Exemple : sauvegarde d’un sondage<?public function saveSurvey(&$survey) {$this->connection->beginTransaction();

$query = $this->connection->prepare("INSERT INTO surveys(owner,question)"."VALUES (?,?)");

if ($query===false) { $this->connection->rollback(); return false; }

$r = $query->execute(array($survey->getOwner(), $survey->getQuestion()));if ($r === false) { $this->connection->rollback(); return false; }

$id = $this->connection->lastInsertId();$survey->setId($id);

$responses = &$survey->getResponses();foreach ($responses as &$response) {

if ($this->saveResponse($response)===false) {$this->connection->rollback(); return false;

}}$this->connection->commit(); return true;

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 171 / 423

. . . . . .

PHP Base de données Les requêtes et fonctions utiles

La classe Database

<? class Database {private $connection;

public function __construct() { ... }

public function checkPassword($nickname, $password) { ... }public function addUser($nickname, $password) { ... }public function updateUser($nickname, $password) { ... }public function saveSurvey(&$survey) { ... }public function loadSurveysByOwner($owner) { ... }public function loadSurveysByKeyword($keyword) { ... }public function vote($id) { ... }

private function createDataBase() { ... }private function checkNicknameValidity($nickname) { ... }private function checkPasswordValidity($password) { ... }private function checkNicknameAvailability($nickname) { ... }private function saveResponse(&$response) { ... }private function loadSurveys($arraySurveys) { ... }private function loadResponses($survey, $arrayResponses) { ... }

} ?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 172 / 423

. . . . . .

PHP Base de données Mapping objet-relationnel (ORM)

Mapping objet-relationnel (ORM)Les besoins :

▶ Sauvegarde simple des objets en base de données :<?$user = new User();$user->nickname = "bob";$user->password = md5("truc");$user->save();

?>

▶ Création automatique des tables;▶ Chargement des objets;▶ Gestion des relations entre les objets/enregistrements;▶ ...

Quelques solutions en PHP :▶ Propel▶ Doctrine▶ Redbean▶ ...

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 173 / 423

. . . . . .

PHP Base de données Mapping objet-relationnel (ORM)

Redbean – IntroductionInitialisation de la connexion à la base de données :<?$dbHost = $_SERVER['dbHost']; $dbBd = $_SERVER['dbBd'];$dbPass = $_SERVER['dbPass']; $dbLogin = $_SERVER['dbLogin'];$url = 'mysql:host='.$dbHost.';dbname='.$dbBd;R::setup($url, $dbLogin, $dbPass);

?>

Pour vider la base de données :<?R::nuke();

?>

Création et sauvegarde d’un bean :<?$user = R::dispense('user');$user->nickname = $nickname;$user->password = $password;R::store($user);

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 174 / 423

. . . . . .

PHP Base de données Mapping objet-relationnel (ORM)

Redbean – Chargement des beans

Chargement d’un bean à partir de son identifiant :<?$user = R::load('user', $_SESSION['id']);/* retourne NULL si le bean n'a pas été trouvé. */

?>

Charger un bean dans la base de données à partir d’une requête :<?$user = R::findOne('user', 'nickname = ? AND password = ?',

array($nickname, $password));/* retourne NULL si le bean n'a pas été trouvé. */

?>

Charger plusieurs beans :<?$surveys = R::find('survey', 'question like ?',

array('%'.$keyword.'%'));/* retourne un tableau. */

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 175 / 423

. . . . . .

PHP Base de données Mapping objet-relationnel (ORM)

Redbean – One-to-many

Association “one-to-many” entre les sondages et les réponses :<?$survey = R::dispense('survey');$survey->owner = $_SESSION['id'];$survey->question = $question;

$survey-> ownResponse = array();foreach ($titles as $title) {$response = R::dispense('response');$response->title = $title;$response->count = 0;$survey->ownResponse[] = $response;

/* Le nom du champ est important ! */}

R::store($survey); /* Tout est sauvé */?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 176 / 423

. . . . . .

PHP Base de données Mapping objet-relationnel (ORM)

Redbean – One-to-many

Le chargement de l’intégralité du sondage est automatique :<?$surveys = R::find('survey', 'owner = ?', array($_SESSION['id']));

foreach ($surveys as &$survey) {$total = 0;foreach ($survey->ownResponse as $r)$total += $r->count;

if ($total===0) {foreach ($survey->ownResponse as &$r)$r->percentage = 0;

} else {foreach ($survey->ownResponse as &$r)$r->percentage = (100*$r->count)/$total;

}}

?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 177 / 423

. . . . . .

JavaScript Introduction

JavaScript

JavaScript est un langage de programmation initialement utilisé pour créerdes pages web interactives. Il peut être inclus dans un document HTML :<!DOCTYPE html><html><head><script type="text/javascript" src="script.js"></script><script type="text/javascript">//<![CDATA[/* code JavaScript *///]]></script>

</head><body></body>

</html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 178 / 423

. . . . . .

JavaScript Déclaration des fonctions

JavaScript – Les fonctions

Il est possible de définir des fonctions en JavaScript :

function additionner(a,b,c) {a = b + c;return a;

}

function multiplier(a,b) {return a*b;

}

alert(additionner(1,2,3));alert(mutltiplier(2,4));

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 179 / 423

. . . . . .

JavaScript Les variables

JavaScript – Les variables

Par défaut, les variables non-déclarées sont globales :function ajouter(a) { total += a; }total = 0; ajouter(2); ajouter(4); alert(total);

Pour déclarer une variable, il faut utiliser le mot-clé var :function ajouter(a,b) {

var total = a + b;return b;

}total = 0;total = ajouter(total,2); total = ajouter(total,4);alert(total);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 180 / 423

. . . . . .

JavaScript Les types

JavaScript – Les typesEn JavaScript, les types sont associés aux valeurs :var v = "toto"; // variable contient une chaînev = 'toto'; // variable contient une chaînev = 22; // variable contient un nombrev = 22.12; // variable contient un nombrev = true; // variable contient un booléenv = ["toto", 22]; // variable contient un tableauv = {name:"toto", age:22}; // variable contient un objet

Une variable qui n’a jamais été affecté est ”undefined” :var v; /* v est considéré comme "undefined". */

La valeur ”null” peut être affectée à une variable. Cela signifie que lavariable existe mais sa valeur ne désigne aucun objet :var v = null;

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 181 / 423

. . . . . .

JavaScript Les types

JavaScript – Les types

Il est possible de connaître le type de la valeur contenue dans une variableà l’aide du mot-clé typeof :var v; alert(typeof v); // "undefined"v = "toto"; alert(typeof v); // "string"v = 'toto'; alert(typeof v); // "string"v = 22; alert(typeof v); // "number"v = 22.12; alert(typeof v); // "number"v = true; alert(typeof v); // "boolean"v = null; alert(typeof v); // "object"v = ["toto", 22]; alert(typeof v); // "object"v = {name:"a", age:22}; alert(typeof v); // "object"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 182 / 423

. . . . . .

JavaScript Les booleans

JavaScript – Les booleans

Affectation et utilisation des booleans :var a = true;var b = false;

var c = a || b;

if (c) {alert(a && b);

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 183 / 423

. . . . . .

JavaScript Les nombres

JavaScript – Les nombresLes différentes opérations arithmétiques :var v = 12;var v = 2 + 4;var v = 2 * 4;var v = 4 / 2;var v = 123 % 10;v++; v--;

Les différentes affectations :v=2; v+=2; v-=2; v*=2; v/=2; v%=2;

Les conversions entre chaînes et nombres :var v = parseInt("123");var v = parseFloat("123.12");var s = v.toString();

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 184 / 423

. . . . . .

JavaScript Les opérateurs

JavaScript – Les comparaisons et opérateurs logiques

égal a == b vrai si a est égal à bidentique a === b vrai si a et b sont égaux et ont le même typedifférent a != b vrai si a est différent de bnon identique a !== b vrai si a et b sont différents

ou n’ont pas le même typeplus petit a < b vrai si a est strictement plus petit que bplus grand a > b vrai si a est strictement plus grand que binférieur ou égal a <= b vrai si a est plus petit ou égal à bsupérieur ou égal a >= b vrai si a est plus grand ou égal à b

non !a vrai si a n’est pas vraiet a && b vrai si a et b sont vraisou a || b vrai si a ou b sont vrais

var v = (test)?"Vrai":"Faux";

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 185 / 423

. . . . . .

JavaScript Les conditions et les boucles

JavaScript – If/For/While/Continue/Break

var x = 2, y = 5;if (x < y) document.write("<");else document.write(">");

for (var i = 0; i < 10; i++) {if (i == 4) continue;document.write(i);if (i > 7) break;

}

var i = 0;while(i < 10) {document.write(i);i++;

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 186 / 423

. . . . . .

JavaScript Les conditions et les boucles

JavaScript – Switch

function (x) {switch (x) {

case 0 : alert("zéro"); break;case 1 : alert("un"); break;case 2 : alert("deux"); break;case 3 : alert("trois"); break;case 4 : alert("quatre"); break;default : alert("nombre"; break;

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 187 / 423

. . . . . .

JavaScript Les tableaux

JavaScript – Les tableaux

Déclaration d’un tableau :var fleurs = new Array();fleurs[0] = "Rose";fleurs[1] = "Tulipe";fleurs[2] = "Coquelicot";/* ou */fleurs = ["Rose", "Tulipe", "Coquelicot"];

Les méthodes et les propriétés:var length = fleurs.length;var position = fleurs.indexOf("Tulipe");

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 188 / 423

. . . . . .

JavaScript Les tableaux

JavaScript – Les tableaux

Parcourir un tableau :for (var i = 0; i < fleurs.length; i++)document.write(i+"->"+fleurs[i]);

for (var i in fleurs)document.write(i+"->"+fleurs[i]);

for (var fleur of fleurs) /* Expérimental */document.write(fleur);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 189 / 423

. . . . . .

JavaScript Les chaînes de caractères

JavaScript – Les chaînes de caractères

var fleur="Tulipe";var c=fleur[2]; // 'l'var length = fleur.length; // 6var index = fleur.indexOf("ip"); // '3'var s = fleur.match("[^i]*"); // 'Tul'var s = "Machin Truc";var r = s.replace("Truc", "Bidule"); // "Machin Bidule"var s = "a,b,c";var r = s.split(","); // ['a','b','c']var c = "Machin"+ " Truc" + 5 // "Machin Truc5"

Autres méthodes utiles sur les chaînes de caractères :charAt, charCodeAt, concat, contains, endsWith, indexOf, lastIndexOf,match, replace, search, slice, split, startsWith, substr, substring,toLowerCase, toString, toUpperCase, trim.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 190 / 423

. . . . . .

JavaScript Les fonctions

JavaScript – Les fonctions

Il est possible d’affecter le code d’une fonction à une variable :var sum = function(a,b) { return a+b; }alert(sum(2,3)); // affiche 5alert(typeof sum); // affiche "function"

Les fonctions peuvent utiliser des variables externes à la fonction :var a;var b = 2;var assign = function() { a = b; }assign(); alert(a); // affiche 2b = 3; assign(); alert(a); // affiche 3

Il est important de noter que le code est lié au variable (et non aux valeursdes variables au moment de la définition de la fonction).

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 191 / 423

. . . . . .

JavaScript Les fonctions

JavaScript – Les fonctionsLes paramètres des fonctions sont passés par valeur donc chaqueparamètre est une variable locale à la fonction :var sum2 = function(n) { n += 2; return n; }var n = 2;alert(sum2(n)); // affiche 4alert(n); // affiche 2

Une fonction peut retourner une fonction :var getDisplayFunction = function(a) {

return function() { alert(a); }}

var display3 = getDisplayFunction(3);var display4 = getDisplayFunction(4);display3(); // affiche 3display4(); // affiche 4

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 192 / 423

. . . . . .

JavaScript Les fonctions

JavaScript – Les fonctions

Une fonction peut retourner une fonction :var getDisplayFunction = function(a) {

return function() { alert(a); }}

var display3 = getDisplayFunction(3);display3(); // affiche 3

Le code précédent est équivalent au code suivant :var getDisplayFunction3 = function() { var a = 3;

return function() { alert(a); }}

var display3 = getDisplayFunction3();display3(); // affiche 3

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 193 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objetsEn JavaScript, il n’y a pas de classe. Les instance sont créée directement :person=new Object();person.name="Bob";person.age=22;

On peut également utiliser une description littérale de l’objet :person = {name : "Bob", age : 22};

Nous sommes en présence de références :var bob = {name: "Bob", age:22}var jim = {name: "Jim", age:23}var joe = {name: "Joe", friends : [bob, jim]}jim.age = 43;alert(joe.friends[1].age); // affiche 43

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 194 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objets

En JavaScript, il n’y a pas de classe.Une fonction permet de construire un objet :function Person(name, age) {

this.name = name;this.age = age;

}

var bob = new Person("bob", 23);var joe = new Person("joe", 42);

Il est possible d’ajouter des propriétés après la création de l’objet :var jim = new Person("jim", 45);jim.friends = [bob, joe];

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 195 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objets

Des fonctions (ou méthodes) peuvent être associées à un objet :function Counter() { this.count = 0; }var counter = new Counter();counter.notify = function() { this.count++; }counter.add(v) = function() { this.count += v; }counter.toString = function() { return "counter :"

+this.count; }counter.notify();counter.add(3);alert(counter.toString()); // "counter : 4"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 196 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objets

Il est également possible d’associer des méthodes dans le constructeur :function Counter() {

this.count = 0;this.notify = function() { this.count++; }this.add = function(v) { this.count += v; }this.toString = function() { return "counter :"

+this.count; }}

var counter = new Counter();counter.notify();counter.add(3);alert(counter.toString()); // "counter : 4"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 197 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objetsAttention, le code suivant ne fonctionne pas car, dans la méthode click, lafonction notify n’est appelée sur un objet (dans ce cas, this contient uneréférence vers l’objet Window) :function Counter() {...this.notify = function() { this.count++; }...

}

function click(callback) {callback();

}

var counter = new Counter();click(counter.notify);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 198 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objets

Le code suivant fonctionne :function Counter() {...this.notify = function() { this.count++; }...

}

function click(callback) {callback();

}

var counter = new Counter();click(function() { counter.notify(); });

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 199 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objetsUn autre exemple avec deux objets :function Button(listener) {

this.listener = listener;this.click = function() { listener.notify(this); }

}

function Counter() {this.count = 0;this.notify = function() { this.count++; }

}

var counter = new Counter();var button = new Button(counter);button.click();alert(counter.count);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 200 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objetsLe code suivant ne fonctionne pas. Pourquoi ?function Button() {

this.setCallback = function(c) { this.callback = c; }this.click = function() { this.callback(this); }

}

function Counter(notifier) {this.count = 0;notifier.setCallback(function() { this.notify(); });this.notify = function() { this.count++; }

}

var button = new Button();var counter = new Counter(button);button.click(); alert(counter.count);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 201 / 423

. . . . . .

JavaScript Les objets

JavaScript – Les objetsCorrection du code précédent :function Button() {

this.setCallback = function(c) { this.callback = c; }this.click = function() { this.callback(this); }

}

function Counter(notifier) {this.count = 0;var self = this;notifier.setCallback(function() { self.notify(); });this.notify = function() { this.count++; }

}

var button = new Button();var counter = new Counter(button);button.click(); alert(counter.count);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 202 / 423

. . . . . .

JavaScript Les prototypes

JavaScript – Les prototypesLe constructeur suivant associe des méthodes identiques à chaque objet :function Counter() {

this.count = 0;this.notify = function() { this.count++; }this.add = function(v) { this.count += v; }this.toString = function() { return "counter :"

+this.count; }}Notez que ce n’est pas forcement le cas :function Counter(step) {

this.count = 0;this.notify = function() { this.count+=step; }

}var c1 = new Counter(1); c1.notify(); alert(c1.count); // "1"var c2 = new Counter(2); c2.notify(); alert(c2.count); // "2"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 203 / 423

. . . . . .

JavaScript Les prototypes

JavaScript – Les prototypes▶ Sans optimisation et analyse du code, il est obligatoire de conserver

en mémoire toutes les fonctions associés à toutes les objets.▶ Cependant, on va pouvoir associer à des objets un prototype

contenant un ensemble de fonctions (et de propriétés) partagées.▶ Lors d’une invocation, la méthode est recherchée dans l’objet puis

dans le prototype (de façon récursive -> simulation de l’extension).▶ Voici une mauvaise façon d’affecter un prototype à un objet :

function CounterPrototype() {this.notify = function() { this.count++; }

}

var prototype = new CounterPrototype();function Counter() {

this.count = 0; this.__proto__ = prototype;}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 204 / 423

. . . . . .

JavaScript Les prototypes

JavaScript – Les prototypes

La bonne façon de faire :function Counter() { this.count = 0; }

Counter.prototype.notify = function() { this.count++; }Counter.prototype.add = function(v) { this.count += v; }Counter.prototype.toString = function() { return "counter :"

+this.count; }

var counter = new Counter();counter.notify();counter.add(2);alert(counter.toString()); // "3"alert(counter.__proto__ == Counter.prototype); // true

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 205 / 423

. . . . . .

JavaScript objet Math

JavaScript – L’objet Math

▶ x = Math.abs(-2.23); // 2.23▶ x = Math.ceil(6.05); // 7▶ x = Math.floor(6.23); // 6▶ x = Math.round(3.8); // 4▶ x = Math.max(2,6); // 6▶ x = Math.min(2,6); // 2▶ x = Math.pow(3,3); // 27▶ x = Math.random(); // 0.2323...▶ x = Math.sqrt(9); // 3▶ Math.E, Math.exp(v), Math.LN2, Math.LN10, Math.log(v),

Math.LOG2E, Math.SQRT1_2, Math.SQRT2, Math.PI, Math.sin(v),Math.asin(v), Math.cos(v), Math.acos(v), Math.tan(v),Math.atan(v);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 206 / 423

. . . . . .

JavaScript objet Date

JavaScript – L’objet Date

Création d’un objet Date :var today = new Date()var d1 = d1 = new Date("February 10, 2013 10:12:12");var d2 = new Date(2013,1,10);var d3 = new Date(2013,1,10,10,12,12);

Utilisation :var today = new Date()var year = today.getFullYear(); alert(year);today.setMonth(4);...

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 207 / 423

. . . . . .

JavaScript Exceptions

JavaScript – Les exceptions

La gestion des exceptions est similaire à Java :function validate(x) {

if(x=="") throw "empty";if(isNaN(x)) throw "not a number";if(x=="0") throw "equal zero";if(x>50) throw ["too high", x, 50];

}

try {validate("12");validate("123");

} catch(err) {alert(err);

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 208 / 423

. . . . . .

JavaScript JSON

JavaScript – JSON

JSON (JavaScript Oject Notation) est un format de données dérivé de lanotation des objets et tableaux de ECMAScript (donc de JavaScript) :{"machin": {"taille": 12,"style": "gras","bidule": {

"machin": [{"style" : "italique" },{"style" : "gras" }

]}

}}

L’avantage de JSON est qu’il est reconnu nativement par JavaScript.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 209 / 423

. . . . . .

JavaScript JSON

JavaScript – JSON

Les éléments en JSON :▶ Les objets : {chaîne : valeur, chaîne : valeur...}▶ Les tableaux : [valeur, valeur, ...]▶ Les valeurs : chaîne, nombre, objet, tableau, true, false, null▶ Les chaînes : "abcdef" ou "abcd\n\t"▶ Les nombres : -1234.12

{"unObjet": {"unTableau": [12, 13, 53],"unNombre" : 53,"unChaîne" : "truc\n""unObjet" : { "style" : "gras" }

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 210 / 423

. . . . . .

JavaScript JSON

JavaScript – JSON

En JavaScript, il est très facile de sérialiser une valeur en JSON :var bob = {name: "Bob", age:22}var jim = {name: "Jim", age:23}var joe = {name: "Joe", friends : [bob, jim]}JSON.stringify(joe);

Le code précédent génère la chaîne de caractères suivante :{"name":"Joe","friends":[

{"name":"Bob","age":22},{"name":"Jim","age":23}

]}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 211 / 423

. . . . . .

JavaScript JSON

JavaScript – JSON

Inversement, il est facile de construire une valeur à partir d’une chaîne decaractères respectant le format JSON en utilisant la fonction eval :var json = '{'+

'"name":"Joe",'+'"friends":['+

'{"name":"Bob","age":22},'+'{"name":"Jim","age":23}'+

']'+'}';

var joe = eval('('+json+')');for (var i = 0; i < joe.friends.length; i++)alert(joe.friends[i].name);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 212 / 423

. . . . . .

HTML, CSS, DOM HTML

HTMLHTML (Hypertext Markup Language) est

▶ un standard du W3C (World Wide Web Consortium).▶ un format de données conçu pour présenter des pages web.▶ un langage de balisage.

<!DOCTYPE html><html><head><title>Exemple</title>

</head><body>izgz hzegizihzi zihzg zeighze<a href="toto.html">toto</a>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 213 / 423

. . . . . .

HTML, CSS, DOM HTML

HTML

Les documents HTML décrivent une structure d’arbre :

<body><b>Liste : </b><ul>

<li>Element 1</li><li>Element 2</li><li>Element 3</li>

</ul></body>

<body>

<b> <ul>

<li> <li> <li>Liste :

Element 1 Element 2 Element 3

Chaque balise peut posséder des attributs :<img src="toto.jpg" class="image"><span class="alert">alerte</span>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 214 / 423

. . . . . .

HTML, CSS, DOM HTML

de HTML à HTML5Histoire de HTML :

▶ 1989-1992 : Origine▶ 1995 : HTML 2.0▶ 1997 : HTML 3.2 et 4.0▶ 1999 : HTML 4.01▶ 2004 : le WHATWG commence à travailler sur un nouveau standard▶ Depuis 2007 : le W3C travaille sur HTML5▶ 2014? : Version définitive de HTML5 par le W3C

Les objectifs de HTML5 :▶ De nouveaux éléments;▶ Meilleure intégration de CSS;▶ “DOM Scripting”;▶ Un grand nombre d’API pour faire des RIA.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 215 / 423

. . . . . .

HTML, CSS, DOM CSS Introduction

CSS – Introduction

CSS (Cascading Style Sheets) est un langage permettant de définir laprésentation d’un document HTML (ou XML).

Histoire de CSS :▶ 1996 : CSS 1▶ 1998 : CSS 2▶ 2004-2011 : CSS 2.1 (CR -> R)▶ 2011-2012 : CSS 3 (divisé en modules en R ou en CR)

Objectif : Séparation du contenu du document de sa présentation.Avantage : Un document peut avoir plusieurs présentations différentes.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 216 / 423

. . . . . .

HTML, CSS, DOM CSS Association du CSS au code HTML

CSS – Association du CSS au code HTMLDans un fichier séparé (fortement conseillé) :<!DOCTYPE html><html><head><link rel="stylesheet" type="text/css" href="s1.css" media="screen, tv"><link rel="stylesheet" type="text/css" href="s2.css" media="print">

</head><body></body>

</html>

Dans le fichier HTML (pour tester) :<!DOCTYPE html><html><head><style>p {margin-left:20px;}</style>

</head><body></body>

</html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 217 / 423

. . . . . .

HTML, CSS, DOM CSS Association du CSS au code HTML

CSS – Association du CSS au code HTML

On peut également utiliser l’attribut style (déconseillé) :<!DOCTYPE html><html><head></head><body><span style="font-size:20pt;color:red;">toto</span>

</body></html>

Cette solution ne doit être utilisée que pour tester une présentation.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 218 / 423

. . . . . .

HTML, CSS, DOM CSS Format

CSS – FormatUn fichier CSS se compose de règles CSS ayant le format suivant :selector { property: value; property: value; ... }

Principes :▶ Le “selector” permet de désigner un ensemble d’éléments HTML.▶ Les valeurs de certaines propriétés du style CSS des éléments

sélectionnés sont modifiées.

Exemples :body { background-color:#b0c4de; }

a:hover {text-decoration:underline;color:#FF00FF;

}Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 219 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Introduction

Association d’un style à tous les éléments :* { color:red; font-size:20pt; }

Association d’un style à tous les éléments d’un certain type :span { color:red; }p { font-size:20pt; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 220 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – AttributsSelection avec un attribut :

span[attr] /* possède */span[attr="toto"] /* est égale */span[attr~="toto"] /* est dans une liste sep. par des , */span[attr^="toto"] /* débute par */span[attr$="toto"] /* fini par */span[attr*="toto"] /* contient */span[lang|="en"] /* pour les sous-codes linguistiques */

Exemple :<span class="alert,message">mon texte</span><br>

Association d’un style aux éléments qui possèdent une classe :span[class~="alert"] { color:red; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 221 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Classes et identifiantsAssociation d’une classe à un élément HTML :<span class="alert">mon texte</span><br><span class="alert large">mon texte</span>Association d’un style aux éléments qui possèdent une classe :span.alert { color:red; }*.large { font-size:20pt; }/* ou */ .large {font-size:20pt; }

Association d’un identifiant à un élément HTML :<span id="mymessage">mon texte</span>Association d’un style à un élément via son identifiant :span#mymessage { color:red; }*#mymessage { font-size:20pt; }/* ou */ #mymessage { font-size:20pt; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 222 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Pseudo-classes structurelles

Vous pouvez baser votre sélection sur des informations se trouvant dansl’arbre documentaire à l’aide des pseudo-classes suivantes :

▶ E:root, E:nth-child(n), E:nth-last-child(n), E:nth-of-type(n),E:nth-last-of-type(n), E:first-child, E:last-child, E:first-of-type,E:last-of-type, E:only-child, E:only-of-type, E:empty

Exemples :li:last-child { color:blue; }li:first-child { color:red; }tr:nth-child(2n+1) { color:blue; }tr:nth-child(even) { color:red; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 223 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Les autres pseudo-classes

Les autres pseudo-classes :▶ E:link, E:visited, E:active, E:hover, E:focus, E:target,

E:lang(c), E:enabled, E:disabled, E:checked,E:indeterminate, E:contains(”txt”), E:not(s)

Exemples :a:link { color:red; }a:link:hover { text-decoration:underline; }a:not([href="toto.html"]) {color:red; }span:contains("toto") { color:blue; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 224 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Les pseudo-éléments

Les pseudo-éléments :▶ E::first-line, E::first-letter, E::selection, E::before, E::after

Exemple :p { font-size: 12pt; line-height: 12pt }p::first-letter {

font-size: 200%;font-weight: bold;float: left;

}span { text-transform: uppercase; }

Pour le texte :<p><span>Les premiers</span> mots d'un article.</p>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 225 / 423

. . . . . .

HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Les combinateurs

Les combinateurs :▶ E F : un élément F descendant de E▶ E > F : un élément F fils de E▶ E + F : un élément F immédiatement précédé par E▶ E ~ F : un élément F précédé par E

Exemple :div p *[href="toto.html"] { color : red; }div ol>li p a:link { color : red; }ol li.alert { color : red; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 226 / 423

. . . . . .

HTML, CSS, DOM CSS Propriétés

CSS – Propriétés

p {background-color:#e0ffff;}h1 {text-align:center;}h1 {font-size:40px; font-style:italic; font-weight:bold; }a:link {text-decoration:underline;}ul.square {list-style-type: square;}p { border-style:solid; border-width:5px; }div { margin:25px 50px 75px 100px; }div { padding:25px 50px 75px 100px; }div.hidden {display:none;}span { display:block; }div { display:inline; }.center { margin-left:auto; margin-right:auto; width:600px; }

Nous utiliserons souvent Bootstrap pour simplifier l’écriture des CSS.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 227 / 423

. . . . . .

HTML, CSS, DOM DOM

DOM – Introduction

Le DOM (Document Object Model) est :▶ un standard du W3C;▶ une interface pour accéder et mettre à jour le contenu, la structure ou

le style d’un document HTML ou XML;▶ indépendant de tout langage de programmation.

Le DOM est découpé en trois parties :▶ Core DOM : Modèle pour tous les documents;▶ XML DOM : Modèle pour les documents XML;▶ HTML DOM : Modèle pour les documents HTML.

Le DOM HTML permet de récupérer, de changer, d’ajouter ou desupprimer des éléments HTML.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 228 / 423

. . . . . .

HTML, CSS, DOM DOM

DOM – Les noeudsChaque élément du document HTML est un noeud :

▶ Le document est un noeud;▶ Les éléments HTML (venant des balises) sont des noeuds;▶ Les textes dans les balises sont des noeuds;▶ Les attributs sont des noeuds;▶ Les commentaires sont des noeuds.

Document

Élement racine :<html>

Élement :<head>

Élement :<title>

Texte :"Titre"

Élement :<body>

Élement :<span>

Texte :"Mon texte"

Attirbut :class="alert"

Élement :<b>

Texte :"Truc"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 229 / 423

. . . . . .

HTML, CSS, DOM DOM

DOM – Les noeuds

▶ Chaque noeud a un unique parent (la racine n’a pas de parent);▶ Un noeud peut avoir plusieurs enfants;▶ Les enfants de chaque noeud sont ordonnés.

Document

Élement racine :<html>

Élement :<head>

Élement :<title>

Texte :"Titre"

Élement :<body>

Élement :<span>

Texte :"Mon texte"

Attirbut :class="alert"

Élement :<b>

Texte :"Truc"

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 230 / 423

. . . . . .

HTML, CSS, DOM DOM

DOM – API

Modification du DOM via JavaScript :function showMessage() { alert("click !"); }

var button = document.getElementById("mybutton");button.onclick = showMessage;var links = document.getElementsByTagName("a");for (var i=0; i<links.length; i++)links[i].onclick = showMessage;

Remarques :▶ Des fonctions existent pour modifier les attributs, le style, insérer et

supprimer des éléments HTML, c’est-à-dire, des noeuds du DOM.▶ Des librairies existent pour simplifier les interactions avec le DOM.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 231 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQueryjQuery est une bibliothèque JavaScript libre qui permet de simplifier laprogrammation en JavaScript (AJAX et interaction avec le DOM).Elle est disponible sous Licence MIT, GNU GPL.“Installation” :

▶ Télécharger le code JavaScript sur le site de JQuery;▶ Inclure le code suivant dans l’en-tête de votre fichier HTML :

<script type="text/javascript" src="jquery-xxx.min.js"></script>

Exemple d’utilisation :<script type="text/javascript">$(function() {

$("a").click(function() { alert("Hello world!"); });});</script>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 232 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – Sélectionner des élémentsSélectionner un élément par son identifiant :$("#id_element").addClass("maClasseCss");Sélectionner un élément par sa classe :$(".classeCss").click(function() { alert("coucou"); });Sélectionner des elements contenus dans un autre élément :$("#list > li").addClass("blue"); /* ou */$("#list").find("li").addClass("blue");Tout sélectionner :$("*").addClass("blue");Appliquer une fonction sur un ensemble d’éléments :$("#list").find("li").each(function(i) {

$(this).append( "Je suis le numero " + i);});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 233 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – Modifier les attributs et les propriétés

Les attributs (valeurs initiales présentes dans le HTML) :$("#id_element").attr("title","toto");a = $("#id_element").attr("title");$("#id_element").removeAttr("title");

Les propriétés (valeurs courantes dans le DOM) :$("#id_element").prop("checked",true);a = $("#id_element").prop("checked");$("#id_element").removeProp("toto");

La valeur :$("#id_element").val("coucou");v = $("#id_element").val();

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 234 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – Parcourir les élémentsAppliquer une fonction sur un ensemble d’éléments :$("#list").find("li").each(function(i) {

$(this).append( "Je suis le numero " + i);});Récupérer la liste des fils d’un élément :$('#list').children().css('background-color', 'red');Récupérer le premier élément :$('#list').children().first().css('background-color', 'red');Récupérer le dernier élément :$('#list').children().last().css('background-color', 'red');Filtrer les éléments :$('#list').children().filter(function(i) {return i%3== 0;})

.css('background-color', 'red');

(Voir les autres fonctionnalités sur le site de jQuery)Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 235 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – Ajouter, supprimer des élémentsModifier et récupérer le contenu des éléments :$("#list").find("li").html("<b>toto</b>");$("#list").find("li").text("<b>toto</b>");c_html = $("#list").find("li").html();c_text = $("#list").find("li").text();Ajouter dans des éléments :$("#list").find("li").append("toto");Supprimer un ensemble d’éléments du DOM :$("#list").find("li").remove();Insérer avant et après des éléments :$('#test').children().before("<li>avant chaque element</li>");$('#test').children().after("<li>apres chaque element</li>");

(Voir les autres fonctionnalités sur le site de jQuery)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 236 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – CSSLes classes css :r = $("#id_element").hasClass("maClasseCss");$("#id_element").removeClass("maClasseCss");$("#id_element").toggleClass("maClasseCss");Jouer avec le style :$("#id_element").css('background-color', 'red');color = $("#id_element").css('background-color');Jouer avec la hauteur et la largeur :$("#id_element").height(100);h = $("#id_element").height();$("#id_element").!+width(100);w = $("#id_element").width();Connaître la position d’un élément :p = $("#id_element").offset(); // par rapport au documentalert(p.left+" "+p.top);p = $("#id_element").position(); // par rapport au parentalert(p.left+" "+p.top);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 237 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – Les événementsLa souris :$("#id_element").click(function() { alert("click."); });$("#id_element").mouseup(function(){$(this).append('up ');}).

.mousedown(function(){$(this).append('down ');});

Le clavier :$('#input_text').keydown(function(event) {

if (event.keyCode == '13') {alert("ok");

}});

Les changements :$("#id_element").change(function() { alert("change."); });

(Voir les autres fonctionnalités sur le site de jQuery)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 238 / 423

. . . . . .

HTML, CSS, DOM jQuery

jQuery – Les autres fonctionnalités

▶ Les effets et animations▶ Des outils pour simplifier la programmation en JavaScript▶ JQuery UI :

▶ Librairie de widgets▶ Interaction (Drag & drop, tri, etc).▶ Thèmes▶ Effets

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 239 / 423

. . . . . .

Communication client/serveur AJAX

Ajax (Asynchronous JavaScript and XML)

Ajax est un acronyme pour Asynchronous JavaScript and XML.

Il est un ensemble de technologies libres couramment utilisées :▶ HTML (ou XHTML) pour la structure sémantique des informations;▶ CSS pour la présentation des informations;▶ DOM et javaScript pour interagir avec l’information présentée;▶ l’objet XMLHttpRequest pour échanger l’information avec le serveur;▶ XML (parfois JSON) pour le format des données informatives.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 240 / 423

. . . . . .

Communication client/serveur AJAX L’objet XMLHttpRequest

XMLHttpRequest : CréationUne fonction Javascript permettant de créer un objet XMLHttpRequest :function createXhrObject(){

if (window.XMLHttpRequest)return new XMLHttpRequest();

if (window.ActiveXObject) {var names = [

"Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"

];for(var i in names) {

try{ return new ActiveXObject(names[i]); }catch(e){}

}}window.alert("pas de XMLHTTPRequest.");return null;

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 241 / 423

. . . . . .

Communication client/serveur AJAX L’objet XMLHttpRequest

XMLHttpRequest : Les méthodes et propriétésDescription de l’objet XMLHttpRequest :interface XMLHttpRequest {

/* requête */void open(DOMString method, DOMString url);void open(DOMString method, DOMString url, boolean async);/* ... */void setRequestHeader(DOMString header, DOMString value);void send();void send(Document data);/* ... */void abort();

/* réponse */readonly attribute unsigned short status;readonly attribute DOMString statusText;DOMString getResponseHeader(DOMString header);DOMString getAllResponseHeaders();readonly attribute DOMString responseText;readonly attribute Document responseXML;

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 242 / 423

. . . . . .

Communication client/serveur AJAX L’objet XMLHttpRequest

XMLHttpRequest : Les méthodes et propriétés

Suite de la descrition de l’objet XMLHttpRequest :interface XMLHttpRequest {

/* ... */

/* gestionnaire d'événement */attribute Function onreadystatechange;

/* états */const unsigned short UNSENT = 0;const unsigned short OPENED = 1;const unsigned short HEADERS_RECEIVED = 2;const unsigned short LOADING = 3;const unsigned short DONE = 4;readonly attribute unsigned short readyState;

};

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 243 / 423

. . . . . .

Communication client/serveur AJAX L’objet XMLHttpRequest

XMLHttpRequest : Les états

Les différents états de XMLHttpRequest :▶ UNSENT (0) : L’objet a été construit.▶ OPENED (1) : La méthode open a été invoquée avec succès. Le header

de la requête peut être modifié avec la méthode setRequestHeader.▶ HEADERS_RECEIVED (2) : Le header HTTP de la réponse a été reçu.▶ LOADING (3) : Le corps de la réponse est en cours de téléchargement.▶ DONE (4) : Le transfert des données est terminé (ou erreur !).

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 244 / 423

. . . . . .

Communication client/serveur AJAX Les reqêtes asynchrones

XMLHttpRequest : Requête asynchrone GET

Exemple de requête GET :

xhr = createXhrObject();

xhr.onreadystatechange = function() {if(xhr.readyState == 4) {

if(xhr.status == 200) alert(xhr.responseText);else alert("Error : "+xhr.status);

}};

xhr.open("GET", "server.php?a=12&b=13", true);xhr.send(null);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 245 / 423

. . . . . .

Communication client/serveur AJAX Les reqêtes asynchrones

XMLHttpRequest : Requête asynchrone POST

Exemple de requête POST :xhr = createXhrObject();

xhr.onreadystatechange = function() {if(xhr.readyState == 4) {

if(xhr.status == 200) alert(xhr.responseText);else alert("Error : "+xhr.status);

}};

xhr.open("POST", "server.php", true);xhr.setRequestHeader("Content-Type",

"application/x-www-form-urlencoded");xhr.send("a=12&b=13");

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 246 / 423

. . . . . .

Communication client/serveur AJAX Les reqêtes asynchrones

AJAX et jQuery

Exemple de requête POST :$.ajax({type: "POST",url: "toto.php",data: {numero : "123", nom : "bob"}

}).done(function( msg ) { alert( msg ); }).fail(function() { alert("erreur"); }).always(function() { alert("fini"); });

Exemple de requête GET :$.get("test.php", { 'choices[]': ["Jon", "Susan"]} );

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 247 / 423

. . . . . .

Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : la problématique

Nous souhaitons réaliser le site suivant :

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 248 / 423

. . . . . .

Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : les données

Nous avons sur notre serveur le fichier authors.json suivant :[{

"name" : "Simone de Beauvoir","picture" : "beauvoir.jpg","description" : "beauvoir.json"

},{

"name" : "Agatha Christie","picture" : "christie.jpg","description" : "christie.json"

},/* ... */

]

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 249 / 423

. . . . . .

Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : les donnéesNous avons également les images associés aux auteurs dans un répertoireimage du serveur. De plus, pour chaque auteur, nous avons un fichier dela forme suivante :{ "name" : "Victor Hugo","description" : "Victor Hugo, né le 26 février 1802 à

Besançon et mort le 22 mai 1885 àParis, est un poète, dramaturge etprosateur romantique considéré commel’un des plus importants écrivainsde langue française. [wikipedia]",

"born" : "26 février 1802, Besançon","died" : "22 mai 1885, Paris"

}

Le nom du fichier est donné par les propriétés description associées àchaque auteur dans le fichier authors.json.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 250 / 423

. . . . . .

Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : index.htmlNous allons remplir dynamiquement la structure de document suivante :<!DOCTYPE html><html><head>

<script src="index.js"></script><!--- et bootstrap et jquery ---></head><body>

<div class="container"><div class="fluid-row"><table id="list" class="table table-bordered span3 offset2"></table><div id="author" class="span4 well hide">

<h2 id="author_name"></h2><span id="author_description"></span><br><br><strong>Naissance : </strong><span id="author_born"></span><br><strong>Décès : </strong><span id="author_died"></span><br>

</div></div></div>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 251 / 423

. . . . . .

Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : index.jsfunction displayAuthorsList(authors) {$("#list").html("");for (var i = 0; i < authors.length; i++) {

var author = authors[i];var line = '<tr onclick="showAuthor(\''+author.description+'\');">';line += '<td><strong>'+author.name+'</strong></td>';line += '<td><img src="resources/images/'+author.picture+'"></td>';line += '</tr>';$("#list").append(line);

}}

function displayAuthor(author) {$("#author").removeClass("hide");$("#author_name").text(author.name);$("#author_description").text(author.description);$("#author_born").text(author.born);$("#author_died").text(author.died);

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 252 / 423

. . . . . .

Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : index.jsfunction requestAuthorsList(callback) {$.ajax({ url : "resources/authors.json",

type : "GET",dataType : "json",success : callback });

}

function requestAuthor(ressource, callback) {$.ajax({ url : "resources/"+ressource,

type : "GET",dataType : "json",success : callback });

}

function showList() { requestAuthorsList(displayAuthorsList); }function showAuthor(resource) { requestAuthor(resource, displayAuthor); }

$(document).ready(function() { showList(); });

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 253 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

jQuery, AJAX, JSON et PHP

Côté serveur :header('Content-type: application/json');$a = array('nom'=>$_POST['nom'],

'maj'=>strtoupper($_POST['nom']));echo json_encode($a);

Côté client :$.ajax({type: "post",url: "server.php",data: { nom : "bob" }

}).done(function( msg ) {alert( msg['nom']+"=>"+msg['maj'] );

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 254 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletionAutocomplétion sur les mots du français :

Nous allons utiliser :▶ coté client : jQuery et Bootstrap;▶ coté serveur : PHP.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 255 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletion – index.html

<!DOCTYPE html><html><head>

<link href="bootstrap-combined.min.css" rel="stylesheet"><script src="jquery.min.js"></script><script src="bootstrap.min.js"></script><script src="index.js"></script>

</head><body>

<input id="input"type="text"data-provide="typeahead">

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 256 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletion – index.js

Avec Bootstrap, il est très facile de mettre en place l’autocompletion :function getWords(query, callback) {$.ajax({ url : "server.php",

method : "post",dataType : "JSON",data : { query : query },success : callback

});}

$(document).ready(function() {$("#input").typeahead({ source : getWords });

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 257 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletion – server.php<?function getWords(&$query) {

if (empty($query)) return array();$file = fopen("francais.txt","r");$words = array();while (($word = fgets($file, 255))!==false) {

if (strpos($word, $query) === 0) $words[] = $word;if (count($words) > 8) break;

}return $words;

}

$query = &$_POST['query'];$words = getWords($query);echo json_encode($words);?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 258 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletion – déroulement d’une requête

getWords("mang", callback)

$.ajax({...}) : post server.php avec query="mang"

getWords("mang")json_encode(array("manganate", ...))

réponse du serveur '["manganate", ... ]'

callback(["manganate", ... ])

Serveur

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 259 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – index.html

<body><div class="navbar navbar-inverse navbar-fixed-top"><div class="navbar-inner"><div class="container"><form id="signin_form" action="#" class="navbar-form pull-right"><input id="signin_nickname" class="span2" type="text"><input id="signin_password" class="span2" type="password"><button id="signin_button" type="submit" class="btn">Sign In</button>

</form><form id="logout_form" action="#" class="navbar-form pull-right hide"><button id="logout_button" type="submit" class="btn">Logout</button>

</form></div></div>

</div><div class="container"><div id="message" class="hide alert alert-error span6 offset2"></div>

</div></body>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 260 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – server.php

Fonctions pour maintenir le pseudonyme de l’utilisateur dans la session :<?function setSessionNickname($nickname) {$_SESSION["nickname"] = $nickname;

}

function getSessionNickname() {$nickname = &$_SESSION["nickname"];return isset($nickname)?$nickname:null;

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 261 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – server.phpExécution de l’action demandée par le client :<?function runServerAction(&$action) {

if (!isset($action) || !(in_array($action,array("signin", "logout", "init"))))

return array("action"=>"error", "msg"=>"Invalid action.");return $action();

}

session_start();$action = &$_GET['action'];$result = runServerAction($action);echo json_encode($result);?>Il est également possible (et souhaitable) de mettre place une architecturesimilaire à celle du premier projet ou utiliser un framework PHP.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 262 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – server.phpLes actions du serveur :<?function signin() {$nickname = &$_POST['nickname'];$password = &$_POST['password'];if (empty($nickname) || empty($password))return array("action"=>"error",

"msg"=>"Empty nickname or password.");if ($nickname !== "toto" || $password !== "toto")return array("action"=>"error",

"msg"=>"Invalid nickname or password.");setSessionNickname($nickname);return array("action"=>"signin", "nickname"=>$nickname);

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 263 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – server.php

Les actions du serveur :<?function logout() {setSessionNickname(null);return array("action"=>"logout");

}

function init() {$nickname = getSessionNickname();if ($nickname!==null)

return array("action"=>"signin", "nickname"=>$nickname);else return array("action"=>"logout");

}?>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 264 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – index.jsfunction signin() {$("#message").addClass("hide");runServerAction("signin", {

nickname : $("#signin_nickname").val(),password : $("#signin_password").val() });

}function logout() {$("#message").addClass("hide");runServerAction("logout", { });

}

$(document).ready(function() {$("#signin_button").click(signin);$("#logout_button").click(logout);runServerAction("init", { });

});Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 265 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – index.jsfunction runClientAction(data) {

switch (data.action) {case "error" : runErrorAction(data); break;case "signin" : runSigninAction(data); break;case "logout" : runlogoutAction(data); break;

}}

function runServerAction(actionName, data) {$.ajax({ url : "server.php?action="+actionName,

method : "post",dataType : "JSON",data : data,success : runClientAction

});}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 266 / 423

. . . . . .

Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – index.js

function runErrorAction(data) {$("#message").text(data.msg);$("#message").removeClass("hide");

}

function runSigninAction(data) {$("#signin_form").addClass("hide");$("#logout_form").removeClass("hide");

}

function runlogoutAction(data) {$("#signin_form").removeClass("hide");$("#logout_form").addClass("hide");

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 267 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)Vous devez réaliser un jeu client/serveur.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 268 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Déroulement de la partie :

▶ La grille est vide et le serveur choisit un mot à faire deviner au joueur.▶ Le joueur tape un mot de 8 lettres dans la zone de texte puis appuie

sur la touche entrée pour soumettre le mot au serveur.▶ Le serveur associe alors une couleur à chaque lettre du mot :

▶ La couleur rouge est associée aux lettres bien placées.▶ La couleur jaune est associée aux lettres mal placées mais présentes

dans le mot à trouver.▶ Les couleurs associées à chaque lettre sont envoyées au client.▶ La partie s’arrête une des deux conditions est vérifiées :

▶ Le joueur a trouvé le mot → gagné;▶ Le joueur a rempli toutes les lignes de la grille → perdu;

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 269 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)Première partie du projet : Vous devez réaliser le projet en utilisantuniquement PHP en vous basant sur l’organisation mise à place dans leprojet ”Sondages”. Les joueurs doivent pouvoir :

▶ créer un compte;▶ s’authentifier;▶ changer de mot de passe;▶ commencer une nouvelle partie;▶ jouer;▶ afficher le tableau des scores.

Deuxième partie du projet : Utiliser la technologie AJAX pour réduire laquantité de données envoyées par le serveur. Le but est d’obtenir uneversion où toutes les actions de l’utilisateur se font en utilisant AJAX.Librairies : jQuery et Bootstrap.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 270 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 271 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 272 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 273 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 274 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 275 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 276 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 277 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 278 / 423

. . . . . .

Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 279 / 423

. . . . . .

Communication client/serveur Comet Problématique

Problématique

Problématique : Nous souhaitons réaliser un tchat.▶ Les clients se connectent au serveur;▶ Les clients peuvent discuter;▶ Les clients peuvent voir les messages envoyés par les autres clients;

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 280 / 423

. . . . . .

Communication client/serveur Comet Problématique

ProblématiqueProblème : En PHP, chaque requête du client est traitée indépendamment.Il n’y a donc pas de :

▶ Processus persistant et de donnée en mémoire persistante⇒ Difficulté pour conserver l’état courant de la partie

(i.e. orchestrer plusieurs clients)▶ Connexion persistante (le client demande et le serveur répond)

⇒ Difficulté pour envoyer des événements aux clients.Solution :

▶ Côté client : WebSocket de HTML 5▶ Côté serveur : Java et Jetty (serveur HTTP et moteur de servlet libre)

Autres solutions :▶ AJAX et l’approche Comet▶ Socket.IO (développement du client et du serveur en JavaScript)▶ ...

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 281 / 423

. . . . . .

Communication client/serveur Comet Création d’un serveur avec Jetty

Jetty – Création d’un serveur Web

Création d’un serveur Web avec Jetty :Server httpServer = new Server(8080);

ResourceHandler resourceHandler = new ResourceHandler();resourceHandler.setWelcomeFiles(new String[] { "index.html" });resourceHandler.setResourceBase("www");

HandlerList handlers = new HandlerList();handlers.setHandlers(new Handler[] { resourceHandler,

new DefaultHandler() });httpServer.setHandler(handlers);httpServer.start();httpServer.join();

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 282 / 423

. . . . . .

Communication client/serveur Comet Création d’un serveur avec Jetty

Jetty – Création d’un serveur WebGestion des sessions et mises en place de code spécifique pour traiter lesrequêtes send et get :/* ... */ServletContextHandler contextHandler = new

ServletContextHandler(ServletContextHandler.SESSIONS);contextHandler.setContextPath("/chat");

ChatServer chatServer = new ChatServer();contextHandler.addServlet(new ServletHolder(

new SendServlet(chatServer)), "/send");contextHandler.addServlet(new ServletHolder(

new GetServlet(chatServer)), "/get");

HandlerList handlers = new HandlerList();handlers.setHandlers(new Handler[] { resourceHandler,

contextHandler,new DefaultHandler() });

httpServer.setHandler(handlers);/* ... */

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 283 / 423

. . . . . .

Communication client/serveur Comet Le serveur

Jetty – Classe ChatServer

public class ChatServer {

private List<User> users;

public ChatServer() { users = new ArrayList<User>(); }

public void addUser(User user) { users.add(user); }

public void sendMessage(String msg) {for (User user : users) user.addMessage(msg);

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 284 / 423

. . . . . .

Communication client/serveur Comet Le serveur

Jetty – Classe Userpublic class User {

private BlockingDeque<String> messages;

public User() {messages = new LinkedBlockingDeque<String>();

}

synchronized public void addMessage(String msg) {try { messages.putLast(msg); }catch (InterruptedException e) { }

}synchronized public String getMessage() {

try { String msg = messages.takeFirst(); return msg;} catch (InterruptedException e) { return ""; }

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 285 / 423

. . . . . .

Communication client/serveur Comet Le serveur

Jetty – Classe ChatServer

public abstract class ChatServlet extends HttpServlet {protected ChatServer server;

public ChatServlet(ChatServer server) { this.server = server; }

protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {

HttpSession session = req.getSession(true);User user = (User)session.getAttribute("user");if (user==null) { user = new User(); server.addUser(user);

session.setAttribute("user", user);}String responses = doAction(user, req);resp.getWriter().println(responses);

}

protected abstract String doAction(User user, HttpServletRequest req);}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 286 / 423

. . . . . .

Communication client/serveur Comet Le serveur

Jetty – Classe SendServlet

public class SendServlet extends ChatServlet {

public SendServlet(ChatServer server) {super(server);

}

@Overrideprotected String doAction(User user,

HttpServletRequest req) {String msg = req.getParameter("msg");if (msg!=null) server.sendMessage(msg);return "\"ok\"";

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 287 / 423

. . . . . .

Communication client/serveur Comet Le serveur

Jetty – Classe GetServlet

public class GetServlet extends ChatServlet {

public GetServlet(ChatServer server) {super(server);

}

@Overrideprotected String doAction(User user,

HttpServletRequest req) {String msg = user.getMessage();return msg;

}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 288 / 423

. . . . . .

Communication client/serveur Comet Le client

Jetty – index.html<!DOCTYPE html><html><head><!--- avec Bootstrap et jQuery --->

<script src="index.js"></script></head><body><div class="container">

<div class="fluid-row"><div class="span4"><form action="#" class="well form-inline">

<input type="text" id="message"><button class="btn" id="send">Send</button>

</form></div><div class="well span3" id="messages"></div>

</div></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 289 / 423

. . . . . .

Communication client/serveur Comet Le client

Jetty – index.js

function sendCallback(data) { $("#message").val(""); }

function send() {$.ajax({ url : "/chat/send",

method : "post",dataType : "JSON",data : { msg : $("#message").val() },success : sendCallback

});}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 290 / 423

. . . . . .

Communication client/serveur Comet Le client

Jetty – index.js

function getCallback(data) {$("#messages").append(data+"<br>");getMessage();

}

function getMessage() {$.ajax({ url : "/chat/get",

method : "post",success : getCallback

});}

function init() { $("#send").click(send); getMessage(); }$(document).ready(function() { init(); });

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 291 / 423

. . . . . .

Communication client/serveur Comet Continuations

Jetty – Continuations

Problématique : Dans la première version, pour supporter un très grandnombre de clients, il est nécessaire que le serveur puisse être en train detraiter un grand nombre de requêtes simultanément.

Première solution : Dans la première version, on doit permettre auserveur de créer un thread pour créer chacune des requêtes des clients. End’autres termes, le nombre de clients possibles est limité par le nombre dethreads que le serveur peut créer.

Les “continuations” : Elles permettent de mettre en suspend letraitement d’une requête et de le reprendre plus tard.Conséquence : On va pouvoir mettre en place un pool de Threads pourtraiter les requêtes (nouvelles ou suspendus).

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 292 / 423

. . . . . .

Communication client/serveur Comet Continuations

Jetty – Modification de la classe User

public class User {private Deque<String> messages = new ArrayDeque<String>();private Continuation continuation;

synchronized public String getMessage(HttpServletRequest req) {

if (messages.size()==0) {continuation =

ContinuationSupport.getContinuation(req);continuation.suspend(); return null;

}return messages.pollFirst();

}/* ... */

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 293 / 423

. . . . . .

Communication client/serveur Comet Continuations

Jetty – Modification de la classe User

public class User {/* ... */

synchronized public void addMessage(String msg) {messages.add(msg);if (continuation!=null) {continuation.resume(); continuation = null;

}}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 294 / 423

. . . . . .

Communication client/serveur Comet Continuations

Jetty – Modification de la classe ChatServlet

public abstract class ChatServlet extends HttpServlet {/* ... */

protected void doPost(HttpServletRequest req,HttpServletResponse resp)

throws ServletException, IOException {/* ... */String response = doAction(user, req);if (response!=null) resp.getWriter().println(response);

}

/* ... */}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 295 / 423

. . . . . .

Communication client/serveur Comet Continuations

Jetty – Modification de la création du serveur

Il est maitenant possible de limiter le nombre de Threads à la création duserveur sans limiter le nombre de clients :QueuedThreadPool threadPool = new QueuedThreadPool();threadPool.setMaxThreads(200);Server httpServer = new Server(8080);httpServer.setThreadPool(threadPool);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 296 / 423

. . . . . .

Communication client/serveur WebSocket

WebSocketObjectif (Wikipedia) : Obtenir un canal de communication bidirectionnelet full-duplex sur un socket TCP pour les navigateurs et les serveurs web.

Demande de connexion du client et “handshake” :GET /ws HTTP/1.1Host: pmxUpgrade: websocketConnection: UpgradeSec-WebSocket-Version: 6Sec-WebSocket-Origin: http://pmxSec-WebSocket-Extensions: deflate-streamSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==

du serveur :HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 297 / 423

. . . . . .

Communication client/serveur WebSocket WebSocket et JavaScript

Client – WebSocket et JavaScript

Demande d’ouverture de la connexion avec le serveur :ws = new WebSocket('ws://toto.com:8080');

Mise en place des “callbacks” :ws.onopen = onOpen;ws.onclose = onClose;ws.onerror = onError;ws.onmessage = onMessage;

Exemples de “callbacks” :function onOpen(event) { alert("Connexion etablie."); }function onClose(event) { alert("Connexion perdue."); }function onError(event) { alert("Erreur"); }function onMessage(event) { alert(event.data); }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 298 / 423

. . . . . .

Communication client/serveur WebSocket WebSocket et Jetty

Serveur – avec JettyCréation du serveur avec Jetty :public static void main(String[] args) throws Exception {

Server httpServer = new Server(8080);

ResourceHandler resourceHandler = new ResourceHandler();resourceHandler.setWelcomeFiles(new String[] { "index.html" });resourceHandler.setResourceBase("www");

HandlerList handlers = new HandlerList();handlers.setHandlers(new Handler[] {

new WSHandler(),resourceHandler,new DefaultHandler() });

httpServer.setHandler(handlers);

httpServer.start();httpServer.join();

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 299 / 423

. . . . . .

Communication client/serveur WebSocket WebSocket et Jetty

Serveur – avec Jetty

La classe qui reçoit les notifications de connexion :public class WSHandler extends WebSocketHandler {

@Overridepublic WebSocket doWebSocketConnect(HttpServletRequest request,

String protocol) {Client client = new Client();return client;

}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 300 / 423

. . . . . .

Communication client/serveur WebSocket WebSocket et Jetty

Serveur – avec Jetty

Le client :public class Client implements WebSocket.OnTextMessage {

private Connection connection;

public void onOpen(Connection connection) {this.connection = connection;

}

public void onMessage(String data) { /* ... */ }

public void onClose(int code, String msg) { /* ... */ }

public void send(String data) {try { connection.sendMessage(data); }catch (IOException e) { connection.close(); }

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 301 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – index.html<!DOCTYPE html><html><head><!-- jQuery et définition du style --><script src="index.js"></script>

</head><body>

<div id="c00" class="cell"></div><div id="c10" class="cell"></div><div id="c20" class="cell"></div><br><div id="c01" class="cell"></div><div id="c11" class="cell"></div><div id="c21" class="cell"></div><br><div id="c02" class="cell"></div><div id="c12" class="cell"></div><div id="c22" class="cell"></div><br><div id="message"></div>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 302 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – index.js

function onMessage(event) {var message = eval('('+event.data+')');eval(message.action)(message);

}

function onClick(x,y) { ws.send(JSON.stringify({ x : x, y : y })); }

function initCell(x,y) { $('#c'+x+y).click(function(){onClick(x,y);}); }

$(function() {ws = new WebSocket('ws://localhost:8080');ws.onopen = onOpen; ws.onmessage = onMessage; ws.onclose = onClose;for (var i = 0; i < 3; i++)

for (var j = 0; j < 3; j++)initCell(i,j);

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 303 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – index.js

function onOpen(event) { $("#message").text("Connexion etablie."); }function onClose(event) { $("#message").text("Connexion perdue."); }

function timeToPlay(message) { $("#message").text("À vous de jouer."); }function wait(message) { $("#message").text("À l'autre de jouer."); }function lost(message) { $("#message").text("Vous avez perdu."); }function win(message) { $("#message").text("Vous avez gagné."); }function draw(message) { $("#message").text("Match nul."); }

function play(message) {var x = message.x;var y = message.y;var color =(message.position == 0)?"red":"blue";$('#c'+x+y).css("background-color", color);

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 304 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveurpublic class Main {

public static void main(String[] args) throws Exception {Server httpServer = new Server(8080);

ResourceHandler resourceHandler = new ResourceHandler();resourceHandler.setWelcomeFiles(new String[] { "index.html" });resourceHandler.setResourceBase("www");

HandlerList handlers = new HandlerList();handlers.setHandlers(new Handler[] {

new WSHandler(),resourceHandler,new DefaultHandler() });

httpServer.setHandler(handlers);

httpServer.start();httpServer.join();

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 305 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur

public class WSHandler extends WebSocketHandler {

private MorpionServer server = new MorpionServer();

@Overridepublic WebSocket doWebSocketConnect(HttpServletRequest request,

String protocol) {Client client = new Client(server);return client;

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 306 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur

public class MorpionServer {Game currentGame = new Game();

public void addClient(Client client) {currentGame.addPlayer(client);if (currentGame.isFull())currentGame = new Game();

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 307 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur

public class Client implements WebSocket.OnTextMessage {private Connection connection;private MorpionServer server;private Game game; private int position;

public Client(MorpionServer server) { this.server = server; }

public void onOpen(Connection connection) {this.connection = connection; server.addClient(this);

}public void setGame(Game game, int position) {

this.game = game; this.position = position;}public void onClose(int code, String msg) {

if (game!=null) game.closeGame();}public void closeGame() { game = null; connection.close(); }

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 308 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveurpublic class Game {

private int currentPlayer;private List<Client> players;

public Game() { players = new ArrayList<>(); }

synchronized public void addPlayer(Client player) {player.setGame(this, players.size());players.add(player);if (players.size() == 2) startGame();

}

public boolean isFull() { return players.size() == 2; }

private void startGame() { /* ... */ }synchronized public void closeGame() {

for (Client player : players) player.closeGame();players.clear();

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 309 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur

public class ServerMessage {private String action;private int position;private int x, y;

public ServerMessage(int position, int x, int y) {action = "play"; this.position = position;this.x = x; this.y = y;

}

public ServerMessage(String action) { this.action = action; }}

public class ClientMessage {private int x, y;public int getX() { return x; }public int getY() { return y; }

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 310 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveurpublic class Client implements WebSocket.OnTextMessage {/* ... */public void onMessage(String json) {

if (game == null) return;Gson gson = new Gson();ClientMessage message = gson.fromJson(json, ClientMessage.class);game.onMessage(position, message);

}

public void send(ServerMessage message) {try {Gson gson = new Gson();connection.sendMessage(gson.toJson(message));

} catch (IOException e) {if (game!=null) game.closeGame();

}}/* ... */

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 311 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveurpublic class Game {

private int currentPlayer;private List<Client> players;private int[][] grid;private int emptyCells;/* ... */private void startGame() {

grid = new int[3][3]; emptyCells = 9;for (int i = 0; i < 3; i++) Arrays.fill(grid[i], -1);setCurrentPlayer(0);

}

private void setCurrentPlayer(int currentPlayer) {this.currentPlayer = currentPlayer;players.get(currentPlayer).send(new ServerMessage("timeToPlay"));players.get(1-currentPlayer).send(new ServerMessage("wait"));

}/* ... */

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 312 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveurpublic class Game {/* ... */synchronized public void onMessage(int pos, ClientMessage message){if (pos != currentPlayer) return;int x = message.getX(), y = message.getY();if (x < 0 || x >=3 || y < 0 || y >=3 || grid[x][y]!=-1) return;grid[x][y] = pos; emptyCells--;for (Client player : players)

player.send(new ServerMessage(pos, x, y));if (hasWon(pos)) {

players.get(pos).send(new ServerMessage("win"));players.get(1-pos).send(new ServerMessage("lost"));currentPlayer = -1;

} else if (emptyCells == 0) {for (Client player : players) player.send(new ServerMessage("draw"));

} else setCurrentPlayer(1 - currentPlayer);}/* ... */

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 313 / 423

. . . . . .

Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur

public class Game {/* ... */private boolean hasWon(int position) {

int j;for (int i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) if (grid[i][j] != position) break;if (j==3) return true;for (j = 0; j < 3; j++) if (grid[j][i] != position) break;if (j==3) return true;

}for (j = 0; j < 3; j++) if (grid[j][j] != position) break;if (j==3) return true;for (j = 0; j < 3; j++) if (grid[j][2-j] != position) break;if (j==3) return true;return false;

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 314 / 423

. . . . . .

Node.js Introduction

Node.js – IntroductionNode.js est une plateforme :

▶ permettant d’écrire des applications;▶ basée sur le langage JavaScript (et l’interpréteur de Chrome);▶ adaptée à la programmation de serveur Web;

Exemple :var http = require('http');http.createServer(function (req, res) {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello World\n');

}).listen(8888, '127.0.0.1');console.log('Server running at http://127.0.0.1:8888/');

Exécution :$ node example.jsServer running at http://127.0.0.1:8888/

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 315 / 423

. . . . . .

Node.js Les modules

Node.js – Les modulesPour organiser votre programme, vous pouvez définir des modules :

var tools = require('./tools.js');console.log( 'Aire = ' + tools.circleArea(4));

Le fichier tools.js :

var PI = Math.PI;

module.exports.circleArea = function (r) {return PI * r * r;

}

module.exports.rectangleArea = function (w, h) {return w*h;

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 316 / 423

. . . . . .

Node.js Les modules

Node.js – Installation de modulesPour télécharger et installer des modules, vous pouvez utiliser npm :

$ npm install expressnpm http GET https://registry.npmjs.org/express...

▶ La commande npm cherche un répertoire node_modules présent dansun répertoire se trouvant entre le répertoire courant et la racine;

▶ Le module est installé dans le répertoire node_modules trouvé;▶ Il est accessible dans tous les sous-répertoires du répertoire courant;▶ On a accès au module installé à l’aide la fonction require;

var express = require('express'); var app = express();app.get('/t.txt', function(req, res){ res.send('t'); });app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 317 / 423

. . . . . .

Node.js Quelques API

Node.js – Quelques APIUn certain nombre de fonctions sont fournies dans node.js :→ voir http://nodejs.org/api (je vous laisse parcourir les API)

Exemple avec STDIO :console.log('count: %d', count);console.info('info: %s', info);console.error('Erreur : Truc == null.');console.warn('Attention : variable Truc contient null.');

Exemple avec Net :var net = require('net');var server = net.createServer(function (socket) {console.log(socket.remoteAddress); socket.end("bye\n");

});server.listen(8888, function() { console.log('go !'); });

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 318 / 423

. . . . . .

Node.js Express

Node.js – Express – IntroductionExpress est un framework pour construire des applications Web en Node

Installation :> npm install expressnpm http GET https://registry.npmjs.org/express...

Création d’une application :

var express = require('express');var app = express();

Après avoir configuré l’application, on commence à écouter sur un port :

app.listen(8080);console.log('Nous écoutons sur le port 8080');

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 319 / 423

. . . . . .

Node.js Express

Node.js – Express – Répondre à une demande

Vous pouvez répondre à des requêtes par des callbacks :

var express = require('express'); var app = express();

var count = 0;

app.get('/count', function(req, res) {res.send(""+count);count++;

});

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 320 / 423

. . . . . .

Node.js Express

Node.js – Express – Accès aux paramètresVous pouvez également accéder aux paramètres de la requête HTTP :

var express = require('express'); var app = express();

var count = 0;

/* ... */

app.get('/set', function(req, res, next) {var value = req.query['value'];if (!value) return next(new Error("value required !"));count = parseInt(value);res.send("ok");

});

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 321 / 423

. . . . . .

Node.js Express

Node.js – Express – Contenus statiques

Pour distribuer le contenu d’un répertoire :

var express = require('express');var app = express();app.use(express.static(__dirname + '/public'));app.use('/static', express.static(__dirname + '/static'));app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 322 / 423

. . . . . .

Node.js Express

Node.js – Express – Les sessions

Utilisation des sessions :var express = require('express'); var app = express();app.use(express.cookieParser('zhizehgiz'));app.use(express.session());

app.get('/', function(req, res){if (req.session.count) { req.session.count++; } else {

req.session.count = 1;}res.send(""+req.session.count);

});

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 323 / 423

. . . . . .

Node.js Express

Node.js – Express – Les paramètres

Les paramètres :

var express = require('express');var app = express();

var users = [{name:"joe",age:21},{name:"bob",age:22}];

app.get('/user/:user', function(req, res, next){var user = users[req.params.user];if (!user) return next(new Error("bad user id !"));res.writeHead(200, {'Content-Type': 'application/json'});res.send(JSON.stringify(user));

});

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 324 / 423

. . . . . .

Node.js Express

Node.js – Express – Les sequencesLes sequences :

var express = require('express'); var app = express();app.use(express.cookieParser('zhizehgiz'));app.use(express.session());

app.get('/auth', function(req, res, next) {if (req.query["password"]=="toto")

req.session.auth = true;res.send("ok");

});function restrict(req, res, next) {

if (!req.session.auth) next(new Error("Unauthorized"));else next();

}/* ... */

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 325 / 423

. . . . . .

Node.js Express

Node.js – Express – Les sequencesLes sequences (suite) :

/* ... */

app.get('/auth', function(req, res, next) { /* ... */ });function restrict(req, res, next) { /* ... */ }

app.get('/t', restrict, function(req, res, next) {res.send("t");

});

app.get('/h', restrict, function(req, res, next) {res.send("h");

});

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 326 / 423

. . . . . .

Node.js Express

Node.js – Express – Templates avec ejsIl est possible d’utiliser un langage proche de PHP pour générer les pages :

var express = require('express');var app = express();app.engine('.html', require('ejs').__express);app.set('views', __dirname + '/views');app.set('view engine', 'html');

var users = [{name:"joe",age:21},{name:"bob",age:22}];app.get('/', function(req, res){res.render('users', {

users: users,});

});

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 327 / 423

. . . . . .

Node.js Express

Node.js – Express – Templates avec ejsLe fichier users.html :<!doctype html><html><head><title>Example</title>

</head><body>Users :<ul>

<% for (i in users) { %><li><%= users[i].name %> : <%= users[i].age %></li><% } %>

</ul></body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 328 / 423

. . . . . .

Node.js Express

Node.js – Express – Templates avec Jade

Il est possible d’utiliser un langage proche de PHP pour générer les pages :

var express = require('express');var app = express();

app.set('views', __dirname + '/views');app.set('view engine', 'jade');

var users = [{name:"joe",age:21},{name:"bob",age:22}];

app.get('/', function(req, res){res.render('users', { users: users, }); });

app.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 329 / 423

. . . . . .

Node.js Express

Node.js – Express – Templates avec Jade

Le fichier users.html :!!! 5htmlhead

title Examplebody Users :

ulfor user in usersli #{user.name} : #{user.age}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 330 / 423

. . . . . .

Node.js MySQL

Node.js – MySQL

var mysql = require('mysql');

var connection = mysql.createConnection({ host : 'localhost', user : 'username',password : 'password', database : 'database' });

connection.connect();

var query = 'SELECT * FROM users';connection.query(query, function(err, rows) {

if (err) throw err;for (var i in rows) console.log(rows[i].name

+" "+rows[i].age);});

connection.end();

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 331 / 423

. . . . . .

Node.js MySQL

Node.js – MySQL

var mysql = require('mysql');

var connection = mysql.createConnection(/* ... */);connection.connect();

var id = 3;var query = 'SELECT * FROM users WHERE id = ?';connection.query(query, [id], function(err, rows) {

if (err) throw err;for (var i in rows) console.log(rows[i].name

+" "+rows[i].age);});

connection.end();

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 332 / 423

. . . . . .

Node.js Socket.IO Introduction

Node.js – Socket.IOSocket.IO est un module qui permet de mettre en place (ou de simuler)une connexion bidirectionnelle entre un client et un serveur.

Techniques utilisées (en fonction de la disponibilité):▶ WebSocket▶ Technologie Flash▶ AJAX long polling▶ AJAX multipart streaming▶ Forever Iframe▶ JSONP Polling

Navigateurs supportés :▶ Internet Explorer 5.5+, Safari 3+, Google Chrome 4+, Firefox 3+,

Opera 10.61+, iPhone Safari, iPad Safari, Android WebKit, WebOsWebKit.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 333 / 423

. . . . . .

Node.js Socket.IO Introduction

Node.js – Socket.IO

Association de WebSocket et de Express :

var app = require('express')();var server = require('http').createServer(app);var io = require('socket.io').listen(server);

app.get('/', function (req, res) {res.sendfile(__dirname + '/client.html');

});

/* Configuration du serveur */

server.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 334 / 423

. . . . . .

Node.js Socket.IO Le serveur

Node.js – Socket.IO – Serveur – Notifications

Notification de la connexion d’un nouveau client :io.sockets.on('connection', function (socket) {/* socket représente la connexion entre

le client et le serveur. */});

Notification de la déconnexion d’un client :socket.on('disconnect', function () { /* ... */ });

Notification de la réception d’un message :

socket.on('msgName', function(data) { /* ... */ });

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 335 / 423

. . . . . .

Node.js Socket.IO Le serveur

Node.js – Socket.IO – Serveur – Messages

Envoyer un message via un socket :

socket.emit('msgName', data);

Envoyer un message à tous les autres sockets (à l’exception de ce socket) :

socket.broadcast.emit('msgName', data);

Envoyer un message à tous les sockets :

io.sockets.emit('msgName', data);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 336 / 423

. . . . . .

Node.js Socket.IO Le client

Node.js – Socket.IO – Client

Ajout du script :

<script src="/socket.io/socket.io.js"></script>

Connexion :var socket = io.connect('http://localhost:8080');

Envoyer un message au serveur :

socket.emit('msgName', data);

Écouter un type de message provenant du serveur :

socket.on('msgName', function (data) { /* ... */ });

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 337 / 423

. . . . . .

Node.js Socket.IO Premier exemple

Node.js – Socket.IO – Premier exemple

Contenu du fichier index.html :<!doctype html><html>

<head><script src="/socket.io/socket.io.js"></script><script src="jquery.min.js"></script><script src="index.js"></script>

</head><body>

<div id="time"></div><input id="format"></input><button id="changeFormat">Changer le format</button>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 338 / 423

. . . . . .

Node.js Socket.IO Premier exemple

Node.js – Socket.IO – Premier exemple

Contenu du fichier index.js :

$(document).ready(function() {var socket = io.connect('http://localhost:8080');

socket.on('time', function (data) {$("#time").text(data.time);

});

$("#changeFormat").click(function() {socket.emit("format", { format : $("#format").val() });

});});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 339 / 423

. . . . . .

Node.js Socket.IO Premier exemple

Node.js – Socket.IO – Premier exemple

Code du serveur :var express = require('express');var app = express();var server = require('http').createServer(app);var io = require('socket.io').listen(server);

app.use('/', express.static(__dirname + '/static'));

/* Initialisation de la connexion */

server.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 340 / 423

. . . . . .

Node.js Socket.IO Premier exemple

Node.js – Socket.IO – Premier exempleInitialisation de la connexion :var dateFormat = require('dateformat');var format = "h:MM:ss";

io.sockets.on('connection', function (socket) {setInterval(sendTime, 1000, socket);socket.on('format', function (data) {

format = data.format;});

});

function sendTime(socket) {var now = new Date();socket.emit('time', { time : dateFormat(now, format) });

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 341 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Client

<!DOCTYPE html><html><head>

<script src="jquery.min.js"></script><script src="/socket.io/socket.io.js"></script><script src="index.js"></script><style><!-- style --></style>

</head><body>

<div id="c00" class="cell"></div><!-- ... --><div id="c22" class="cell"></div><br><div id="message" class="message"></div><br/>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 342 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Client

var socket = io.connect('http://localhost:8080');

function play(data) {var x = data.x;var y = data.y;var color =(data.position == 0)?"red":"blue";$('#c'+x+y).css("background-color", color);

}

function onClick(x,y) { socket.emit("play", {x:x,y:y}); }

function initCell(x,y) {$('#c'+x+y).click(function() { onClick(x,y); });

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 343 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Client

$(function() {socket.on('play', play);

socket.on('timeToPlay', function () {$("#message").text("À vous de jouer.");

});socket.on('wait', function () { /* ... */ });socket.on('lost', function () { /* ... */ });socket.on('win', function () { /* ... */ });socket.on('draw', function () { /* ... */ });

for (var i = 0; i < 3; i++)for (var j = 0; j < 3; j++)initCell(i,j);

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 344 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

var express = require('express'); var app = express();var server = require('http').createServer(app);var io = require('socket.io').listen(server);var Game = require('./game');var Player = require('./player');

app.use(express.static(__dirname+'/www'));

var currentGame = new Game();io.sockets.on('connection', function (socket) {currentGame.addPlayer(new Player(socket));if (currentGame.isFull()) currentGame = new Game();

});

server.listen(8080);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 345 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

var Game = function() {this.players = [];this.activePosition = -1;/* ... */

}

Game.prototype = {isFull : function() { return this.players.length == 2; },

addPlayer : function(player) {player.setGame(this, this.players.length);this.players.push(player);if (this.isFull()) this.startGame();

}, /* ... */}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 346 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

var Player = function(socket) {this.socket = socket;this.game = null;this.position = 0;

}

Player.prototype = {sendMessage : function(msg, data) {

this.socket.emit(msg, data);},

setGame : function(game, position) {/* ... */

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 347 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

var Player = function(socket) { /* ... */ }

Player.prototype = {/* ... */setGame : function(game, position) {

this.game = game;this.position = position;this.socket.on('play', function(data) {game.play(position, data.x, data.y);

});this.socket.on('disconnect', function() {game.giveUp(position);

});}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 348 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveurvar Game = function() {/* ... */this.initGrid();

}

Game.prototype = {isFull : function() { /* ... */ },addPlayer : function(player) { /* ... */ },

initGrid : function() {this.nbEmptyCells = 9;this.grid = [];for (var x = 0; x < 3; x++) {

this.grid[x] = [];for (var y = 0; y < 3; y++)

this.grid[x][y] = -1;}

}, /* ... */}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 349 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

Game.prototype = {isFull : function() { /* ... */ },addPlayer : function(player) { /* ... */ },initGrid : function() { / * ... */ },

setActivePosition : function(position) {this.activePosition = position;this.players[position].sendMessage("timeToPlay");this.players[1 - position].sendMessage("wait");

},

startGame : function() {this.setActivePosition(0);

}, /* ... */}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 350 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

Game.prototype = {/* isFull, addPlayer, initGrid, setActivePosition */

play : function(position, x, y) {if (this.activePosition!=position) return;if (this.grid[x][y]!=-1) return;this.grid[x][y] = position;this.nbEmptyCells--;

for (var p = 0; p < 2; p++)this.players[p].sendMessage("play",

{ position : position, x : x, y : y });

if (this.hasWin(position)) this.endGameWithAVictory(position);else if (this.nbEmptyCells==0) this.endGameInADraw(position);else this.setActivePosition(1 - this.activePosition);

}, /* ... */}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 351 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – ServeurGame.prototype = {/* isFull, addPlayer, initGrid, setActivePosition, play */endGameInADraw : function() {

this.players[0].sendMessage("draw");this.players[1].sendMessage("draw");this.activePosition = -1;

},endGameWithAVictory : function(position) {

this.players[position].sendMessage("win");this.players[1-position].sendMessage("lost");this.activePosition = -1;

},giveUp : function(position) {

if (this.activePosition!=-1) {this.players[1-position].sendMessage("win");this.activePosition = -1;

} this.players = [];}, /* ... */

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 352 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

Game.prototype = {/* isFull, addPlayer, initGrid, setActivePosition, play... */

hasWin : function(pos) {for (var i = 0; i < 3; i++) {

var ok1 = true, ok2 = true;for (var j = 0; j < 3; j++) ok1 = ok1 && (this.grid[i][j]==pos);for (var j = 0; j < 3; j++) ok2 = ok2 && (this.grid[j][i]==pos);if (ok1 || ok2) return true;

}var ok1 = true, ok2 = true;for (var i = 0; i < 3; i++) ok1 = ok1 && (this.grid[i][i]==pos);for (var i = 0; i < 3; i++) ok2 = ok2 && (this.grid[i][2-i]==pos);return ok1 || ok2;

}}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 353 / 423

. . . . . .

Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur

Organisation du programme du serveur :▶ trois fichiers : main.js, game.js, player.js.

Exportation :

var Player = function(socket) { /* ... */}

Player.prototype = {setGame : function(game, position) { /* ... */ },sendMessage : function(msg, data) { /* ... */ }

}

module.exports = Player;

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 354 / 423

. . . . . .

AngularJS Introduction

IntroductionAngularJS :

▶ simplifie l’écriture des vues dynamiques d’une application Web;▶ est un outil écrit en JavaScript par Google;▶ étend l’expressivité de HTML;

Exemple de page dynamique utilisant AngularJS :

<!doctype html><html ng-app>

<head><script src="angular.min.js"></script></head><body>

<input type="text" ng-model="name"><h1>Bonjour {{name}}!</h1>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 355 / 423

. . . . . .

AngularJS Introduction

Introduction

Un deuxième exemple de page dynamique :

<!doctype html><html ng-app>

<head><script src="angular.min.js"></script></head><body>

<p ng-init=" nom='Bob' ">Bonjour {{nom}}!</p></body>

</html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 356 / 423

. . . . . .

AngularJS Contrôleurs

Contrôleurs et Data Binding▶ Data Binding : les vues sont automatiquement modifiées lors d’un

changement du modèle par un contrôleur.▶ Les contrôleurs sont attachés aux éléments du DOM et font évoluer

le modèle en fonction des actions de l’utilisateurs ou d’événements.

<!doctype html><html ng-app>

<!-- ... --><body>

<div ng-controller="MyCtrl"><input type="text" ng-model="src"><button ng-click="copy()">Copier</button><h1>{{dst}}</h1>

</div></body>

</html>Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 357 / 423

. . . . . .

AngularJS Contrôleurs

Contrôleurs et Data Binding

▶ Data Binding : les vues sont automatiquement modifiées lors d’unchangement du modèle par un contrôleur.

▶ Les contrôleurs sont attachés aux éléments du DOM et font évoluerle modèle en fonction des actions de l’utilisateurs ou d’événements.

La fonction qui permet de construire une instance du contrôleur :function MyCtrl($scope) {

$scope.copy = function() {$scope.dst = $scope.src;

}}

La variable $scope référence un objet qui correspond à la partie dumodèle attachée à l’élément du DOM contrôle.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 358 / 423

. . . . . .

AngularJS Contrôleurs

Scopes et RootScopeLa variable $scopeScope contient l’intégralité du modèle alors que lavariable $scope contient uniquement la partie du modèle attachée àl’élément du DOM :<body>

<div ng-controller="MyCtrl"><input type="text" ng-model="src"><button ng-click="copy()">Copier</button>

</div><h1>{{dst}}</h1>

</body>

function MyCtrl($scope, $rootScope) {$scope.copy = function() { $rootScope.dst = $scope.src; }

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 359 / 423

. . . . . .

AngularJS Contrôleurs

Scopes et RootScope

Portée des scopes :

<body><div ng-controller="MyCtrl">

{{ dst }}</div>{{ dst }}

</body>

function MyCtrl($scope, $rootScope) {$rootScope.dst = "rootScope";$scope.dst = "scope";

}

Chaque contrôleur peut donc avoir une partie du modèle comme contexte.Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 360 / 423

. . . . . .

AngularJS Template

Template – ng-repeat

<body ng-controller="ListCtrl"><input ng-model="item"><button ng-click="add()">add</button><ul><li ng-repeat="e in items">

{{ e }}</li></ul>

</body>

function ListCtrl($scope) {$scope.items = [];$scope.add = function() {

$scope.items.push($scope.item);}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 361 / 423

. . . . . .

AngularJS Template

Template – ng-repeat

<body ng-controller="ListCtrl"><input ng-model="item"><button ng-click="add()">add</button><ul><li ng-repeat="e in items">

{{ e }}</li></ul>

</body>

function ListCtrl($scope) {$scope.items = [];$scope.add = function() {

$scope.items.push($scope.item);}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 362 / 423

. . . . . .

AngularJS Template

Template – visibilité

Il est possible de masquer ou d’afficher certains éléments :

<body><input type="checkbox" ng-model="checked"><span ng-show="checked">coché</span><span ng-hide="checked">non coché</span>

<input type="text" ng-model="data"><ul ng-switch on="data">

<li ng-switch-when="toto">data==toto</li><li ng-switch-when="truc">data==truc</li><li ng-switch-default>data!=toto and data!=truc</li>

</ul></body>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 363 / 423

. . . . . .

AngularJS Template

Template – style

Il est possible de modifier la classe et le style des éléments :

<body ng-init="style={color:'green'}"><button ng-click="style={color:'red'}">Rouge</button><button ng-click="style={color:'black'}">Noir</button><span ng-style="style">zadza</span><pre>style={{style}}</pre>

</body>

<body ng-init="cls='green'"><button ng-click="cls='red'">Rouge</button><button ng-click="cls='black'">Noir</button><span ng-class="cls">zadza</span>

</body>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 364 / 423

. . . . . .

AngularJS Template

Template – formulaire

<form name="myForm"><input name="input" type="text" name="input"

ng-model="text" ng-pattern="/^[a-z]{3,6}$/" required><button ng-disabled="!myForm.$valid" type="submit">

Envoyer</button><span class="error"

ng-show="myForm.input.$error.required">Nécessaire

</span><span class="error"

ng-show="myForm.input.$error.pattern">3 à 6 lettres miniscules

</span></form>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 365 / 423

. . . . . .

AngularJS Template

Template – événements

<body ng-controller="MyCtrl"><div ng-click="onEvent('click')">click</div><div ng-mousedown="onEvent('down')">down</div><div ng-mouseup="onEvent('up')">up</div><div ng-mouseenter="onEvent('enter')">enter</div><div ng-mouseleave="onEvent('leave')">leave</div><div ng-mouseover="onEvent('over')">over</div><input ng-model="data" ng-change="onEvent('change')">

</body>

function MyCtrl($scope) {$scope.onEvent = function(s) { console.log(s); }

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 366 / 423

. . . . . .

AngularJS Template

Template – les liens et les images

<body ng-controller="MyCtrl"><div ng-repeat="item in items">

<a ng-href="{{item.img}}"><img ng-src="{{item.rimg}}">

</a></div>

</body>

function MyCtrl($scope) {$scope.items = [

{img : "a.jpg", rimg : "ra.jpg" },{img : "b.jpg", rimg : "rb.jpg" }

];}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 367 / 423

. . . . . .

AngularJS Template

Template – utilisation des filtres

<body ng-controller="ListCtrl"><input ng-model="item"><button ng-click="add()">add</button><input ng-model="query"><ul><li ng-repeat="e in items | filter:query">

{{ e }}</li></ul>

</body>

function ListCtrl($scope) {$scope.items = [];$scope.add = function() {

$scope.items.push($scope.item);}

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 368 / 423

. . . . . .

AngularJS Modules

Les modules

▶ La façon de construire l’application est spécifiée par des modules.▶ Dans les modules, on spécifie ce qui est partagé dans l’application.▶ Un module peut dépendre d’autres modules.▶ L’application a un module principal.

Dans le code HTML :<!doctype html><html ng-app="myApp"><!-- ... --></html>

Côté JavaScript :

var myApp = angular.module('myApp', []);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 369 / 423

. . . . . .

AngularJS Modules

Les modulesUn exemple avec la définition d’un nouveau filtre :

var myApp = angular.module('myApp', []);myApp.filter('bracket', function() {

return function(text) { return '['+text+']'; }});

Utilisation du filtre côté HTML :<!doctype html><html ng-app="myApp">

<head><!-- ... --></head><body>

{{ 'exemple' | bracket }} <!-- [exemple] --></body>

</html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 370 / 423

. . . . . .

AngularJS Modules

Les modules

Trois sortes d’éléments peuvent être définis dans un module :▶ Un service (un objet partageable);▶ Une directive (nouvel élément côté HTML);▶ Un filtre (voir le transparent précédent).

Il est recommandé de séparer les différents éléments :

var myAppService = angular.module('myApp.service', []);var myAppDirective = angular.module('myApp.directive', []);var myAppFilter = angular.module('myApp.filter', []);

var myApp = angular.module('myApp', ['myApp.service','myApp.directive','myApp.filter']);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 371 / 423

. . . . . .

AngularJS Modules

Les modules

Il est possible d’exécuter du code au lancement de l’application :

var myApp = angular.module('myApp', []);myApp.run(function($rootScope) {$rootScope.message = "Mon message";

});

<!doctype html><html ng-app="myApp">

<head><!-- ... --></head><body>

{{ message }} <!-- devient "Mon message" --></body>

</html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 372 / 423

. . . . . .

AngularJS Services

Les servicesUn service est un objet utilisable par d’autres objets de l’application :

var myAppService = angular.module('myApp.service', []);var myApp = angular.module('myApp', ['myApp.service']);myAppService.factory('messages', function() {

return {callbacks : [],addMessage : function(msg) {

for (var i = 0; i < this.callbacks.length; i++)this.callbacks[i](msg);

},addCallback : function(callback) {

this.callbacks.push(callback);}

}});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 373 / 423

. . . . . .

AngularJS Services

Les services

Code du contrôleur pour poster de nouveau message :

function AddMsgCtrl($scope, messages /* injection */) {$scope.addMessage = function() {

messages.addMessage($scope.msg);}

}

Code HTML associé à ce contrôleur :<div ng-controller="AddMsgCtrl">

<input type="text" ng-model="msg"><button ng-click="addMessage()">Add</button>

</div>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 374 / 423

. . . . . .

AngularJS Services

Les services

Code d’un contrôleur qui affiche le dernier message :

function MsgViewer($scope, messages) {messages.addCallback(function(msg) {

$scope.msg = msg;});

}

Code HTML associé à ce contrôleur :<div ng-controller="MsgViewer">{{ msg }}

</div>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 375 / 423

. . . . . .

AngularJS Services

Les servicesDéfinition de Counter (un service qui compte des messages) :

function Counter() {this.count = 0;this.callbacks = [];

}

Counter.prototype.notify = function(msg) {this.count++;for (var i = 0; i < this.callbacks.length; i++)

this.callbacks[i](this.count);}

Counter.prototype.addCallback = function(callback) {this.callbacks.push(callback);

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 376 / 423

. . . . . .

AngularJS Services

Les services

Ajout d’une fabrique pour créer le service avec l’aide d’un autre service :

myAppService.factory('counter', function(messages) {var counter = new Counter();messages.addCallback(function(msg) {

counter.notify(msg);});return counter;

});

Le service messages est injecté dans la fabrique du service counter.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 377 / 423

. . . . . .

AngularJS Services

Les services

Utilisation du service counter par un contrôleur :

function CountViewer($scope, counter) {counter.addCallback(function(count) {

$scope.count = count;});

}

Code HTML qui utilise ce contrôleur :

<div ng-controller="CountViewer">{{ count }}

</div>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 378 / 423

. . . . . .

AngularJS Services

Les servicesServices et événements extérieurs à AngularJS :

▶ Les modifications du modèle engendrent une modification du DOMuniquement à la fin d’un évenements AngularJS.

▶ Donc, il n’y aura pas de modification du DOM à la fin d’untraitement associé à un événement extérieur à AngularJS.

▶ La méthode $apply(func) permet d’exécuter une fonction depuisl’extérieur de AngularJS.

Pseudo-code de la méthode $apply() :function $apply(expr) {

try {return $eval(expr);

} catch (e) { $exceptionHandler(e); }finally { $root.$digest(); }

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 379 / 423

. . . . . .

AngularJS Services

Les services

app.factory('socket', function ($rootScope) {var socket = io.connect('ws://localhost:8080');return {

on: function (eventName, callback) {socket.on(eventName, function () {

var args = arguments;$rootScope.$apply(function () {

callback.apply(socket, args);});

});},/* méthode emit du transparent suivant */

};});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 380 / 423

. . . . . .

AngularJS Services

Les services

app.factory('socket', function ($rootScope) {var socket = io.connect('ws://localhost:8080');return {

/* méthode on du transparent précédent */emit: function (eventName, data, callback) {socket.emit(eventName, data, function () {

var args = arguments;$rootScope.$apply(function () {

if (callback) { callback.apply(socket, args); }});

})}

};});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 381 / 423

. . . . . .

AngularJS Services

Les services

app.factory('socket', function ($rootScope) {var socket = io.connect('ws://localhost:8080');return {

/* méthode on du transparent précédent */emit: function (eventName, data, callback) {socket.emit(eventName, data, function () {

var args = arguments;$rootScope.$apply(function () {

if (callback) { callback.apply(socket, args); }});

})}

};});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 382 / 423

. . . . . .

AngularJS Injection

Injection

Par inférence sur le nom des paramètres :

function MyController($scope, counter /* injection */) {/* ... */}

Cette méthode d’injection ne résiste pas à la minification/obfuscation ducode JavaScript. Par conséquent, il est préférable de faire :

function MyController(scope, counter) {/* ... */}

MyController.$inject = ['$scope', 'counter'];

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 383 / 423

. . . . . .

AngularJS Injection

InjectionPour les fabriques, il est possible de faire :

function counterFactory(messages) {/* ... */

}counterFactory.$inject = ['messages'];

myAppService.factory('counter', counterFactory);

ou plus simplement avec la notation “en ligne” :

myAppService.factory('counter', ['messages',function(messages) {

/* ... */}

]);

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 384 / 423

. . . . . .

AngularJS Routes

RoutesObjectif :

▶ afficher des vues en fonction de l’URL présente dans la barred’adresse du navigateur de façon à avoir un déplacement agréabledans le site Web (avec gestion de l’historique et des paramètres).

Solution :▶ Avec HTML5, il est possible d’interagir avec la barre d’adresse du

navigateur (URL, historique, etc.). Le service $location deAngularJS permet d’avoir accès à ces fonctionnalités.

▶ Le service $route de AngularJS observe l’URL (grâce au service$location) et modifie le contenu de la page en fonction de l’URL.

▶ Les routes sont définies via l’API $routeProvider.▶ Les vues sont insérées côté HTML à l’aide de ng-view.▶ Les paramètres sont accessibles via le service $routeParams.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 385 / 423

. . . . . .

AngularJS Routes

Routes

Soit le tableau suivant :var users = [{ id : 0, name : "Lucie", age : 21},{ id : 1, name : "Bob", age : 22},{ id : 2, name : "Christine", age : 30},{ id : 3, name : "Arthur", age : 24},

];

#/users :▶ Lucie▶ Bob▶ Christine▶ Arthur

#/user/1 :

Bob

age : 22

#/user/2 :

Christine

age : 30

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 386 / 423

. . . . . .

AngularJS Routes

Routes

Pour configurer les routes, on configure le service $routeProvider :

angular.module('myapp', []).config(function($routeProvider) {

$routeProvider.when('/users', {templateUrl: 'users.html',controller: UserListCtrl

}).when('/user/:id', {

templateUrl: 'user.html',controller: UserCtrl

}).otherwise({redirectTo: '/users'});

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 387 / 423

. . . . . .

AngularJS Routes

Routes

Le fichier users.html :<ul>

<li ng-repeat="user in users"><a href="#/user/{{user.id}}">{{user.name}}</a>

</li></ul>

Le contrôleur UserListCtrl :function UserListCtrl($scope) {$scope.users = users;

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 388 / 423

. . . . . .

AngularJS Routes

Routes

Le fichier userlist.html :<b>{{user.name}}</b><ul>

<li>age : {{user.age}}</li></ul><a href="#/users">Liste des utilisateurs</a>

Le contrôleur UserCtrl :function UserCtrl($scope, $routeParams) {/* TODO : tester la valeur du paramètre */$scope.user = users[$routeParams.id];

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 389 / 423

. . . . . .

AngularJS Directives

DirectivesLes directives permettent de créer de “nouveaux éléments” HTML :angular.module('myapp', []).directive('user', function(){

return {restrict: 'E',replace: true,scope: { src : '=src' }, /* ou src : '=' */template: '<span>{{src.name}} :

{{src.age}}</span>'}});

Ensuite, il est possible d’utiliser le nouveau composant dans le HTML :<body ng-init="bob = {name:'bob', age:22}">

<user src="bob" /></body>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 390 / 423

. . . . . .

AngularJS Directives

Directives

Il est possible d’isoler le template dans un autre fichier :

var myapp = angular.module('myapp', [])myapp.directive('user', function(){

return {restrict: 'E',replace: true,scope: { src : '=src' },template: 'user.html',

}});

Contenu du fichier user.html :<span>{{src.name}} : {{src.age}}</span>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 391 / 423

. . . . . .

AngularJS Directives

Directives

Il est possible d’associer un contrôleur à l’élément :

myapp.directive('userform', function(){return {restrict: 'E',replace: true,scope: { userList : '=' }, /* attr. user-list */templateUrl: 'userform.html',controller : 'UserFormCtrl'

}});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 392 / 423

. . . . . .

AngularJS Directives

Directives

Le code du contrôleur UserFormCtrl :function UserFormCtrl($scope) {$scope.add = function(user) {

$scope.userList.push(user);}

}

Le contenu du fichier userform.html :<div>

<input type="text" ng-model="user.name" /><input type="text" ng-model="user.age" /><button ng-click="add(user);">ajouter</button>

</div>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 393 / 423

. . . . . .

AngularJS Directives

DirectivesUtilisation des balises précédentes :

<body ng-controller="MainCtrl"><ul>

<li ng-repeat="user in users"><user src="user" />

</li></ul><userform user-list="users" />

</body>

Code du contrôleur GlobalCtrl :function MainCtrl($scope) {$scope.users = [{ name : "Lucie", age : 21}, /*...$*/];

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 394 / 423

. . . . . .

AngularJS Directives

DirectivesSupposons que la directive suivante soit définie :myapp.directive('message', function(){

return {restrict: 'E',replace: true,scope: { nickname : '=' },templateUrl: 'message.html',

}});

Nous souhaitons utiliser la directive de la façon suivante :<message nickname="bob">Bonjour.</message>

De façon à obtenir :<b>bob</b> : Bonjour.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 395 / 423

. . . . . .

AngularJS Directives

Pour ce faire, il suffit de définir le template de la façon suivante :

<span><b>{{nickname}}</b> :<span ng-transclude></span>

</span>

Le mot-clé ng-transclude permet de copier le contenu présent dans labalise dans la balise désignée à l’aide du mot-clé.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 396 / 423

. . . . . .

AngularJS Directives

DirectivesRéalisation d’une grille de morpion :

<body ng-controller="MainCtrl"><grid grid="grid" on-click="play"></grid>

</body>

Avec le style suivant :

.cell {display :inline-block;height:30px; width:30px;border: 1px solid gray;

}.red { background-color:red; }.blue { background-color:blue; }.while { background-color:white; }

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 397 / 423

. . . . . .

AngularJS Directives

Directives

Définition de la directive :var myapp = angular.module('myapp', []);myapp.directive('grid', function(){

return {restrict: 'E',replace: true,scope: { grid : '=',

onClick : '='},

templateUrl: 'grid.html',}

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 398 / 423

. . . . . .

AngularJS Directives

DirectivesDéfinition du contrôleur :function MainCtrl($scope) {$scope.grid = [];for (var i = 0; i < 3; i++) {

$scope.grid[i] = [];for (var j = 0; j < 3; j++)$scope.grid[i][j] = 'while';

}$scope.play = function(x,y) { $scope.grid[x][y]='red'; }

}

Rappel de l’utilisation du contrôleur :<body ng-controller="MainCtrl">

<grid grid="grid" on-click="play"></grid></body>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 399 / 423

. . . . . .

AngularJS Directives

Directives

Le template grid.html :

<div><div ng-repeat="l in [0,1,2]">

<div class="cell"ng-repeat="c in [0,1,2]"ng-class="grid[l][c]"ng-click="onClick(l,c)">

</div></div>

</div>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 400 / 423

. . . . . .

AngularJS Directives

DirectivesSi nous avons le code HTML suivant :<body ng-controller="MainCtrl">

<grid grid="grid" on-click="playRed"></grid><br><br><grid grid="grid" on-click="playBlue"></grid>

</body>

Que se passe-t-il avec le contrôleur suivant ?

function MainCtrl($scope) {/* TODO : initilisation de la grille. */$scope.playRed =

function(x,y) { $scope.grid[x][y]='red'; }$scope.playBlue =

function(x,y) { $scope.grid[x][y]='blue'; }}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 401 / 423

. . . . . .

AngularJS Directives

DirectivesNous souhaitons utiliser le code HTML suivant :<body ng-controller="MainCtrl">

<grid grid="grid" on-click="grid[x][y]='red'"></grid><grid grid="grid" on-click="grid[x][y]='blue'"></grid>

</body>

Avec le contrôleur suivant :function MainCtrl($scope) {$scope.grid = [];for (var i = 0; i < 3; i++) {

$scope.grid[i] = [];for (var j=0;j<3;j++) $scope.grid[i][j] = 'while';

}}

Pourquoi la directive donnée précédemment ne fonctionne plus ?Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 402 / 423

. . . . . .

AngularJS Directives

Directives

Modification de la directive :var myapp = angular.module('myapp', []);myapp.directive('grid', function(){

return {restrict: 'E',replace: true,scope: { grid : '=',

onClick : '&'},

templateUrl: 'grid.html',}

});

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 403 / 423

. . . . . .

AngularJS Directives

DirectivesModification du template grid.html :<div>

<div ng-repeat="l in [0,1,2]"><div class="cell"

ng-repeat="c in [0,1,2]"ng-class="grid[l][c]"ng-click="onClick({x:l, y:c})"></div>

</div></div>

Rappel de l’utilisation de la directive :<body ng-controller="MainCtrl">

<grid grid="grid" on-click="grid[x][y]='red'"></grid><grid grid="grid" on-click="grid[x][y]='blue'"></grid>

</body>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 404 / 423

. . . . . .

AngularJS Directives

DirectivesLes différentes façons d’insérer une directive :

E Element name: <my-directive></my-directive>A Attribute: <div my-directive="exp"> </div>C Class: <div class="my-directive: exp;"></div>M Comment: <!-- directive: my-directive exp -->

Modification de la directive :var myapp = angular.module('myapp', []);myapp.directive('grid', function(){

return { restrict: 'CA', /* ... */ }});

Utilisation :<div class="grid: grid" on-click="grid[x][y]='red'"></div><div grid="grid" on-click="grid[x][y]='blue'"></div>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 405 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Introduction

Objectif : Proposer un nouveau langage côté client (et serveur) quipermette le développement d’applications de grande taille.

Dart :▶ est un nouveau langage de programmation (de Google);▶ peut être compilé en JavaScript;▶ est un langage orienté objet (classe, interfaces, extension...);▶ permet de typer statiquement des variables;▶ propose un IDE (auto-completion, debug...);▶ dispose également une machine virtuelle (Dart VM);▶ permet un découpage en modules de l’application;▶ etc.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 406 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Introduction

Utilisation d’un script Dart dans du code HTML :

<!DOCTYPE html><html>

<head><!--***--></head><body>

<div id="text"></div><script type="application/dart" src="test.dart"></script><script src="packages/browser/dart.js"></script>

</body></html>

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 407 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Introduction

Utilisation d’un script Dart dans du code HTML :

import 'dart:html';

void main() {query("#text").text = "Truc";

}

Dans ce code, nous utilisons la librairie html pour interagir avec le DOM.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 408 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Introduction

Un autre exemple :import 'dart:html';

void main() {query("#text").text = "Truc";query("#text").onClick.listen(textClick);

}

void textClick(Event e) {String txt = query("#text").text;query("#text").text="["+txt+"]";

}

Notez que certaines variables sont typées statiquement.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 409 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objet

Il est possible de définir une classe et de créer une instance :

class Point {num x;num y;

Point(num x, num y) { this.x = x; this.y = y; }}

main() {var point = new Point(2, 4);point.x = 4;assert(point.x == 4);assert(point.y == 4);

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 410 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objetQuelques nouveautés pour faciliter le développement :

class Point {num x;num y;

Point(this.x, this.y);Point.alongXAxis(num x) : this(x, 0);Point.alongYAxis(num y) : this(0, y);Point.fromJson(Map<String,num> json) {

x = json['x'];y = json['y'];

}

String toString() => "(${x},${y})";}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 411 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objet

Utilisation de la classe décrite précédemment :

void main() {Point p1 = new Point(2,3);Point p2 = new Point.alongXAxis(2);Point p3 = new Point.alongYAxis(2);Point p4 = new Point.fromJson({"x":3, "y":6});query("#text").text = "${p1} ${p2} ${p3} ${p4}";

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 412 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objetIl est possible d’étendre une classe :

class Pixel extends Point {num r, g, b;Pixel(x, y, this.r, this.g, this.b) : super(x,y);String toString() => "((${super.toString()},"+

"${r},${g},${b})";}

Quel texte est placé dans la balise text :void main() {Pixel pixel = new Pixel(2,3,2.3,3.4,5.0);Point point = pixel;query("#text").text = "${pixel} ${point}";

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 413 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objet

Les interfaces implicites :

class Converter {String convert(String s) => s;

}

class UpperCaseConverter implements Converter {String convert(String s) => s.toUpperCase();

}

class LowerCaseConverter implements Converter {String convert(String s) => s.toLowerCase();

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 414 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objet

Utilisation des classes précédentes :

void main() {List<Converter> converters =

[new Converter(),new UpperCaseConverter(),new LowerCaseConverter()

];

String txt = "[ToTo]";query("#text").text =

converters.map((c) => c.convert(txt)).join(";");

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 415 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Programmation objet

Autres fonctionnalités :▶ possibilité de définir des getters et des setters;▶ classes abstraites;▶ classes “immutables” et mot-clé const;▶ types génériques;

Autres exemples :

var names = new List<String>();names.addAll(<String>['Bob', 'Arthur', 'Louis', 'Bob']);var nameSet = new Set<String>.from(names);query("#text").text = nameSet.join(";");

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 416 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Les librairies

dart:core Numbers, Collections, Strings, and Moredart:async Asynchronous Programmingdart:math Math and Randomdart:html Browser-Based Apps

dart:isolate Concurrency with Isolatesdart:io I/O for Command-Line Apps

dart:json Encoding and Decoding Objectsdart:uri Manipulating URIsdart:utf Strings and Unicode

dart:crypto Hash Codes and More

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 417 / 423

. . . . . .

Dart/TypeScript Dart

Dart – Les librairies

import 'dart:html';import 'dart:json' as json;

void main() {var jsonString = '''

[{ "name" : "bob", "age" : 22 },{ "name" : "arthur", "age": 45 },

]''';var persons = json.parse(jsonString);var list = persons.map(

(p) => "<li><b>${p["name"]}</b> : ${p["age"]}</li>");query("#text").innerHtml = "<ul>${list.join()}</ul>"; <!-- $ -->

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 418 / 423

. . . . . .

Dart/TypeScript TypeScript

TypeScript

Objectif : Proposer un nouveau langage côté client qui permette ledéveloppement d’applications de grande taille.

TypeScript :▶ est un nouveau langage de programmation (de Microsoft);▶ se compile en JavaScript (avec Node.js);▶ est un langage orienté objet (classe, interfaces, extension...);▶ permet de typer statiquement des variables;▶ propose un plugin pour Visual Studio;▶ propose des plugins pour d’autres éditeurs;▶ etc.

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 419 / 423

. . . . . .

Dart/TypeScript TypeScript

TypeScript

TypeScript est un langage orienté objet :

interface Converter {convert(s:string) : string;

}

class LowerCaseConverter implements Converter {convert(s:string) : string { return s.toLowerCase(); }

}

class UpperCaseConverter implements Converter {convert(s:string) : string { return s.toUpperCase(); }

}

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 420 / 423

. . . . . .

Dart/TypeScript TypeScript

TypeScript

Utilisation de l’interface et des classes précédentes :

var converters : Converter[] = [new LowerCaseConverter(),new UpperCaseConverter()

];

var r : string = "";for(var i =0; i < converters.length; i++)r+= converters[i].convert("[ToTo]");

document.body.innerHTML = r;

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 421 / 423

. . . . . .

Dart/TypeScript TypeScript

TypeScriptLe code TypeScript précédent compilé en JavaScript :

var SimpleConverter = (function () {function SimpleConverter() { }SimpleConverter.prototype.convert = function (s) {

return s;};return SimpleConverter;

})();var UpperCaseConverter = (function () {

function UpperCaseConverter() { }UpperCaseConverter.prototype.convert = function (s) {

return s.toUpperCase();};return UpperCaseConverter;

})();

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 422 / 423

. . . . . .

Dart/TypeScript TypeScript

TypeScript

Le code TypeScript précédent compilé en JavaScript :

var converters = [new SimpleConverter(),new UpperCaseConverter()

];var r = "";for(var i = 0; i < converters.length; i++) {

r += converters[i].convert("[ToTo]");}document.body.innerHTML = r;

Bertrand Estellon (AMU) Développement Web 2 April 26, 2013 423 / 423