Vous êtes sur la page 1sur 436

Développement Web 2

Bertrand Estellon

Aix-Marseille Université

April 1, 2014

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 1 / 436
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 1, 2014 2 / 436
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 1, 2014 3 / 436
PHP Bases du langage Introduction

Le Web “statique”

Protocole HTTP
1. Je veux toto.html

Client Serveur
2. Contenu de toto.html

Requête : Réponse :
GET /toto.html HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>page d’exemple.</P>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 4 / 436
PHP Bases du langage Introduction

Le Web “dynamique”

Protocole HTTP
1. Je veux toto.html

Client Serveur
2. Contenu de toto.html

Requête : Réponse :
GET /toto.html HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>page d’exemple.</P>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 5 / 436
PHP Bases du langage Introduction

Le Web “dynamique”

Protocole HTTP
1. Je veux toto.php

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

Requête : Réponse :
GET /toto.php?n1=10&n2=15 HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>Résultat .: .25.</P>
. . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 6 / 436
PHP Bases du langage Introduction

Le Web “dynamique”

Protocole HTTP
1. Je veux toto.php

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

Requête : Réponse :
POST /toto.php HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
n1=10&n2=15 Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>Résultat .: .25.</P>
. . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 7 / 436
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 1, 2014 8 / 436
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 1, 2014 9 / 436
PHP Bases du langage Introduction

Inclusion de fichiers

index.php : tete.inc.php :
<html> <?
<head> echo "Bienvenue<br>";
<title>Titre</title> ?>
</head>
<body>
<? corps.html :
require("tete.inc.php"); Corps du site<br>
include("corps.html");
require("pied.inc.php");
?> pied.inc.php :
</body>
</html> <?
echo date('d/M/Y');
Mais aussi : ?>
include_once et require_once
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 10 / 436
PHP Bases du langage Introduction

Commentaires

<html>
<head>
<title>Titre</title>
</head>
<body>
<?
echo "Bonjour"; // commentaire
echo "Salut"; /* commentaire
sur plusieurs lignes. */
echo "Coucou"; # commentaire
?>
<!-- commentaire -->
</body>
</html>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 11 / 436
PHP Bases du langage Instructions, opérations, variables

Instructions, opérations et fonctions

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

retourne 1

print
retourne 27

+ retourne 24

3 * retourne 4

6 strlen

"toto"
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 12 / 436
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 1, 2014 13 / 436
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 1, 2014 14 / 436
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

2. affecte la valeur 2 1. affecte la valeur 2


à la variable $a à la variable $b
et retourne la valeur 2 et retourne la valeur 2

$a = $b = 2

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 15 / 436
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 1, 2014 16 / 436
PHP Bases du langage Instructions, opérations, variables

Affectations de valeur
<?
$variable = 12;
$variable2 = "toto";
$variable2 = $variable;
$variable = 12.12+3;
?>

$variable $variable2

12 "toto"

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 17 / 436
PHP Bases du langage Instructions, opérations, variables

Affectations de valeur
<?
$variable = 12;
$variable2 = "toto";
$variable2 = $variable;
$variable = 12.12+3;
?>

$variable $variable2

12 12

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 18 / 436
PHP Bases du langage Instructions, opérations, variables

Affectations de valeur
<?
$variable = 12;
$variable2 = "toto";
$variable2 = $variable;
$variable = 12.12+3;
?>

$variable $variable2

15.12 12

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 19 / 436
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 variable


précédée du caractère '&' :
$var2 = &$var1;

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


variable $var1.

▶ Après l’affectation, la variable $var2 ne fait que référencer le


conteneur associé à la variable $var1.

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 20 / 436
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 1, 2014 21 / 436
PHP Bases du langage Instructions, opérations, variables

Affectations de référence
<?
$variable = 12;
$variable2 = &variable;
$variable2 = "toto";
$variable = 12.12;
?>

$variable $variable2

12

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 22 / 436
PHP Bases du langage Instructions, opérations, variables

Affectations de référence
<?
$variable = 12;
$variable2 = &variable;
$variable2 = "toto";
$variable = 12.12;
?>

$variable $variable2

"toto"

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 23 / 436
PHP Bases du langage Instructions, opérations, variables

Affectations de référence
<?
$variable = 12;
$variable2 = &variable;
$variable2 = "toto";
$variable = 12.12;
?>

$variable $variable2

12.12

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 24 / 436
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 1, 2014 25 / 436
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’une


variable $var :
▶ gettype($var) retourne une chaîne de caractères contenant le type
de 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 1, 2014 26 / 436
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 1, 2014 27 / 436
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 1, 2014 28 / 436
PHP Bases du langage Instructions, opérations, variables

Opérateurs numériques

Négation -$a Opposé de $a


Addition $a + $b Somme de $a et $b
Soustraction $a - $b Différence de $a et $b
Multiplication $a * $b Produit de $a et $b
Division $a / $b Quotient de $a et $b
Modulo $a % $b Reste de $a divisé par $b

Pre-incrémente ++$a Incrémente $a de 1, puis retourne $a


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

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 29 / 436
PHP Bases du langage Instructions, opérations, variables

Opérateurs logiques

et $a and $b TRUE si $a et $b valent TRUE


ou $a or $b TRUE si $a ou $b valent TRUE
ou exclusif $a xor $b TRUE si $a ou $b est égal TRUE
mais pas les deux en même temps
non !$a TRUE si $a n’est pas égal à TRUE
et $a && $b TRUE si $a et $b sont égaux TRUE
ou $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 1, 2014 30 / 436
PHP Bases du langage Instructions, opérations, variables

Opérateurs de comparaison

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


TRUE si $a et $b sont égaux
identique $a === $b
et ont le même type
différent $a != $b TRUE si $a est différent de $b
différent a <> b+ TRUE si $a est différent de $b
TRUE si $a et $b sont différents
non identique $a !== $b
ou n’ont pas le même type
plus petit $a < $b TRUE si $a est strictement plus petit que $b
plus grand $a > $b TRUE si $a est strictement plus grand que $b
inférieur ou égal $a <= $b TRUE si $a est plus petit ou égal à $b
supé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 1, 2014 31 / 436
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 1, 2014 32 / 436
PHP Bases du langage Instructions, opérations, variables

Opérateurs de commande

▶ L’opérateur ` (guillements obliques) permet d’exécuter des


commandes 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 1, 2014 33 / 436
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 à $a


soustraction $a -= $b soustrait $a et $b puis affecte le résultat à $a
multiplication $a *= $b multiplie $a et $b puis affecte le résultat à $a
division $a /= $b divise $a et $b puis affecte le résultat à $a
modulo $a %= $b divise $a et $b puis affecte le reste à $a
concaté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 1, 2014 34 / 436
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’aide


des accolades ouvrantes et fermantes { } :
<?
if ($a == 2) {
echo "instruction 1";
echo "instruction 2";
}
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 35 / 436
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 C


ou 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 1, 2014 36 / 436
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 1, 2014 37 / 436
PHP Bases du langage Instructions, opérations, variables

break et continue

▶ la commande break arrête l’exécution de la boucle :


<? 
 Truc
for ($i = 0; $i < 5; $i++) { 

 Toto
if ($tab[$i]=="bonjour") break; Bonjour


echo $tab[$i]; 
 Bip
} Salut
?>
▶ la commande continue arrête l’itération en cours de la boucle :

<? 
 Truc
for ($i = 0; $i < 5; $i++) { 

 Toto
if ($tab[$i]=="bonjour") continue; Bonjour


echo $tab[$i]; 
 Bip
} Salut
?>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 38 / 436
PHP Bases du langage Instructions, opérations, variables

switch

<? <?
switch ($a) { switch ($a) {
case 0 : case "a" :
echo '0'; echo 'a';
break; break;
case 1 : case "b" :
echo '1'; echo 'b';
break; break;
default : default :
echo 'default'; echo 'default';
} }
?> ?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 39 / 436
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 1, 2014 40 / 436
PHP Bases du langage Instructions, opérations, variables

Portée des variables

<?
<?
function modif() {
function modif() {
global $var;
$var = "salut";
$var = "salut";
}
}
$var = "toto";
$var = "toto";
var_dump($var); // 1
var_dump($var); // 3
modif();
modif();
var_dump($var); // 2
var_dump($var); // 4
?>
?>
1. string(4) "toto" 3. string(4) "toto"
2. string(4) "toto" 4. string(5) "salut"

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 41 / 436
PHP Bases du langage Chaînes de caractères

Affichage des chaînes

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

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 42 / 436
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
} 
65


$chaine=""; 
66

67
for ($i = 0; $i<6; $i++) { 1.
$c = rand(65,90); 
68


$chaine.=chr($c); 
69
} 70
echo "$chaine\n"; // 2 2. GZXNIY
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 43 / 436
PHP Bases du langage Chaînes de caractères

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

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 44 / 436


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 1, 2014 45 / 436
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 1, 2014 46 / 436
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); 1. &lt;b&gt;d&eacute;truire&lt;b&gt;
echo $b."\n"; /* 3 */ 2. <b>détruire</b>
$b=urlencode($a); 3. détruire
echo $b."\n"; /* 4 */ .
4 %3Cb%3Ed%E9truire%3C%2Fb%3E
$c=urldecode($b);
.
echo $c."\n"; /* 5 */ 5 <b>détruire</b>
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 47 / 436
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 */ 1. int(2)
$pos = strpos($ch,"Salut"); 2. string(17) "salut salut salut"
var_dump($pos); /* 4 */
$pos = stripos($ch,"Salut"); 3. int(8)
var_dump($pos); /* 5 */ 4. bool(false)
$ch3 = substr($ch,8,5); 5. int(8)
var_dump($ch3); /* 6 */
?> 6. string(5) "salut"

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 48 / 436
PHP Bases du langage Chaînes de caractères

Comparaison de chaînes de caractères

<?
$ch1=11;
$ch2="11toto";
1. int(11)
var_dump($ch1); /* 1 */
2. string(6) "11toto"
var_dump($ch2); /* 2 */
3. bool(true)
var_dump($ch1==$ch2); /* 3 */
4. bool(false)
var_dump($ch1===$ch2); /* 4 */
5. bool(false)
var_dump("$ch1"==$ch2); /* 5 */
var_dump($ch1*$ch2); /* 6 */ 6. int(121)
var_dump("$ch1"*$ch2); /* 7 */ 7. int(121)
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 49 / 436
PHP Bases du langage Chaînes de caractères

Comparaison de chaînes de caractères

<?
→ int(0) 1.
var_dump(strcmp("toto2","toto2"));
→ int(-1) 2.
var_dump(strcmp("toto12","toto2"));
→ int(1) 3.
var_dump(strcmp("toto2","toto12"));
→ int(0) 4.
var_dump(strcasecmp("toto","ToTo"));
var_dump(strnatcmp("toto12","toto2")); → int(1) 5.
?>
<?
$ch1 = "abc";
$ch2 = "bcd";
if ($ch1 < $ch2) echo "<"; else echo ">";
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 50 / 436
PHP Bases du langage Tableaux

Tableaux

▶ On peut indicer les tableaux avec des entiers ou des chaînes de


caractères;
▶ La fonction count($tab) retourne le nombre d’éléments présents
dans le tableau.

<? 
 array(3) {


$a[2] = 12; 
 [2] => int(12)

$a[4] = 23; [4] => int(23)
1.
$a["toto"] = 12.13; 
 [”toto”] => float(12.13)


var_dump($a); /* 1 */ 
 [clé] => valeur

$b = count($a); }
var_dump($b); /* 2 */
?> 2. int(3)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 51 / 436
PHP Bases du langage Tableaux

Tableaux

▶ Le mot clé array : Il prend un nombre variable de paramètres sous la


forme ”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 */
?>

 array(5) { 

  array(4) {

 [12] => int(3) 


 
 [0] => int(1)

 [”a”] => float(12.12) 

. [1] => int(2)
1 [13] => int(15) 2.

 
 [2] => int(3)

 [14] => string(1) ”c” 


 
 [3] => int(4)

 [1] => int(2) 
 }
}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 52 / 436
PHP Bases du langage Tableaux

Intervalles
<? 
$a=range(1,4); 
 array(4) {


var_dump($a); /* 1 */ 
 [0] => int(1)

$a=range(0,30,10); [1] => int(2)
1.
var_dump($a); /* 2 */ 
 [2] => int(3)


$a=range('d','g'); 
 [3] => int(4)

var_dump($a); /* 3 */ }
?>
 

 array(4) { 
 array(4) {

 


 [0] => int(0) 
 [0] => string(1) ”d”
 
[1] => int(10) [1] => string(1) ”e”
2. 3.

 [2] => int(20) 
 [2] => string(1) ”f”

 


 [3] => int(30) 
 [3] => string(1) ”g”
 
} }
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 53 / 436
PHP Bases du langage Tableaux

Ré-indexation
<?
$a = array(1,"a"=>2);
$a[] = 3; 

 array(3) {
var_dump($a); /* 1 */ 

 [0] => int(1)
unset($a[1]); .
1 [”a”] => int(2)
$a[] = 4; 


 [1] => int(3)
var_dump($a); /* 2 */ 
}
$a = array_values($a);
var_dump($a); /* 3 */
?>  

 array(3) { 
 array(3) {

 

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

 


 [2] => int(4) 
 [2] => int(4)
 
} }
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 54 / 436
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 */ 2. int(2)
$a[12][20] = 2;
var_dump($a[12]); /* 3 */
?>


 array(2) { 



 [12]=> array(3) { 
 array(4) {

 

 [0]=> int(1)  [0] => int(1)
1. [15]=> int(2) 3. [15] => int(2)

 

 }
 
 [20] => int(2)

 

 [15]=> int(2) }

}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 55 / 436
PHP Bases du langage Tableaux

foreach

▶ La boucle foreach parcourt tous les couples ”clé ⇒ valeur” contenus


dans 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=>12  12
 
a=>12.12 12.12
1. 2.

 c=>3 
3
2=>4 4
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 56 / 436
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=>12

a=>12.12
1.

 c=>3
2=>4

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 57 / 436
PHP Bases du langage Tableaux

list

▶ la fonction list affecte plusieurs variables simultanément :


<?
$a = array("a", 12, "c"); 1. string(1) ”a”
list($x,$y,$z)=$a; 2. int(12)
var_dump($x); /* 1 */
3. string(1) ”c”
var_dump($y); /* 2 */
var_dump($z); /* 3 */
list($i,,$j)=$a; 4. string(1) ”a”
var_dump($i); /* 4 */
5. string(1) ”c”
var_dump($j); /* 5 */
list($i,$j)=$a;
var_dump($i); /* 6 */ 6. string(1) ”a”
var_dump($j); /* 7 */ 7. int(12)
?>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 58 / 436
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=>12

a=>12.12
1.

 c=>3
2=>4

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 59 / 436
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_push

array_shift array_pop
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 60 / 436
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 */
?>

 array(5) {



 [0] => string(4) ”toto”
2. float(12.12)

 [1] => int(1)
1. [”a”] => int(2)


 [2] => int(3) 3. string(4) ”toto”



 [3] => float(12.12)
} . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 61 / 436
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 */
?>  


Array ( 

Array (

 [0] => 1 


  [0] => 1


 [a] => 2 
 [a] => 2

 


 [1] => 3 
 [1] => 3
 
[b] => 9 [b] => Array ( [0] => 4 [1] => 9 )
1. 2.

 [2] => 5 
 [2] => 5

 [c] => 6 
 [c] => 6

 


 [3] => 7 


  [3] => 7


 [4] => 8 

  [4] => 8
) ) ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 62 / 436


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 */
?>

 Array ( 

  Array (
 [0] => 1 
[a] => 2
1. [3] => 3 2.

 
 [4] => 5

 [b] => 4 )
)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 63 / 436
PHP Bases du langage Tableaux

Tri de tableaux indicés


<?
$a=array("a10", "b11", "b"=>"a9", "C12", "c12");
sort($a);  
 Array (  Array (
print_r($c); /* 1 */ 
 


 [0] => C12 
 [0] => c12
rsort($a); 
 [1] => a10 
 [1] => b11
print_r($c); /* 2 */
1. [2] => a9 2. [2] => a9
natsort($a); 
 


 [3] => b11 
 [3] => a10
print_r($c); /* 3 */ 
 [4] => c12 

natcasesort($a);   [4] => C12
) )
print_r($c); /* 4 */
 
?>  Array (  Array (

 


 [4] => C12 
 [2] => a9

 [2] => a9 
 [3] => a10
1. [3] => a10 2. [1] => b11

 


 [1] => b11 
 [0] => c12

 [0] => c12 

  [4] => C12
) )
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 64 / 436
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 */
?>


 Array (

 [0] => Array ([0] => 2 [1] => 2)
1. [1] => Array ([0] => 1 [1] => 4)



 [2] => Array ([0] => 1 [1] => 5)
)
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 65 / 436
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); 
 Array (
print_r($a); /* 2 */ 
 [b] => a
1. [a] => c
sort($a); 


print_r($a); /* 3 */  [c] => d
)
?>
 

 Array ( 
 Array (

 [c] => d 
 [0] => a
2. [a] => c 3. [1] => c

 


 [b] => a 
 [2] => d
) )

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 66 / 436
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 */
?>
 

 Array ( 
 Array (

 

 [a] => c  [c] => d
1. [b] => a 2. [b] => a

 

 [c] => d
 
 [a] => c
 
) )

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 67 / 436
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);
} 

 Array (


 [aa] => Array([0] => 0 [1] => 1)
$a = array("aa"=>array(0,1), 1. [a] => Array([0] => 1 [1] => 2)


"aaa"=>array(2,2),  [aaa] => Array([0] => 2 [1] => 2)


)
"a"=>array(1,2));
uasort($a,"compar1"); 

 Array (


print_r($a); /* 1 */  [a] => Array([0] => 1 [1] => 2)
uksort($a,"compar2"); 2. [aa] => Array([0] => 0 [1] => 1)


 [aaa] => Array([0] => 2 [1] => 2)

print_r($a); /* 2 */ 
)
?>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 68 / 436
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 */
?>


 Array (

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


)
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 69 / 436
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");
?>

 <b>0</b> : 1<br/>

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

 <b>1</b> : 2<br/>
<b>1</b> : 0<br/>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 70 / 436
PHP Bases du langage Tableaux

Chaînes et tableaux


<? 
 Array (

 [0] => J’aime
$ch = "J'aime le PHP. Vive le web!"; 



$tab = explode(' ',$ch); 
 [1] => le

print_r($tab); /* 1 */ [2] => PHP.
1.
$tab = explode('.',$ch); 
 [3] => Vive


print_r($tab); /* 2 */ 
 [4] => le


$tab = array("J'aime", "le", "PHP."); 
 [5] => web!

$ch = implode(" ",$tab); )
echo $ch."\n"; /* 3 */
$ch = implode("--",$tab); 

 Array (
echo $ch."\n"; /* 4 */ 
[0] => J’aime le PHP
?> 2.

 [1] => Vive le web!

)

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


. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 71 / 436
PHP Bases du langage Tableaux

Autres fonctions utiles sur les tableaux

▶ La fonction array_unique($tab) supprime les valeurs en double


dans 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 et


renumérote les éléments.

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 72 / 436
PHP Formulaires Introduction

GET

Protocole HTTP
1. Je veux toto.php

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

Requête : Réponse :
GET /toto.php?n1=10&n2=15 HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>Résultat .: .25.</P>
. . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 73 / 436
PHP Formulaires Introduction

POST

Protocole HTTP
1. Je veux toto.php

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

Requête : Réponse :
POST /toto.php HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
?n1=10&n2=15 Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>Résultat .: .25.</P>
. . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 74 / 436
PHP Formulaires Introduction

Les formulaires en HTML

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

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

<textarea>...</textarea>

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

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


. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 75 / 436
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 page


page.php lorsque l’utilisateur clique sur le bouton Envoyer. . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 76 / 436
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 1, 2014 77 / 436
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> POST traitement.php
</html> Requête : ...
nom=Superman
▶ Fichier traitement.php ...
Réponse : Bonjour Superman.
<html> ...
<body>
Bonjour <? echo $_POST['nom']; ?>.</br>
</body>
</html>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 78 / 436
PHP Formulaires Variables $_POST et $_GET

Variable $_POST

Client Serveur

GET index.php

contenu de
index.php

Saisie du nom
POST traitement.php
Clic sur "Envoyer"
...
nom=Superman

Génération de
la page par PHP
Bonjour Superman

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 79 / 436
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> Requête : GET traitement.php?nom=superman
...

▶ Fichier traitement.php ...


Réponse : Bonjour Superman.
<html> ...
<body>
Bonjour <? echo $_GET['nom']; ?>.</br>
</body>
</html>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 80 / 436
PHP Formulaires Variables $_POST et $_GET

Variable $_GET

Client Serveur

GET index.php

contenu de
index.php

Saisie du nom
GET traitement.php
Clic sur "Envoyer"
?nom=Superman
...

Génération de
la page par PHP
Bonjour Superman

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 81 / 436
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 1, 2014 82 / 436
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 1, 2014 83 / 436
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 : Vous avez coché : A C


<html>
<body>
Vous avez coche :
<? foreach ($_POST['choix'] as $v)
echo "$v "; ?>
<br/>
</body>
</html> . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 84 / 436
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 1, 2014 85 / 436
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 1, 2014 86 / 436
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>

 array(1) {



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



 [”name”]]=> string(3) ”a.c”

 [”type”]=> string(10) ”text/plain”
1. [”tmp_name”]=> string(14) ”/tmp/phpi5JOt8”



 [”error”]=> int(0)

 [”size”]=> int(185)



 }

} . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 87 / 436
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 1, 2014 88 / 436
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 1, 2014 89 / 436
PHP Fichiers Ouverture

Ouverture d’un fichier

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

$id = tmpfile(); 1. resource(5) of type (stream)


var_dump($id); /* 3 */
fclose($id); 2. resource(5) of type (Unknown)
var_dump($id); /* 4 */
3. resource(6) of type (stream)
?>
4. resource(6) of type (Unknown)
▶ 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 1, 2014 90 / 436
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 commencent
au début. Le fichier doit exister.
w : le fichier est ouvert en écriture et l’écriture commence au début du
fichier. Le fichier est créé s’il n’existe pas.
w+ : le fichier est ouvert en écriture et en lecture et les opérations
commencent 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 du
fichier. Le fichier est créé s’il n’existe pas.
a+ : le fichier est ouvert en écriture et lecture. L’écriture commence à la
fin et la lecture au début. Le fichier est créé s’il n’existe pas.

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 91 / 436
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éverrouillage
fclose($id);
?>
▶ LOCK_SH : Verrouillage en écriture seulement
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 92 / 436
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$\backslas
$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 texte
100

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 93 / 436
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");
jean;pascal
flock($id, LOCK_SH); didier;julien
fwrite($id, "$nom;$prenom\n");
flock($id, LOCK_UN);
paul;jacques
$r = fclose($id); michel;jean
if ($r===FALSE) die("erreur");
}
?>
</body>
</html> . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 94 / 436
PHP Fichiers Lecture

Lecture dans un fichier

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

mon texte
100
<?
$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 pointant
sur un fichier et le nombre maximum de caractères à lire
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 95 / 436
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;pascal
didier;julien

paul;jacques
michel;jean . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 96 / 436
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); 1. : nombre maximum de caractères à lire
?>
</table> 2. : caractère séparateur

jean;pascal
didier;julien

paul;jacques
michel;jean
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 97 / 436
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;pascal
didier;julien

paul;jacques
michel;jean
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 98 / 436
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 1, 2014 99 / 436
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 1, 2014 100 / 436
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 1, 2014 101 / 436
PHP Headers Introduction

Headers

Protocole HTTP
1. Je veux toto.html

Client Serveur
2. Contenu de toto.html

Requête : Réponse :
GET /toto.html HTTP/1.0 HTTP/1.0 200 OK
Host: example.com Date: Fri, 31 Dec 1999 23:59:59 GMT
Referer: http://example2.com/ Server: Apache/0.8.4
User-Agent: Mozilla/5.0 (X11; U; Linux Content-Type: text/html
x86_64; fr; rv:1.9.0.4) Gecko/2008111217 Content-Length: 59
Fedora/3.0.4-1.fc10 Firefox/3.0.4 Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modified: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>page d’exemple.</P>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 102 / 436
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>
<? } else
header('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 1, 2014 103 / 436
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 1, 2014 104 / 436
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 1, 2014 105 / 436
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 1, 2014 106 / 436
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 le


serveur, c’est-à-dire, sans utiliser ce fichier php.
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 107 / 436
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 1, 2014 108 / 436
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 visiteur
ses préférences (présentation personnalisée du site).

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 109 / 436
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 être
appelée avant d’écrire sur la sortie standard.
▶ Par défaut, le cookie expire à la fermeture du navigateur et est
accessible 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 1, 2014 110 / 436
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 valeur1
echo $_COOKIE["nom2"]."</br>"; // affiche valeur2
?>

▶ Attention : Les cookies ne sont pas immédiatement accessibles par la


page qui vient de les créer.
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 111 / 436
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 1, 2014 112 / 436
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 1, 2014 113 / 436
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 1, 2014 114 / 436
PHP Cookies et sessions Cookies

Exemple d’utilisation des cookies

▶ Au début du fichier index.php :


<?
$couleur = 'red'; // couleur par défaut
if (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 1, 2014 115 / 436
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 de
session passé dans une requête GET, POST ou par un cookie.
2. Au moment de la création de la session, chaque utilisateur se voit
attribuer un identifiant (de session) composé de 26 caractères
aléatoires. Il est transmit d’une page à l’autre par l’intermédiaire d’un
cookie 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 1, 2014 116 / 436
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 1, 2014 117 / 436
PHP Cookies et sessions Sessions

Sans cookies
Sans 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 1, 2014 118 / 436


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 1, 2014 119 / 436
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 1, 2014 120 / 436
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 1, 2014 121 / 436
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 1, 2014 122 / 436
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 Date {
public $day = 2;
public $month = 3;
public $year = 1970;

// public $year = strlen('toto'); (interdit !)

public function getYear() { return $this->year; }


public function setDay($day) { $this->day = day; }
}
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 123 / 436
PHP Programmation Orientée Objet Classe et instance

Création d’une instance

Pour créer une instance d’une classe, on utilise le mot-clé new.


<?
class Date {
/* ... */
}

$date1 = new Date();


$date2 = new Date();
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 124 / 436
PHP Programmation Orientée Objet Classe et instance

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

<?
class Date {
public $day = 2;
public $month = 3;
public $year = 1970;
public function getYear() { return $this->year; }
public function setDay($day) { $this->day = day; }
}

$date = new Date();


$date->day = 3; // pas de $ dans le nom de la propriété
echo $date->day;
$date->setDay(12);
?>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 125 / 436
PHP Programmation Orientée Objet Classe et instance

$this

<?
class Date {
public $day = 2;
public $month = 3;
public $year = 1970;
public function getYear() { return $this->year; }
public function setDay($day) { $this->day = day; }
}

$date = new Date();


$date->setDay(12);
echo $date->getYear();
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 126 / 436
PHP Programmation Orientée Objet Classe et instance

Constantes – propriétés et méthodes statiques


<?
class Date {
const maxMonth = 12;
private static $monthStrings = array("Janvier",
"Février" /* ... */ );

private $month = 1;

public function setMonth($month) {


if ($month > self::maxMonth)
die("error");
$this->month = $month;
}

public function getMonthString() {


return self::$monthStrings[$this->month];
}
} ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 127 / 436


PHP Programmation Orientée Objet Classe et instance

Constructeur et destructeur
<?
class Date {
private $day, $month, $year;

function __construct($day, $month, $year) {


$this->day = $day;
$this->month = $month;
$this->year = $year;
}

function __destruct() { echo $this->day; }


}

$date1 = new Date(1,1,1970);


$date2 = new Date(2,1,1970);
$date1 = null; // affichage de '1'
// affichage de '2'
?> ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 128 / 436


PHP Programmation Orientée Objet Héritage et interface

Interface

<?
interface Movable {
public function translate($dx, $dy);
}

class Point implements Movable {


public $x = 0, $y = 0;

public function translate($dx, $dy) {


$this->dx += $dx;
$this->dy += $dy;
}
}
?>

Il est possible d’implémenter plusieurs interfaces.


. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 129 / 436
PHP Programmation Orientée Objet Héritage et interface

Héritage
<?
class Point {
public $x, $y;
function __construct($x, $y) { $this->x = $x; $this->y = $y; }
function toString() { return $this->x.",".$this->y; }
}

class Pixel extends Point {


public $color;

function __construct($x, $y, $color) {


parent::__construct($x,$y); $this->color = $color;
}

function toString() {
return parent::toString()."[".$this->color."]";
}
} ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

?> Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 130 / 436
PHP Programmation Orientée Objet Héritage et interface

Héritage

<?
$point = new Point(2,3);
$pixel = new Pixel(2,3,"red");

var_dump($point instanceof Point); // bool(true)


var_dump($pixel instanceof Point); // bool(true)
var_dump($point instanceof Pixel); // bool(false)
var_dump($pixel instanceof Pixel); // bool(true)
?>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 131 / 436
PHP Programmation Orientée Objet Héritage et interface

Late Static Bindings (Résolution statique à la volée)


<?
class MyClass {
function toString() { return self::getClassName(); }
static function getClassName() {
return "MyClass";
}
}
class MyExtendedClass extends MyClass {
static function agetClassName() {
return "MyExtendedClass";
}
}

$myClass = new MyClass();


$myExtendedClass = new MyExtendedClass();
echo $myClass->toString(); // MyClass
echo $myExtendedClass->toString(); // MyClass
?> ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 132 / 436


PHP Programmation Orientée Objet Héritage et interface

Late Static Bindings (Résolution statique à la volée)


<?
class MyClass {
function toString() { return static::getClassName(); }
static function getClassName() {
return "MyClass";
}
}
class MyExtendedClass extends MyClass {
static function agetClassName() {
return "MyExtendedClass";
}
}

$myClass = new MyClass();


$myExtendedClass = new MyExtendedClass();
echo $myClass->toString(); // MyClass
echo $myExtendedClass->toString(); // MyExtendedClass
?> ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 133 / 436


PHP Programmation Orientée Objet Héritage et interface

Classe abstraite

<?
abstract class Person {
abstract public function getName();

public function displayName() {


echo $this->getName()."\n";
}
}

class Bob extends Person {


public function getName() { return "bob"; }
}

$bob = new Bob();


$bob->displayName(); // affiche 'bob'
?>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 134 / 436
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 MyClass {
public $pub;
protected $pro;
private $pri;
public function publicMethod() { ... }
protected function protectedMethod() { ... }
private function privateMethod() { ... }
}

class MyExtendedClass extends MyClass {


public function test() {
echo $this->pub; $this->publicMethod();
echo $this->pro; $this->protectedMethod();
echo $this->pri; $this->privateMethod(); // interdit !
}
}
?> .
. .
. . . .
.
. . . . . . . . . . . . . . .
. . .
. . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 135 / 436
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 MyClass {
public $pub;
protected $pro;
private $pri;
public function publicMethod() { ... }
protected function protectedMethod() { ... }
private function privateMethod() { ... }
}

class MyOtherClass /* qui n'étend pas MyClass */ {


public function test() {
$i = new MyClass();
echo $i->pub; $i->publicMethod();
echo $i->pro; $i->protectedMethod(); // interdit !
echo $i->pri; $i->privateMethod(); // interdit !
}
} . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
?>
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 136 / 436
PHP Programmation Orientée Objet Clonage

Clonage
<?
class Point {
public $x, $y;

function __construct($x, $y) {


$this->x = $x; $this->y = $y;
}

function __clone() { $this->x += 10; }


}

$point = new Point(10,10);


$point2 = clone $point;
echo $point->x."\n"; // affiche '10'
echo $point2->x."\n"; // affiche '20'
?> ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 137 / 436


PHP Programmation Orientée Objet Méthodes magiques

Méthodes magiques – Set et Get


<?
class MyClass {
private $attrs;

public function __set($attr, $val) {


echo "$attrs <- $val\n";
$this->attrs[$attr] = $val;
}
public function __get($attr) {
if (!isset($this->attrs[$attr])) return "erreur";
else return $this->attrs[$attr];
}
}
$myClass = new MyClass();
$myClass->toto = 2; // affiche 'toto <- 2'
echo $myClass->toto."\n"; // affiche '2'
echo $myClass->a."\n"; // affiche 'erreur'
?> ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 138 / 436


PHP Programmation Orientée Objet Méthodes magiques

Méthodes magiques – Isset et Unset


<?
class MyClass {
private $attrs;

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

public function __isset($attr) {


return isset($this->attrs[$attr]);
}
public function __unset($attr) {
echo "destruction de $attr\n"; unset($this->attrs[$attr]);
}
}
$myClass = new MyClass();
$myClass->toto = 2; // affiche 'toto <- 2'
var_dump(isset($myClass->toto)); // affiche 'bool(true)'
unset($myClass->toto); // affiche 'destruction de toto'
?> ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 139 / 436


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ée


pour 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ésente
des 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 1, 2014 140 / 436
PHP Modèle-Vue-Contrôleur Présentation du projet

Projet 1 – Sondages
Présentation du projet : Les utilisateurs postent des sondages constitués
d’une question et de plusieurs réponses. Une fois le sondage posté, il est
accessible aux visiteurs du site qui pourront voter pour une des réponses
proposées. Les nombres de voix obtenues pour chaque réponse sont
comptabilisés et affichés sous la forme d’un graphique. Tous les visiteurs
peuvent chercher parmi les sondages et voter.

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 141 / 436
PHP Modèle-Vue-Contrôleur Organisation générale

Organisation générale

Contrôleur Action Modèle Vue

Requête HTTP
Crée et exécute

Consulte/modifie

Crée, initialise et affiche

Réponse HTTP

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 142 / 436
PHP Modèle-Vue-Contrôleur Organisation générale

Organisation générale

Contrôleur Action Modèle Vue

Requête HTTP
Crée et exécute

Consulte/modifie

Crée, initialise et affiche

Consulte/observe

Réponse HTTP

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 143 / 436
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 1, 2014 144 / 436
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 1, 2014 145 / 436
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 1, 2014 146 / 436
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 1, 2014 147 / 436
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 {
/* ... */

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 1, 2014 148 / 436
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 1, 2014 149 / 436
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 1, 2014 150 / 436
PHP Modèle-Vue-Contrôleur Le modèle

Le modèle
Le 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 1, 2014 151 / 436
PHP Modèle-Vue-Contrôleur Le modèle

Le modèle
Vous 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 classe
Dababase (instanciée dans le constructeur de classe Action). Nous
détaillerons les fonctionnalités de cette classe plus tard.
..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 152 / 436


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 1, 2014 153 / 436
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 de


la page (en conservant les bordures, le formulaire de connexion, etc.).
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 154 / 436
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 1, 2014 155 / 436
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 1, 2014 156 / 436
PHP Modèle-Vue-Contrôleur Les vues

Exemple : la vue SurveysView


Par 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 1, 2014 157 / 436
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 1, 2014 158 / 436
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 1, 2014 159 / 436
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 1, 2014 160 / 436
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 1, 2014 161 / 436
PHP Modèle-Vue-Contrôleur Les vues

Framework PHP
Il existe des frameworks PHP qui permettent de mettre en place plus
facilement 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 1, 2014 162 / 436
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 1, 2014 163 / 436
PHP Base de données PDO

PDO

PDO (PHP Data Objects) est une interface pour accéder à une base de
données depuis PHP. Elle gère la connexion, l’envoie des requêtes, la
déconnexion à la base de données. Elle permet de changer plus facilement
de 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 1, 2014 164 / 436
PHP Base de données Les requêtes et fonctions utiles

PDO
Une 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 1, 2014 165 / 436
PHP Base de données Les requêtes et fonctions utiles

Injections SQL
Le 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 1, 2014 166 / 436
PHP Base de données Les requêtes et fonctions utiles

PDO
Pour 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 1, 2014 167 / 436
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 1, 2014 168 / 436
PHP Base de données Les requêtes et fonctions utiles

PDO
Voir 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ère


Chaine échappée : ’Chaine ” particulière’ ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 169 / 436


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 1, 2014 170 / 436
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 1, 2014 171 / 436
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 1, 2014 172 / 436
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 1, 2014 173 / 436
PHP Base de données Mapping objet-relationnel (ORM)

Redbean – Introduction
Initialisation 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 1, 2014 174 / 436
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 1, 2014 175 / 436
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 1, 2014 176 / 436
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 1, 2014 177 / 436
JavaScript Introduction

JavaScript

JavaScript est un langage de programmation initialement utilisé pour créer


des 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 1, 2014 178 / 436
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 1, 2014 179 / 436
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 1, 2014 180 / 436
JavaScript Les types

JavaScript – Les types


En JavaScript, les types sont associés aux valeurs :
var v = "toto"; // variable contient une chaîne
v = 'toto'; // variable contient une chaîne
v = 22; // variable contient un nombre
v = 22.12; // variable contient un nombre
v = true; // variable contient un booléen
v = ["toto", 22]; // variable contient un tableau
v = {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 la
variable existe mais sa valeur ne désigne aucun objet :
var v = null;
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 181 / 436
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 1, 2014 182 / 436
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 1, 2014 183 / 436
JavaScript Les nombres

JavaScript – Les nombres


Les 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 1, 2014 184 / 436
JavaScript Les opérateurs

JavaScript – Les comparaisons et opérateurs logiques

égal a == b vrai si a est égal à b


identique a === b vrai si a et b sont égaux et ont le même type
différent a != b vrai si a est différent de b
non identique a !== b vrai si a et b sont différents
ou n’ont pas le même type
plus petit a < b vrai si a est strictement plus petit que b
plus grand a > b vrai si a est strictement plus grand que b
inférieur ou égal a <= b vrai si a est plus petit ou égal à b
supérieur ou égal a >= b vrai si a est plus grand ou égal à b

non !a vrai si a n’est pas vrai


et a && b vrai si a et b sont vrais
ou a || b vrai si a ou b sont vrais

var v = (test)?"Vrai":"Faux";
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 185 / 436
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 1, 2014 186 / 436
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 1, 2014 187 / 436
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 1, 2014 188 / 436
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 1, 2014 189 / 436
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; // 6
var 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 1, 2014 190 / 436
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 5
alert(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 2
b = 3; assign(); alert(a); // affiche 3
Il est important de noter que le code est lié au variable (et non aux valeurs
des variables au moment de la définition de la fonction).
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 191 / 436
JavaScript Les fonctions

JavaScript – Les fonctions


Les paramètres des fonctions sont passés par valeur donc chaque
paramètre est une variable locale à la fonction :
var sum2 = function(n) { n += 2; return n; }
var n = 2;
alert(sum2(n)); // affiche 4
alert(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 3
display4(); // affiche 4
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 192 / 436
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 1, 2014 193 / 436
JavaScript Les objets

JavaScript – Les objets


En 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 1, 2014 194 / 436
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 1, 2014 195 / 436
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 1, 2014 196 / 436
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 1, 2014 197 / 436
JavaScript Les objets

JavaScript – Les objets


Attention, le code suivant ne fonctionne pas car, dans la méthode click, la
fonction notify n’est appelée sur un objet (dans ce cas, this contient une
ré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 1, 2014 198 / 436
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 1, 2014 199 / 436
JavaScript Les objets

JavaScript – Les objets


Un 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 1, 2014 200 / 436
JavaScript Les objets

JavaScript – Les objets


Le 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 1, 2014 201 / 436
JavaScript Les objets

JavaScript – Les objets


Correction 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 1, 2014 202 / 436
JavaScript Les prototypes

JavaScript – Les prototypes


Le 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 1, 2014 203 / 436
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 1, 2014 204 / 436
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 1, 2014 205 / 436
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 1, 2014 206 / 436
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 1, 2014 207 / 436
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 1, 2014 208 / 436
JavaScript JSON

JavaScript – JSON
JSON (JavaScript Oject Notation) est un format de données dérivé de la
notation 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 1, 2014 209 / 436
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 1, 2014 210 / 436
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 1, 2014 211 / 436
JavaScript JSON

JavaScript – JSON

Inversement, il est facile de construire une valeur à partir d’une chaîne de


caractè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 1, 2014 212 / 436
HTML, CSS, DOM HTML

HTML
HTML (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 1, 2014 213 / 436
HTML, CSS, DOM HTML

HTML

Les documents HTML décrivent une structure d’arbre :

<body>
<body>
<b>Liste : </b>
<ul> <b> <ul>
<li>Element 1</li>
<li>Element 2</li> Liste : <li> <li> <li>
<li>Element 3</li>
Element 1 Element 2 Element 3
</ul>
</body>

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 1, 2014 214 / 436
HTML, CSS, DOM HTML

de HTML à HTML5
Histoire 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 1, 2014 215 / 436
HTML, CSS, DOM CSS Introduction

CSS – Introduction

CSS (Cascading Style Sheets) est un langage permettant de définir la


pré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 1, 2014 216 / 436
HTML, CSS, DOM CSS Association du CSS au code HTML

CSS – Association du CSS au code HTML


Dans 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 1, 2014 217 / 436
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 1, 2014 218 / 436
HTML, CSS, DOM CSS Format

CSS – Format
Un 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 1, 2014 219 / 436
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 1, 2014 220 / 436
HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Attributs


Selection 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 1, 2014 221 / 436
HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Classes et identifiants


Association 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 1, 2014 222 / 436
HTML, CSS, DOM CSS Sélecteurs

CSS – Sélecteurs – Pseudo-classes structurelles

Vous pouvez baser votre sélection sur des informations se trouvant dans
l’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 1, 2014 223 / 436
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 1, 2014 224 / 436
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 1, 2014 225 / 436
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 1, 2014 226 / 436
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 1, 2014 227 / 436
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 de


supprimer des éléments HTML.
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 228 / 436
HTML, CSS, DOM DOM

DOM – Les noeuds


Chaque é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 : Élement :
<head> <body>

Élement : Élement : Élement : Attirbut :


<title> <b> <span> class="alert"

Texte : Texte : Texte :


"Titre" "Truc" "Mon texte"
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 229 / 436
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 : Élement :
<head> <body>

Élement : Élement : Élement : Attirbut :


<title> <b> <span> class="alert"

Texte : Texte : Texte :


"Titre" "Truc" "Mon texte"

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 230 / 436
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 1, 2014 231 / 436
HTML, CSS, DOM jQuery

jQuery
jQuery est une bibliothèque JavaScript libre qui permet de simplifier la
programmation 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 1, 2014 232 / 436
HTML, CSS, DOM jQuery

jQuery – Sélectionner des éléments


Sé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 1, 2014 233 / 436
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 1, 2014 234 / 436
HTML, CSS, DOM jQuery

jQuery – Parcourir les éléments


Appliquer 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 1, 2014 235 / 436
HTML, CSS, DOM jQuery

jQuery – Ajouter, supprimer des éléments


Modifier 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 1, 2014 236 / 436
HTML, CSS, DOM jQuery

jQuery – CSS
Les 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 document
alert(p.left+" "+p.top); ..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

p =Bertrand
$("#id_element").position();
Estellon (AMU) //2 par rapport April
Développement Web au1, parent
2014 237 / 436
HTML, CSS, DOM jQuery

jQuery – Les événements


La 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 1, 2014 238 / 436
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 1, 2014 239 / 436
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 1, 2014 240 / 436
Communication client/serveur AJAX L’objet XMLHttpRequest

XMLHttpRequest : Création
Une 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 1, 2014 241 / 436
Communication client/serveur AJAX L’objet XMLHttpRequest

XMLHttpRequest : Les méthodes et propriétés


Description 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 1, 2014 242 / 436
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 1, 2014 243 / 436
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 1, 2014 244 / 436
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 1, 2014 245 / 436
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 1, 2014 246 / 436
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 1, 2014 247 / 436
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 1, 2014 248 / 436
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 1, 2014 249 / 436
Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : les données


Nous avons également les images associés aux auteurs dans un répertoire
image du serveur. De plus, pour chaque auteur, nous avons un fichier de
la 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 et
prosateur romantique considéré comme
l’un des plus importants écrivains
de 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 1, 2014 250 / 436
Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : index.html


Nous 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 1, 2014 251 / 436
Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : index.js


function 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 1, 2014 252 / 436
Communication client/serveur AJAX Sans serveur dynamique

Un exemple sans serveur dynamique : index.js


function 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 1, 2014 253 / 436
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 1, 2014 254 / 436
Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletion
Autocomplé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 1, 2014 255 / 436
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 1, 2014 256 / 436
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 1, 2014 257 / 436
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 1, 2014 258 / 436


Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : autocompletion – déroulement d’une requête

getWords("mang", callback)
callback(["manganate", ... ])

réponse du serveur '["manganate", ... ]'

Serveur
$.ajax({...}) :
post server.php avec query="mang"

json_encode(array("manganate", ...)) getWords("mang")

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 259 / 436
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 1, 2014 260 / 436
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 1, 2014 261 / 436
Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – server.php


Exé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 architecture
similaire à celle du premier projet ou utiliser un framework PHP.
..
.
..
.
..
. . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. ..
.
..
.
..
.
..
.
..
.

Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 262 / 436


Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – server.php


Les 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 1, 2014 263 / 436
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 1, 2014 264 / 436
Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – index.js


function 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 1, 2014 265 / 436
Communication client/serveur AJAX Avec un serveur écrit en PHP

Exemple : authentification – index.js


function 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 1, 2014 266 / 436
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 1, 2014 267 / 436
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 1, 2014 268 / 436
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 1, 2014 269 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)


Première partie du projet : Vous devez réaliser le projet en utilisant
uniquement PHP en vous basant sur l’organisation mise à place dans le
projet ”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 la


quantité de données envoyées par le serveur. Le but est d’obtenir une
version où toutes les actions de l’utilisateur se font en utilisant AJAX.
Librairies : jQuery et Bootstrap.
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 270 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 271 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 272 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 273 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 274 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 275 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 276 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 277 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 278 / 436
Communication client/serveur AJAX Projet AJAX

Projet 2 (PHP et AJAX)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 279 / 436
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 1, 2014 280 / 436
Communication client/serveur Comet Problématique

Problématique
Problè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 1, 2014 281 / 436
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 1, 2014 282 / 436
Communication client/serveur Comet Création d’un serveur avec Jetty

Jetty – Création d’un serveur Web


Gestion des sessions et mises en place de code spécifique pour traiter les
requê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 1, 2014 283 / 436
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 1, 2014 284 / 436
Communication client/serveur Comet Le serveur

Jetty – Classe User


public 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 1, 2014 285 / 436
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 1, 2014 286 / 436
Communication client/serveur Comet Le serveur

Jetty – Classe SendServlet

public class SendServlet extends ChatServlet {

public SendServlet(ChatServer server) {


super(server);
}

@Override
protected 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 1, 2014 287 / 436
Communication client/serveur Comet Le serveur

Jetty – Classe GetServlet

public class GetServlet extends ChatServlet {

public GetServlet(ChatServer server) {


super(server);
}

@Override
protected String doAction(User user,
HttpServletRequest req) {
String msg = user.getMessage();
return msg;
}

}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 288 / 436
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 1, 2014 289 / 436
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 1, 2014 290 / 436
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 1, 2014 291 / 436
Communication client/serveur Comet Continuations

Jetty – Continuations

Problématique : Dans la première version, pour supporter un très grand


nombre de clients, il est nécessaire que le serveur puisse être en train de
traiter un grand nombre de requêtes simultanément.

Première solution : Dans la première version, on doit permettre au


serveur de créer un thread pour créer chacune des requêtes des clients. En
d’autres termes, le nombre de clients possibles est limité par le nombre de
threads que le serveur peut créer.

Les “continuations” : Elles permettent de mettre en suspend le


traitement d’une requête et de le reprendre plus tard.
Conséquence : On va pouvoir mettre en place un pool de Threads pour
traiter les requêtes (nouvelles ou suspendus).

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 292 / 436
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 1, 2014 293 / 436
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 1, 2014 294 / 436
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 1, 2014 295 / 436
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 du


serveur 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 1, 2014 296 / 436
Communication client/serveur WebSocket

WebSocket
Objectif (Wikipedia) : Obtenir un canal de communication bidirectionnel
et full-duplex sur un socket TCP pour les navigateurs et les serveurs web.

Demande de connexion du client et “handshake” :


GET /ws HTTP/1.1
Host: pmx
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 6
Sec-WebSocket-Origin: http://pmx
Sec-WebSocket-Extensions: deflate-stream
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==

du serveur :
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 297 / 436
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 1, 2014 298 / 436
Communication client/serveur WebSocket WebSocket et Jetty

Serveur – avec Jetty


Cré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 1, 2014 299 / 436
Communication client/serveur WebSocket WebSocket et Jetty

Serveur – avec Jetty

La classe qui reçoit les notifications de connexion :


public class WSHandler extends WebSocketHandler {

@Override
public WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
Client client = new Client();
return client;
}

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 300 / 436
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 1, 2014 301 / 436
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 1, 2014 302 / 436
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 1, 2014 303 / 436
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 1, 2014 304 / 436
Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur


public 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 1, 2014 305 / 436
Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur

public class WSHandler extends WebSocketHandler {

private MorpionServer server = new MorpionServer();

@Override
public WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
Client client = new Client(server);
return client;
}
}

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 306 / 436
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 1, 2014 307 / 436
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 1, 2014 308 / 436
Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur


public 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 1, 2014 309 / 436
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 1, 2014 310 / 436
Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur


public 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 1, 2014 311 / 436
Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur


public 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 1, 2014 312 / 436
Communication client/serveur WebSocket Jeu de Morpion

Exemple du jeu de morpion – Serveur


public 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 1, 2014 313 / 436
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 1, 2014 314 / 436
Node.js Introduction

Node.js – Introduction
Node.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.js
Server running at http://127.0.0.1:8888/ . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 315 / 436
Node.js Les modules

Node.js – Les modules


Pour 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 1, 2014 316 / 436
Node.js Les modules

Node.js – Installation de modules


Pour télécharger et installer des modules, vous pouvez utiliser npm :
$ npm install express
npm http GET https://registry.npmjs.org/express
...

▶ La commande npm cherche un répertoire node_modules présent dans


un 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 1, 2014 317 / 436
Node.js Quelques API

Node.js – Quelques API


Un 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 1, 2014 318 / 436
Node.js Express

Node.js – Express – Introduction


Express est un framework pour construire des applications Web en Node

Installation :
> npm install express
npm 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 1, 2014 319 / 436
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 1, 2014 320 / 436
Node.js Express

Node.js – Express – Accès aux paramètres


Vous 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 1, 2014 321 / 436
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 1, 2014 322 / 436
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 1, 2014 323 / 436
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 1, 2014 324 / 436
Node.js Express

Node.js – Express – Les sequences


Les 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 1, 2014 325 / 436
Node.js Express

Node.js – Express – Les sequences


Les 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 1, 2014 326 / 436
Node.js Express

Node.js – Express – Templates avec ejs


Il 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 1, 2014 327 / 436
Node.js Express

Node.js – Express – Templates avec ejs


Le 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 1, 2014 328 / 436
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 1, 2014 329 / 436
Node.js Express

Node.js – Express – Templates avec Jade

Le fichier users.html :
!!! 5
html
head
title Example
body Users :
ul
for user in users
li #{user.name} : #{user.age}

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 330 / 436
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 1, 2014 331 / 436
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 1, 2014 332 / 436
Node.js Socket.IO Introduction

Node.js – Socket.IO
Socket.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, WebOs
WebKit. . . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 333 / 436
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 1, 2014 334 / 436
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 1, 2014 335 / 436
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 1, 2014 336 / 436
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 1, 2014 337 / 436
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 1, 2014 338 / 436
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 1, 2014 339 / 436
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 1, 2014 340 / 436
Node.js Socket.IO Premier exemple

Node.js – Socket.IO – Premier exemple


Initialisation 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 1, 2014 341 / 436
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 1, 2014 342 / 436
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 1, 2014 343 / 436
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 1, 2014 344 / 436
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 1, 2014 345 / 436
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 1, 2014 346 / 436
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 1, 2014 347 / 436
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 1, 2014 348 / 436
Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur


var 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 1, 2014 349 / 436
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 1, 2014 350 / 436
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 1, 2014 351 / 436
Node.js Socket.IO Jeu de Morpion

Node.js – Socket.IO – Morpion – Serveur


Game.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 1, 2014 352 / 436
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 1, 2014 353 / 436
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 1, 2014 354 / 436
AngularJS Introduction

Introduction
AngularJS :
▶ 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 1, 2014 355 / 436
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 1, 2014 356 / 436
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 1, 2014 357 / 436
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.

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 du
modèle attachée à l’élément du DOM contrôle.
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 358 / 436
AngularJS Contrôleurs

Scopes et RootScope
La variable $scopeScope contient l’intégralité du modèle alors que la
variable $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 1, 2014 359 / 436
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 1, 2014 360 / 436
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 1, 2014 361 / 436
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 1, 2014 362 / 436
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 1, 2014 363 / 436
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 1, 2014 364 / 436
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 1, 2014 365 / 436
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 1, 2014 366 / 436
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 1, 2014 367 / 436
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 1, 2014 368 / 436
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 1, 2014 369 / 436
AngularJS Modules

Les modules
Un 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 1, 2014 370 / 436
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 1, 2014 371 / 436
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 1, 2014 372 / 436
AngularJS Services

Les services
Un 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 1, 2014 373 / 436
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 1, 2014 374 / 436
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 1, 2014 375 / 436
AngularJS Services

Les services
Dé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 1, 2014 376 / 436
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 1, 2014 377 / 436
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 1, 2014 378 / 436
AngularJS Services

Les services
Services et événements extérieurs à AngularJS :
▶ Les modifications du modèle engendrent une modification du DOM
uniquement à la fin d’un évenements AngularJS.
▶ Donc, il n’y aura pas de modification du DOM à la fin d’un
traitement associé à un événement extérieur à AngularJS.
▶ La méthode $apply(func) permet d’exécuter une fonction depuis
l’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 1, 2014 379 / 436
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 1, 2014 380 / 436
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 1, 2014 381 / 436
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 1, 2014 382 / 436
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 du


code 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 1, 2014 383 / 436
AngularJS Injection

Injection
Pour 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 1, 2014 384 / 436
AngularJS Routes

Routes
Objectif :
▶ afficher des vues en fonction de l’URL présente dans la barre
d’adresse du navigateur de façon à avoir un déplacement agréable
dans 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 de
AngularJS 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 1, 2014 385 / 436
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 : #/user/1 : #/user/2 :


▶ Lucie
▶ Bob Bob Christine
▶ Christine

age : 22 age : 30
Arthur
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 386 / 436
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 1, 2014 387 / 436
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 1, 2014 388 / 436
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 1, 2014 389 / 436
AngularJS Directives

Directives
Les 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 1, 2014 390 / 436
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 1, 2014 391 / 436
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 1, 2014 392 / 436
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 1, 2014 393 / 436
AngularJS Directives

Directives
Utilisation 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 1, 2014 394 / 436
AngularJS Directives

Directives
Supposons 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 1, 2014 395 / 436
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 la


balise dans la balise désignée à l’aide du mot-clé.

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 396 / 436
AngularJS Directives

Directives
Ré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 1, 2014 397 / 436
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 1, 2014 398 / 436
AngularJS Directives

Directives
Dé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 1, 2014 399 / 436
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 1, 2014 400 / 436
AngularJS Directives

Directives
Si 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 1, 2014 401 / 436
AngularJS Directives

Directives
Nous 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 1, 2014 402 / 436


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 1, 2014 403 / 436
AngularJS Directives

Directives
Modification 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 1, 2014 404 / 436
AngularJS Directives

Directives
Les 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 1, 2014 405 / 436
Dart/TypeScript Dart

Dart – Introduction

Objectif : Proposer un nouveau langage côté client (et serveur) qui


permette 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 1, 2014 406 / 436
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 1, 2014 407 / 436
Dart/TypeScript Dart

Dart – Introduction

Utilisation d’un script Dart dans du code HTML :


import 'dart:html';

void main() {
querySelector("#text").text = "Truc";
}

Dans ce code, nous utilisons la librairie html pour interagir avec le DOM.

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 408 / 436
Dart/TypeScript Dart

Dart – Introduction

Un autre exemple :
import 'dart:html';

void main() {
querySelector("#text").text = "Truc";
querySelector("#text").onClick.listen(textClick);
}

void textClick(Event e) {
String txt = querySelector("#text").text;
querySelector("#text").text="["+txt+"]";
}

Notez que certaines variables sont typées statiquement.


. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 409 / 436
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 1, 2014 410 / 436
Dart/TypeScript Dart

Dart – Programmation objet


Quelques 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 1, 2014 411 / 436
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});
querySelector("#text").text = "${p1} ${p2} ${p3} ${p4}";
}

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 412 / 436
Dart/TypeScript Dart

Dart – Programmation objet


Il 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;
querySelector("#text").text = "${pixel} ${point}";
}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 413 / 436
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 1, 2014 414 / 436
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]";


querySelector("#text").text =
converters.map((c) => c.convert(txt))
.join(";");
}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 415 / 436
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);
querySelector("#text").text = nameSet.join(";");

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 416 / 436
Dart/TypeScript Dart

Dart – Les librairies

dart:core Numbers, Collections, Strings, and More


dart:async Asynchronous Programming
dart:math Math and Random
dart:html Browser-Based Apps
dart:isolate Concurrency with Isolates
dart:io I/O for Command-Line Apps
dart:convert Encoding and Decoding Objects
dart:collection Collection support
dart:web_gl 3D programming in the browser
(Voir les autres librairies sur le site de Dart)

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 417 / 436
Dart/TypeScript Dart

Dart – Les librairies

import 'dart:html';
import 'dart:convert';

void main() {
var jsonString = '''[
{ "name" : "bob", "age" : 22 },
{ "name" : "arthur", "age": 45 }
]''';
var persons = JSON.decode(jsonString);
var list = persons.map(
(p) => "<li><b>${p["name"]}</b> : ${p["age"]}</li>");
querySelector("#text").innerHtml
= "<ul>${list.join()}</ul>";
}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 418 / 436
Dart/TypeScript Dart

Dart et Polymer

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 419 / 436
Dart/TypeScript Dart

Dart et Polymer
<!DOCTYPE html>
<html>
<head>
<link rel="import" href="clickcounter.html">
<script type="application/dart">
export 'package:polymer/init.dart';
</script>
<script src="packages/browser/dart.js"
type="text/javascript">
</script>
</head>
<body>
<click-counter count="5"></click-counter>
</body>
</html>
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 420 / 436
Dart/TypeScript Dart

Dart et Polymer

<polymer-element
name="click-counter"
attributes="count">
<template>
<div>
<button on-click="{{increment}}">Click me</button>
<span>(click count: {{count}})</span>
</div>
</template>
<script type="application/dart"
src="clickcounter.dart">
</script>
</polymer-element>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 421 / 436
Dart/TypeScript Dart

Dart et Polymer

import 'package:polymer/polymer.dart';

@CustomTag('click-counter')
class ClickCounter extends PolymerElement {
@published int count = 0;

ClickCounter.created() : super.created() {
}

void increment() {
count++;
}
}

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 422 / 436
Dart/TypeScript Dart

Dart et Polymer

import 'package:polymer/polymer.dart';

@CustomTag('click-counter')
class ClickCounter extends PolymerElement {
@published int count = 0;

ClickCounter.created() : super.created() {
}

void increment() {
count++;
}
}

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 423 / 436
Dart/TypeScript Dart

Dart et Polymer

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 424 / 436
Dart/TypeScript Dart

Dart et Polymer

<polymer-element name="item-list">
<template>
<ul>
<template repeat="{{item in items}}">
<li>{{ item }}</li>
</template>
<input type="text" value="{{item}}">
<button on-click="{{addItem}}">Ajouter</button>
</ul>
</template>
<script type="application/dart" src="itemlist.dart">
</script>
</polymer-element>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 425 / 436
Dart/TypeScript Dart

Dart et Polymer
@CustomTag('item-list')
class ItemList extends PolymerElement {
@observable String item;

final List items =


toObservable(['machin', 'chose', 'truc']);

ItemList.created() : super.created() { }

void addItem(Event e, var detail, Node target) {


items.add(item);
item = "";
}

}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 426 / 436
Dart/TypeScript Dart

Dart et Polymer

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 427 / 436
Dart/TypeScript Dart

Dart et Polymer

<polymer-element name="point-input">
<template>
<input type="text" value="{{point.x}}">
<input type="text" value="{{point.y}}">
</template>
</polymer-element>

<polymer-element name="point-display">
<template>
[{{ point.x }}, {{ point.y }}]
</template>
</polymer-element>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 428 / 436
Dart/TypeScript Dart

Dart et Polymer

<polymer-element name="point-widget">
<template>
<point-display point="{{point}}"></point-display>
<point-input point="{{point}}"></point-input>
</template>
</polymer-element>

. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 429 / 436
Dart/TypeScript Dart

Dart et Polymer
@CustomTag('point-display')
class PointDisplay extends PolymerElement {
@published Point point;

PointDisplay.created() : super.created() {
}
}

@CustomTag('point-widget')
class PointWidget extends PolymerElement {
@observable Point point = new Point("0","0");

PointWidget.created() : super.created() {
}
}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 430 / 436
Dart/TypeScript Dart

Dart et Polymer
@CustomTag('point-display')
class PointDisplay extends PolymerElement {
@published Point point;

PointDisplay.created() : super.created() {
}
}

@CustomTag('point-widget')
class PointWidget extends PolymerElement {
@observable Point point = new Point("0","0");

PointWidget.created() : super.created() {
}
}
. . . . . . . . . . . . . . . . . . . .
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
Bertrand Estellon (AMU) Développement Web 2 April 1, 2014 431 / 436
Dart/TypeScript TypeScript

TypeScript

Objectif : Proposer un nouveau langage côté client qui permette le


dé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 1, 2014 432 / 436
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 1, 2014 433 / 436
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 1, 2014 434 / 436
Dart/TypeScript TypeScript

TypeScript
Le 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 1, 2014 435 / 436
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 1, 2014 436 / 436