Dveloppement Web 2
Bertrand Estellon
Aix-Marseille Universit
April 26, 2013
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 1 / 423
. . . . . .
PHP Bases du langage Introduction
Web Dynamique
Wikipedia, etc.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 3 / 423
. . . . . .
PHP Bases du langage Introduction
Le Web statique
Protocole HTTP
Client
Serveur
1. Je veux toto.html
2. Contenu de toto.html
Requte :
GET /toto.html HTTP/1.0
Host: example.com
Referer: http://example2.com/
User-Agent: Mozilla/5.0 (X11; U; Linux
x86_64; fr; rv:1.9.0.4) Gecko/2008111217
Fedora/3.0.4-1.fc10 Firefox/3.0.4
Rponse :
HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Server: Apache/0.8.4
Content-Type: text/html
Content-Length: 59
Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modied: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>page dexemple.</P>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 4 / 423
. . . . . .
PHP Bases du langage Introduction
Le Web dynamique
Protocole HTTP
Client
Serveur
1. Je veux toto.html
2. Contenu de toto.html
Requte :
GET /toto.html HTTP/1.0
Host: example.com
Referer: http://example2.com/
User-Agent: Mozilla/5.0 (X11; U; Linux
x86_64; fr; rv:1.9.0.4) Gecko/2008111217
Fedora/3.0.4-1.fc10 Firefox/3.0.4
Rponse :
HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Server: Apache/0.8.4
Content-Type: text/html
Content-Length: 59
Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modied: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>page dexemple.</P>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 5 / 423
. . . . . .
PHP Bases du langage Introduction
Le Web dynamique
Protocole HTTP
Client
Serveur
1. Je veux toto.php
2. Sortie de l'excution
de toto.html
Requte :
GET /toto.php?n1=10&n2=15 HTTP/1.0
Host: example.com
Referer: http://example2.com/
User-Agent: Mozilla/5.0 (X11; U; Linux
x86_64; fr; rv:1.9.0.4) Gecko/2008111217
Fedora/3.0.4-1.fc10 Firefox/3.0.4
Rponse :
HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Server: Apache/0.8.4
Content-Type: text/html
Content-Length: 59
Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modied: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>Rsultat : 25.</P>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 6 / 423
. . . . . .
PHP Bases du langage Introduction
Le Web dynamique
Protocole HTTP
Client
Serveur
1. Je veux toto.php
2. Sortie de l'excution
de toto.html
Requte :
POST /toto.php HTTP/1.0
Host: example.com
Referer: http://example2.com/
User-Agent: Mozilla/5.0 (X11; U; Linux
x86_64; fr; rv:1.9.0.4) Gecko/2008111217
Fedora/3.0.4-1.fc10 Firefox/3.0.4
n1=10&n2=15
Rponse :
HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Server: Apache/0.8.4
Content-Type: text/html
Content-Length: 59
Expires: Sat, 01 Jan 2000 00:59:59 GMT
Last-modied: Fri, 09 Aug 1996 14:21:40
GMT
<TITLE>Exemple</TITLE>
<P>Rsultat : 25.</P>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 7 / 423
. . . . . .
PHP Bases du langage Introduction
Pourquoi PHP ?
Une solution :
Open-source et multi-plateforme
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 8 / 423
. . . . . .
PHP Bases du langage Introduction
Premier programme
Un type;
Les variables ne sont pas types mais les valeurs ont un type :
array : array(1,2,3)
TRUE sinon.
FALSE sinon.
Oprateur de Cast :
$var2 = (nouveau_type)$var
Truc
Toto
Bonjour
Bip
Salut
Truc
Toto
Bonjour
Bip
Salut
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 38 / 423
. . . . . .
PHP Bases du langage Instructions, oprations, variables
switch
<?
switch ($a) {
case 0 :
echo '0';
break;
case 1 :
echo '1';
break;
default :
echo 'default';
}
?>
<?
switch ($a) {
case "a" :
echo 'a';
break;
case "b" :
echo 'b';
break;
default :
echo 'default';
}
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 39 / 423
. . . . . .
PHP Bases du langage Instructions, oprations, 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 dun paramtre par rfrence.
...
2 La valeur par dfaut du paramtre est 5.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 40 / 423
. . . . . .
PHP Bases du langage Instructions, oprations, variables
Porte des variables
<?
function modif() {
$var = "salut";
}
$var = "toto";
var_dump($var); // 1
modif();
var_dump($var); // 2
?>
<?
function modif() {
global $var;
$var = "salut";
}
$var = "toto";
var_dump($var); // 3
modif();
var_dump($var); // 4
?>
...
1 string(4) "toto"
...
2 string(4) "toto"
...
3 string(4) "toto"
...
4 string(5) "salut"
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 41 / 423
. . . . . .
PHP Bases du langage Chanes de caractres
Achage des chanes
<?
$a = "bonjour";
$b = "salut";
$c = 2;
echo "$a $b\n"; // 1
echo '$a $b\n'; // 2
echo "\n";
echo "$a $b{$c}\n"; // 3
echo date('d')."\n"; // 4
echo "date('d')\n"; // 5
?>
...
1 bonjour salut
...
2 $a $b\n
...
3 bonjour l
...
4 18
...
5 date('d')
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 42 / 423
. . . . . .
PHP Bases du langage Chanes de caractres
Les caractres
<?
$chaine="ABCDEF";
for ($i = 0; $i<strlen($chaine); $i++) {
echo ord($chaine{$i})."\n"; // 1
}
$chaine="";
for ($i = 0; $i<6; $i++) {
$c = rand(65,90);
$chaine.=chr($c);
}
echo "$chaine\n"; // 2
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 43 / 423
...
1
65
66
67
68
69
70
...
2 GZXNIY
. . . . . .
PHP Bases du langage Chanes de caractres
Achage format
<?
$chaine = "Bonjour";
$nombre = "65";
$valeur = "65535";
$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");
vprintf("%c %c %c\n", $a); // 6
$b = vsprintf("%c %c %c", $a);
var_dump($b); // 7
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 44 / 423
...
1 Bonjour
...
2 A 65
...
3 177777
...
4 ##12.235
...
5 string(8)
##12.235
...
6 A B C
...
7 string(5) A B C
. . . . . .
PHP Bases du langage Chanes de caractres
Modication 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) Dveloppement Web 2 April 26, 2013 45 / 423
. . . . . .
PHP Bases du langage Chanes de caractres
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) Dveloppement Web 2 April 26, 2013 46 / 423
. . . . . .
PHP Bases du langage Chanes de caractres
Caractres spciaux dans les URL et en XHTML
<?
$a="<b>dtruire</b>";
$b=htmlentities($a);
echo $b."\n"; /* 1 */
$c=html_entity_decode($b);
echo $c."\n"; /* 2 */
$b=strip_tags($a);
echo $b."\n"; /* 3 */
$b=urlencode($a);
echo $b."\n"; /* 4 */
$c=urldecode($b);
echo $c."\n"; /* 5 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 47 / 423
...
1 <b>détruire<b>
...
2 <b>dtruire</b>
...
3 dtruire
...
4 %3Cb%3Ed%E9truire%3C%2Fb%3E
...
5 <b>dtruire</b>
. . . . . .
PHP Bases du langage Chanes de caractres
Recherche de sous-chanes
<?
$ch = "bonjour salut bonjour";
$nb = substr_count($ch, "bonjour");
var_dump($nb); /* 1 */
$ch2 = str_replace("bonjour", "salut", $ch);
var_dump($ch2); /* 2 */
$pos = strpos($ch,"salut");
var_dump($pos); /* 3 */
$pos = strpos($ch,"Salut");
var_dump($pos); /* 4 */
$pos = stripos($ch,"Salut");
var_dump($pos); /* 5 */
$ch3 = substr($ch,8,5);
var_dump($ch3); /* 6 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 48 / 423
...
1 int(2)
...
2 string(17) "salut salut salut"
...
3 int(8)
...
4 bool(false)
...
5 int(8)
...
6 string(5) "salut"
. . . . . .
PHP Bases du langage Chanes de caractres
Comparaison de chanes de caractres
<?
$ch1=11;
$ch2="11toto";
var_dump($ch1); /* 1 */
var_dump($ch2); /* 2 */
var_dump($ch1==$ch2); /* 3 */
var_dump($ch1===$ch2); /* 4 */
var_dump("$ch1"==$ch2); /* 5 */
var_dump($ch1*$ch2); /* 6 */
var_dump("$ch1"*$ch2); /* 7 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 49 / 423
...
1 int(11)
...
2 string(6) "11toto"
...
3 bool(true)
...
4 bool(false)
...
5 bool(false)
...
6 int(121)
...
7 int(121)
. . . . . .
PHP Bases du langage Chanes de caractres
Comparaison de chanes de caractres
<?
var_dump(strcmp("toto2","toto2"));
var_dump(strcmp("toto12","toto2"));
var_dump(strcmp("toto2","toto12"));
var_dump(strcasecmp("toto","ToTo"));
var_dump(strnatcmp("toto12","toto2"));
?>
<?
$ch1 = "abc";
$ch2 = "bcd";
if ($ch1 < $ch2) echo "<"; else echo ">";
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 50 / 423
int(0)
...
1
int(-1)
...
2
int(1)
...
3
int(0)
...
4
int(1)
...
5
. . . . . .
PHP Bases du langage Tableaux
Tableaux
array(3) {
[2] => int(12)
[4] => int(23)
[toto] => oat(12.13)
[cl] => valeur
}
...
2 int(3)
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 51 / 423
. . . . . .
PHP Bases du langage Tableaux
Tableaux
array(5) {
[12] => int(3)
[a] => oat(12.12)
[13] => int(15)
[14] => string(1) c
[1] => int(2)
}
...
2
array(4) {
[0] => int(1)
[1] => int(2)
[2] => int(3)
[3] => int(4)
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 52 / 423
. . . . . .
PHP Bases du langage Tableaux
Intervalles
<?
$a=range(1,4);
var_dump($a); /* 1 */
$a=range(0,30,10);
var_dump($a); /* 2 */
$a=range('d','g');
var_dump($a); /* 3 */
?>
...
1
array(4) {
[0] => int(1)
[1] => int(2)
[2] => int(3)
[3] => int(4)
}
...
2
array(4) {
[0] => int(0)
[1] => int(10)
[2] => int(20)
[3] => int(30)
}
...
3
array(4) {
[0] => string(1) d
[1] => string(1) e
[2] => string(1) f
[3] => string(1) g
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 53 / 423
. . . . . .
PHP Bases du langage Tableaux
R-indexation
<?
$a = array(1,"a"=>2);
$a[] = 3;
var_dump($a); /* 1 */
unset($a[1]);
$a[] = 4;
var_dump($a); /* 2 */
$a = array_values($a);
var_dump($a); /* 3 */
?>
...
1
array(3) {
[0] => int(1)
[a] => int(2)
[1] => int(3)
}
...
2
array(3) {
[0] => int(1)
[a] => int(2)
[2] => int(4)
}
...
3
array(3) {
[0] => int(1)
[1] => int(2)
[2] => int(4)
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 54 / 423
. . . . . .
PHP Bases du langage Tableaux
Tableaux multidimensionnels
<?
$a = array(12=>array(1,15=>2), 15=>2);
var_dump($a); /* 1 */
var_dump($a[12][15]); /* 2 */
$a[12][20] = 2;
var_dump($a[12]); /* 3 */
?>
...
1
array(2) {
[12]=> array(3) {
[0]=> int(1)
[15]=> int(2)
}
[15]=> int(2)
}
...
3
array(4) {
[0] => int(1)
[15] => int(2)
[20] => int(2)
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 55 / 423
...
2 int(2)
. . . . . .
PHP Bases du langage Tableaux
foreach
1=>12
a=>12.12
c=>3
2=>4
...
2
12
12.12
3
4
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 56 / 423
. . . . . .
PHP Bases du langage Tableaux
reset et each
<?
$a = array(1=>12, "a"=>12.12, "c"=>3, 4);
reset($a);
while ($tab=each($a))
echo $tab[0]."=>".$tab[1]."\n"; /* 1 */
reset($a);
while ($tab=each($a))
echo $tab["key"]."=>".$tab["value"]."\n"; /* 1 */
?>
...
1
1=>12
a=>12.12
c=>3
2=>4
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 57 / 423
. . . . . .
PHP Bases du langage Tableaux
list
1=>12
a=>12.12
c=>3
2=>4
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 59 / 423
. . . . . .
PHP Bases du langage Tableaux
Manipulation dun tableau
$var = array_pop($tab) :
dpile une valeur situe la n du tableau
$var = array_shift($tab) :
supprime et retourne la premire valeur du tableau
array_unshift
array_shift
array_push
array_pop
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 60 / 423
. . . . . .
PHP Bases du langage Tableaux
Manipulation dun tableau
<?
$a=array(1, "a"=>2, 3);
array_push($a, 12.12);
array_unshift($a, "toto");
var_dump($a); /* 1 */
$b = array_pop($a);
var_dump($b); /* 2 */
$c = array_shift($a);
var_dump($c); /* 3 */
?>
...
1
array(5) {
[0] => string(4) toto
[1] => int(1)
[a] => int(2)
[2] => int(3)
[3] => oat(12.12)
}
...
2 oat(12.12)
...
3 string(4) toto
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 61 / 423
. . . . . .
PHP Bases du langage Tableaux
Fusion de tableaux
<?
$a=array(1,"a"=>2, 3, "b"=>4, 4=>5);
$b=array("c"=>6, 1=>7, 8, "b"=>9);
$c=array_merge($a,$b);
print_r($c); /* 1 */
$c=array_merge_recursive($a,$b);
print_r($c); /* 2 */
?>
...
1
Array (
[0] => 1
[a] => 2
[1] => 3
[b] => 9
[2] => 5
[c] => 6
[3] => 7
[4] => 8
)
...
2
Array (
[0] => 1
[a] => 2
[1] => 3
[b] => Array ( [0] => 4 [1] => 9 )
[2] => 5
[c] => 6
[3] => 7
[4] => 8
)
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 62 / 423
. . . . . .
PHP Bases du langage Tableaux
Intersection et dirence de tableaux
<?
$a=array(1,"a"=>2, 3=>3, "b"=>4, 4=>5);
$b=array("c"=>1, 1=>3, 4);
$c=array_intersect($a,$b);
print_r($c); /* 1 */
$c=array_diff($a,$b);
print_r($c); /* 2 */
?>
...
1
Array (
[0] => 1
[3] => 3
[b] => 4
)
...
2
Array (
[a] => 2
[4] => 5
)
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 63 / 423
. . . . . .
PHP Bases du langage Tableaux
Tri de tableaux indics
<?
$a=array("a10", "b11", "b"=>"a9", "C12", "c12");
sort($a);
print_r($c); /* 1 */
rsort($a);
print_r($c); /* 2 */
natsort($a);
print_r($c); /* 3 */
natcasesort($a);
print_r($c); /* 4 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 64 / 423
...
1
Array (
[0] => C12
[1] => a10
[2] => a9
[3] => b11
[4] => c12
)
...
2
Array (
[0] => c12
[1] => b11
[2] => a9
[3] => a10
[4] => C12
)
...
1
Array (
[4] => C12
[2] => a9
[3] => a10
[1] => b11
[0] => c12
)
...
2
Array (
[2] => a9
[3] => a10
[1] => b11
[0] => c12
[4] => C12
)
. . . . . .
PHP Bases du langage Tableaux
Tri personalis
<?
function comparaison($a, $b) {
return ($a[0]+$a[1]) - ($b[0]+$b[1]);
}
$c = array(array(1,5),array(2,2), array(1,4));
usort($c, "comparaison");
print_r($c); /* 1 */
?>
...
1
Array (
[0] => Array ([0] => 2 [1] => 2)
[1] => Array ([0] => 1 [1] => 4)
[2] => Array ([0] => 1 [1] => 5)
)
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 65 / 423
. . . . . .
PHP Bases du langage Tableaux
Tri de tableaux associatifs
<?
$a = array("a"=>"c", "b"=>"a", "c"=>"d");
asort($a);
print_r($a); /* 1 */
arsort($a);
print_r($a); /* 2 */
sort($a);
print_r($a); /* 3 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 66 / 423
...
1
Array (
[b] => a
[a] => c
[c] => d
)
...
2
Array (
[c] => d
[a] => c
[b] => a
)
...
3
Array (
[0] => a
[1] => c
[2] => d
)
. . . . . .
PHP Bases du langage Tableaux
Tri de tableaux associatifs
<?
$a = array("a"=>"c", "b"=>"a", "c"=>"d");
ksort($a);
print_r($a); /* 1 */
krsort($a);
print_r($a); /* 2 */
?>
...
1
Array (
[a] => c
[b] => a
[c] => d
)
...
2
Array (
[c] => d
[b] => a
[a] => c
)
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 67 / 423
. . . . . .
PHP Bases du langage Tableaux
Tri de tableaux associatifs
<?
function compar1($a,$b) {
return ($a[0]+$a[1])-($b[0]+$b[1]);
}
function compar2($a,$b) {
return strlen($a) - strlen($b);
}
$a = array("aa"=>array(0,1),
"aaa"=>array(2,2),
"a"=>array(1,2));
uasort($a,"compar1");
print_r($a); /* 1 */
uksort($a,"compar2");
print_r($a); /* 2 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 68 / 423
...
1
Array (
[aa] => Array([0] => 0 [1] => 1)
[a] => Array([0] => 1 [1] => 2)
[aaa] => Array([0] => 2 [1] => 2)
)
...
2
Array (
[a] => Array([0] => 1 [1] => 2)
[aa] => Array([0] => 0 [1] => 1)
[aaa] => Array([0] => 2 [1] => 2)
)
. . . . . .
PHP Bases du langage Tableaux
Tri de tableaux associatifs
<?
function filtre($a) {
return ($a[0] <= $a[1]);
}
$a = array("a"=>array(0,1),
"b"=>array(3,2),
"c"=>array(1,2),
"d"=>array(1,0));
$selection = array_filter($a, "filtre");
print_r($selection); /* 1 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 69 / 423
...
1
Array (
[a] => Array([0] => 0 [1] => 1)
[c] => Array([0] => 1 [1] => 2)
)
. . . . . .
PHP Bases du langage Tableaux
Appliquer une fonction un tableau
<?
function affichage($a) {
echo "<b>".$a[0]."</b> : ".$a[1]."<br/>\n"; /* 1 */
}
$a = array(array(0,1),
array(3,2),
array(1,2),
array(1,0));
array_walk($a, "affichage");
?>
...
1
<b>0</b> : 1<br/>
<b>3</b> : 2<br/>
<b>1</b> : 2<br/>
<b>1</b> : 0<br/>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 70 / 423
. . . . . .
PHP Bases du langage Tableaux
Chanes et tableaux
<?
$ch = "J'aime le PHP. Vive le web!";
$tab = explode(' ',$ch);
print_r($tab); /* 1 */
$tab = explode('.',$ch);
print_r($tab); /* 2 */
$tab = array("J'aime", "le", "PHP.");
$ch = implode(" ",$tab);
echo $ch."\n"; /* 3 */
$ch = implode("--",$tab);
echo $ch."\n"; /* 4 */
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 71 / 423
...
1
Array (
[0] => Jaime
[1] => le
[2] => PHP.
[3] => Vive
[4] => le
[5] => web!
)
...
2
Array (
[0] => Jaime le PHP
[1] => Vive le web!
)
...
3 Jaime le PHP.
...
4 Jaime- -le- -PHP.
. . . . . .
PHP Bases du langage Tableaux
Autres fonctions utiles sur les tableaux
Fichier index.html
<html>
<body>
<form method="post" action="traitement.php">
<label>Nom : </label>
<input type="text" name="nom"/>
<input type="submit" value="Envoyer"/>
</form>
</body>
</html>
Fichier traitement.php
<html>
<body>
Bonjour <? echo $_POST['nom']; ?>.</br>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 78 / 423
Requte :
Rponse :
POST traitement.php
...
nom=Superman
...
Bonjour Superman.
...
. . . . . .
PHP Formulaires Variables $_POST et $_GET
Variable $_POST
GET index.php
contenu de
index.php
POST traitement.php
...
nom=Superman
Bonjour Superman
Client Serveur
Saisie du nom
Clic sur "Envoyer"
Gnration de
la page par PHP
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 79 / 423
. . . . . .
PHP Formulaires Variables $_POST et $_GET
Variable $_GET
Fichier index.html
<html>
<body>
<form method="get" action="traitement.php">
<label>Nom : </label>
<input type="text" name="nom"/>
<input type="submit" value="Envoyer"/>
</form>
</body>
</html>
Fichier traitement.php
<html>
<body>
Bonjour <? echo $_GET['nom']; ?>.</br>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 80 / 423
Requte :
Rponse :
GET traitement.php?nom=superman
...
...
Bonjour Superman.
...
. . . . . .
PHP Formulaires Variables $_POST et $_GET
Variable $_GET
GET index.php
contenu de
index.php
GET traitement.php
?nom=Superman
...
Bonjour Superman
Client Serveur
Saisie du nom
Clic sur "Envoyer"
Gnration de
la page par PHP
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 81 / 423
. . . . . .
PHP Formulaires Applications
Bouton radio
Fichier index.html :
<html>
<body>
<form method="post" action="traitement.php">
<input type="radio" name="sexe" value="homme">Homme</br>
<input type="radio" name="sexe" value="femme">Femme</br>
<input type="submit" value="Envoyer"/>
</form>
</body>
</html>
Fichier traitement.php :
<html>
<body>
<? if ($_POST['sexe']==='homme') { ?>
Bonjour, vous etes un homme.
<?} else {?>
Bonjour, vous etes une femme.
<? } ?>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 82 / 423
. . . . . .
PHP Formulaires Applications
Avec un seul chier
<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) Dveloppement Web 2 April 26, 2013 83 / 423
. . . . . .
PHP Formulaires Applications
Valeurs multiples et checkboxes
Fichier index.html :
<html>
<body>
<form method="post" action="traitement.php">
<input type="checkbox" name="choix[]" value="A">A</br>
<input type="checkbox" name="choix[]" value="B">B</br>
<input type="checkbox" name="choix[]" value="C">C</br>
<input type="submit" value="Envoyer"/>
</form>
</body>
</html>
Fichier traitement.php :
<html>
<body>
Vous avez coche :
<? foreach ($_POST['choix'] as $v)
echo "$v "; ?>
<br/>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 84 / 423
Vous avez coch : A C
. . . . . .
PHP Formulaires Applications
Maintient de ltat 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) Dveloppement Web 2 April 26, 2013 85 / 423
. . . . . .
PHP Formulaires Applications
Maintient de ltat 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) Dveloppement Web 2 April 26, 2013 86 / 423
. . . . . .
PHP Formulaires Transfert de chiers
Transfert de chiers
<html>
<body>
<form enctype="multipart/form-data" method="post"
action="<? echo $_SERVER["PHP_SELF"]; ?>">
<input type="file" name="fichier" />
<input type="submit" value="Envoyer" />
</form>
<? var_dump($_FILES); /* 1 */ ?>
</body>
</html>
...
1
array(1) {
[chier]=> array(5) {
[name]]=> string(3) a.c
[type]=> string(10) text/plain
[tmp_name]=> string(14) /tmp/phpi5JOt8
[error]=> int(0)
[size]=> int(185)
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 87 / 423
. . . . . .
PHP Formulaires Transfert de chiers
Transfert de chiers
<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) Dveloppement Web 2 April 26, 2013 88 / 423
. . . . . .
PHP Formulaires Transfert de chiers
Transfert de chiers
Les erreurs possibles :
UPLOAD_ERR_OK (valeur 0) :
pas derreur
UPLOAD_ERR_INI_SIZE (valeur 1) :
la taille du chier dpasse la valeur prsente dans le chier php.ini.
UPLOAD_ERR_FORM_SIZE (valeur 2) :
la taille du chier dpasse celle xe dans le formulaire
(champ cach MAX_FILE_SIZE).
UPLOAD_ERR_PARTIAL (valeur 3) :
le chier a t partiellement tlcharg.
UPLOAD_ERR_NO_FILE (valeur 4) :
aucun chier na t tlcharg.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 89 / 423
. . . . . .
PHP Fichiers Ouverture
Ouverture dun chier
<?
$id = fopen("toto.txt", "w");
var_dump($id); /* 1 */
fclose($id);
var_dump($id); /* 2 */
$id = tmpfile();
var_dump($id); /* 3 */
fclose($id);
var_dump($id); /* 4 */
?>
Problme de concurrence :
Plusieurs clients demandent une page simultanment
deux scripts modient un chier en mme temps
Conit
Copie de chiers :
<?
$res = copy("liste.txt", "liste2.txt");
if ($res===FALSE) die("erreur");
?>
Renommer un chier :
<?
$res = rename("liste.txt", "liste2.txt");
if ($res===FALSE) die("erreur");
?>
Supprimer un chier :
<?
$res = unlink("liste.txt");
if ($res===FALSE) die("erreur");
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 99 / 423
. . . . . .
PHP Fichiers Manipulations de chiers
Manipulations de chiers
Existence :
<?
if (file_exists("liste.txt"))
echo "le fichier existe";
else echo "le fichier n'existe pas";
?>
basename("img/truc/toto.php") = toto.php
Attention :
<?
header("HTTP/1.0 404 Not Found");
echo "Bienvenue"; // "Bienvenue" est envoy au client...
exit; // trop tard !
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 104 / 423
. . . . . .
PHP Headers Redirection
Redirection
application/ogg : Ogg
application/pdf : PDF
application/xhtml+xml : XHTML
application/x-shockwave-ash : Flash
Chaque site peut crire un nombre limit de cookies sur chaque client
Attention :
La suppression du cookie est eective au rechargement de la page.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 112 / 423
. . . . . .
PHP Cookies et sessions Cookies
Tableaux associatifs et cookies
Exemple avec des tableaux associatifs :
Utiliser lhritage
Search : recherche
...
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 161 / 423
. . . . . .
PHP Modle-Vue-Contrleur Les vues
Framework PHP
Il existe des frameworks PHP qui permettent de mettre en place plus
facilement le modle MVC :
Zend
Symfony
CodeIgniter
CakePHP...
Ces frameworks proposent :
Organisation (contrleur/actions/vues);
Internationalisation;
Systmes de template...
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 162 / 423
. . . . . .
PHP Modle-Vue-Contrleur Les vues
Systmes 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) Dveloppement Web 2 April 26, 2013 163 / 423
. . . . . .
PHP Base de donnes PDO
PDO
PDO (PHP Data Objects) est une interface pour accder une base de
donnes depuis PHP. Elle gre la connexion, lenvoie des requtes, la
dconnexion la base de donnes. Elle permet de changer plus facilement
de systme de gestion de bases de donnes.
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 donnes.");
$this->createDataBase();
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 164 / 423
. . . . . .
PHP Base de donnes Les requtes et fonctions utiles
PDO
Une fois linstance de PDO construite, vous eectuez des requtes avec :
quote : Protge une chane pour lutiliser dans une requte SQL PDO
<?
$string = 'Chaine \' particulire';
print "non chappe : $string\n";
print "chappe :" . $bd->quote($string) . "\n";
?>
Chaine non chappe : Chaine particulire
Chaine chappe : Chaine particulire
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 169 / 423
. . . . . .
PHP Base de donnes Les requtes et fonctions utiles
Base de donnes du projet
Les trois tables utilises 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) Dveloppement Web 2 April 26, 2013 170 / 423
. . . . . .
PHP Base de donnes Les requtes et fonctions utiles
Exemple : sauvegarde dun 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) Dveloppement Web 2 April 26, 2013 171 / 423
. . . . . .
PHP Base de donnes Les requtes 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) Dveloppement Web 2 April 26, 2013 172 / 423
. . . . . .
PHP Base de donnes Mapping objet-relationnel (ORM)
Mapping objet-relationnel (ORM)
Les besoins :
...
Quelques solutions en PHP :
Propel
Doctrine
Redbean
...
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 173 / 423
. . . . . .
PHP Base de donnes Mapping objet-relationnel (ORM)
Redbean Introduction
Initialisation de la connexion la base de donnes :
<?
$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 donnes :
<?
R::nuke();
?>
Cration et sauvegarde dun bean :
<?
$user = R::dispense('user');
$user->nickname = $nickname;
$user->password = $password;
R::store($user);
?>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 174 / 423
. . . . . .
PHP Base de donnes Mapping objet-relationnel (ORM)
Redbean Chargement des beans
Chargement dun bean partir de son identiant :
<?
$user = R::load('user', $_SESSION['id']);
/* retourne NULL si le bean n'a pas t trouv. */
?>
Charger un bean dans la base de donnes partir dune requte :
<?
$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) Dveloppement Web 2 April 26, 2013 175 / 423
. . . . . .
PHP Base de donnes Mapping objet-relationnel (ORM)
Redbean One-to-many
Association one-to-many entre les sondages et les rponses :
<?
$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) Dveloppement Web 2 April 26, 2013 176 / 423
. . . . . .
PHP Base de donnes Mapping objet-relationnel (ORM)
Redbean One-to-many
Le chargement de lintgralit 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) Dveloppement Web 2 April 26, 2013 177 / 423
. . . . . .
JavaScript Introduction
JavaScript
JavaScript est un langage de programmation initialement utilis pour crer
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) Dveloppement Web 2 April 26, 2013 178 / 423
. . . . . .
JavaScript Dclaration des fonctions
JavaScript Les fonctions
Il est possible de dnir 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) Dveloppement Web 2 April 26, 2013 179 / 423
. . . . . .
JavaScript Les variables
JavaScript Les variables
Par dfaut, les variables non-dclares sont globales :
function ajouter(a) { total += a; }
total = 0; ajouter(2); ajouter(4); alert(total);
Pour dclarer 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) Dveloppement Web 2 April 26, 2013 180 / 423
. . . . . .
JavaScript Les types
JavaScript Les types
En JavaScript, les types sont associs aux valeurs :
var v = "toto"; // variable contient une chane
v = 'toto'; // variable contient une chane
v = 22; // variable contient un nombre
v = 22.12; // variable contient un nombre
v = true; // variable contient un boolen
v = ["toto", 22]; // variable contient un tableau
v = {name:"toto", age:22}; // variable contient un objet
Une variable qui na jamais t aect est undened :
var v; /* v est considr comme "undefined". */
La valeur null peut tre aecte une variable. Cela signie que la
variable existe mais sa valeur ne dsigne aucun objet :
var v = null;
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 181 / 423
. . . . . .
JavaScript Les types
JavaScript Les types
Il est possible de connatre le type de la valeur contenue dans une variable
laide 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) Dveloppement Web 2 April 26, 2013 182 / 423
. . . . . .
JavaScript Les booleans
JavaScript Les booleans
Aectation et utilisation des booleans :
var a = true;
var b = false;
var c = a || b;
if (c) {
alert(a && b);
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 183 / 423
. . . . . .
JavaScript Les nombres
JavaScript Les nombres
Les direntes oprations arithmtiques :
var v = 12;
var v = 2 + 4;
var v = 2 * 4;
var v = 4 / 2;
var v = 123 % 10;
v++; v--;
Les direntes aectations :
v=2; v+=2; v-=2; v*=2; v/=2; v%=2;
Les conversions entre chanes et nombres :
var v = parseInt("123");
var v = parseFloat("123.12");
var s = v.toString();
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 184 / 423
. . . . . .
JavaScript Les oprateurs
JavaScript Les comparaisons et oprateurs logiques
gal a == b vrai si a est gal b
identique a === b vrai si a et b sont gaux et ont le mme type
dirent a != b vrai si a est dirent de b
non identique a !== b vrai si a et b sont dirents
ou nont pas le mme 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
infrieur ou gal a <= b vrai si a est plus petit ou gal b
suprieur ou gal a >= b vrai si a est plus grand ou gal b
non !a vrai si a nest 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) Dveloppement Web 2 April 26, 2013 185 / 423
. . . . . .
JavaScript Les conditions et les boucles
JavaScript If/For/While/Continue/Break
var x = 2, y = 5;
if (x < y) document.write("<");
else document.write(">");
for (var i = 0; i < 10; i++) {
if (i == 4) continue;
document.write(i);
if (i > 7) break;
}
var i = 0;
while(i < 10) {
document.write(i);
i++;
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 186 / 423
. . . . . .
JavaScript Les conditions et les boucles
JavaScript Switch
function (x) {
switch (x) {
case 0 : alert("zro"); 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) Dveloppement Web 2 April 26, 2013 187 / 423
. . . . . .
JavaScript Les tableaux
JavaScript Les tableaux
Dclaration dun tableau :
var fleurs = new Array();
fleurs[0] = "Rose";
fleurs[1] = "Tulipe";
fleurs[2] = "Coquelicot";
/* ou */
fleurs = ["Rose", "Tulipe", "Coquelicot"];
Les mthodes et les proprits:
var length = fleurs.length;
var position = fleurs.indexOf("Tulipe");
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 188 / 423
. . . . . .
JavaScript Les tableaux
JavaScript Les tableaux
Parcourir un tableau :
for (var i = 0; i < fleurs.length; i++)
document.write(i+"->"+fleurs[i]);
for (var i in fleurs)
document.write(i+"->"+fleurs[i]);
for (var fleur of fleurs) /* Exprimental */
document.write(fleur);
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 189 / 423
. . . . . .
JavaScript Les chanes de caractres
JavaScript Les chanes de caractres
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 mthodes utiles sur les chanes de caractres :
charAt, charCodeAt, concat, contains, endsWith, indexOf, lastIndexOf,
match, replace, search, slice, split, startsWith, substr, substring,
toLowerCase, toString, toUpperCase, trim.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 190 / 423
. . . . . .
JavaScript Les fonctions
JavaScript Les fonctions
Il est possible daecter le code dune 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 dnition de la fonction).
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 191 / 423
. . . . . .
JavaScript Les fonctions
JavaScript Les fonctions
Les paramtres des fonctions sont passs par valeur donc chaque
paramtre 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) Dveloppement Web 2 April 26, 2013 192 / 423
. . . . . .
JavaScript Les fonctions
JavaScript Les fonctions
Une fonction peut retourner une fonction :
var getDisplayFunction = function(a) {
return function() { alert(a); }
}
var display3 = getDisplayFunction(3);
display3(); // affiche 3
Le code prcdent est quivalent au code suivant :
var getDisplayFunction3 = function() { var a = 3;
return function() { alert(a); }
}
var display3 = getDisplayFunction3();
display3(); // affiche 3
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 193 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
En JavaScript, il ny a pas de classe. Les instance sont cre directement :
person=new Object();
person.name="Bob";
person.age=22;
On peut galement utiliser une description littrale de lobjet :
person = {name : "Bob", age : 22};
Nous sommes en prsence de rfrences :
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) Dveloppement Web 2 April 26, 2013 194 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
En JavaScript, il ny 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 dajouter des proprits aprs la cration de lobjet :
var jim = new Person("jim", 45);
jim.friends = [bob, joe];
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 195 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
Des fonctions (ou mthodes) peuvent tre associes 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) Dveloppement Web 2 April 26, 2013 196 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
Il est galement possible dassocier des mthodes 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) Dveloppement Web 2 April 26, 2013 197 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
Attention, le code suivant ne fonctionne pas car, dans la mthode click, la
fonction notify nest appele sur un objet (dans ce cas, this contient une
rfrence vers lobjet Window) :
function Counter() {
...
this.notify = function() { this.count++; }
...
}
function click(callback) {
callback();
}
var counter = new Counter();
click(counter.notify);
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 198 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
Le code suivant fonctionne :
function Counter() {
...
this.notify = function() { this.count++; }
...
}
function click(callback) {
callback();
}
var counter = new Counter();
click(function() { counter.notify(); });
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 199 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 200 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 201 / 423
. . . . . .
JavaScript Les objets
JavaScript Les objets
Correction du code prcdent :
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) Dveloppement Web 2 April 26, 2013 202 / 423
. . . . . .
JavaScript Les prototypes
JavaScript Les prototypes
Le constructeur suivant associe des mthodes 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 nest 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) Dveloppement Web 2 April 26, 2013 203 / 423
. . . . . .
JavaScript Les prototypes
JavaScript Les prototypes
x = Math.abs(-2.23); // 2.23
x = Math.ceil(6.05); // 7
x = Math.oor(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
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) Dveloppement Web 2 April 26, 2013 213 / 423
. . . . . .
HTML, CSS, DOM HTML
HTML
Les documents HTML dcrivent une structure darbre :
<body>
<b>Liste : </b>
<ul>
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ul>
</body>
<body>
<b> <ul>
<li> <li> <li> Liste :
Element 1 Element 2 Element 3
Chaque balise peut possder des attributs :
<img src="toto.jpg" class="image">
<span class="alert">alerte</span>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 214 / 423
. . . . . .
HTML, CSS, DOM HTML
de HTML HTML5
Histoire de HTML :
1989-1992 : Origine
De nouveaux lments;
DOM Scripting;
1996 : CSS 1
1998 : CSS 2
E F : un lment F descendant de E
E > F : un lment F ls de E
un standard du W3C;
JQuery UI :
Librairie de widgets
Thmes
Eets
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 239 / 423
. . . . . .
Communication client/serveur AJAX
Ajax (Asynchronous JavaScript and XML)
Ajax est un acronyme pour Asynchronous JavaScript and XML.
Il est un ensemble de technologies libres couramment utilises :
DONE (4) : Le transfert des donnes est termin (ou erreur !).
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 244 / 423
. . . . . .
Communication client/serveur AJAX Les reqtes asynchrones
XMLHttpRequest : Requte asynchrone GET
Exemple de requte 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) Dveloppement Web 2 April 26, 2013 245 / 423
. . . . . .
Communication client/serveur AJAX Les reqtes asynchrones
XMLHttpRequest : Requte asynchrone POST
Exemple de requte 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) Dveloppement Web 2 April 26, 2013 246 / 423
. . . . . .
Communication client/serveur AJAX Les reqtes asynchrones
AJAX et jQuery
Exemple de requte 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 requte GET :
$.get("test.php", { 'choices[]': ["Jon", "Susan"]} );
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 247 / 423
. . . . . .
Communication client/serveur AJAX Sans serveur dynamique
Un exemple sans serveur dynamique : la problmatique
Nous souhaitons raliser le site suivant :
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 248 / 423
. . . . . .
Communication client/serveur AJAX Sans serveur dynamique
Un exemple sans serveur dynamique : les donnes
Nous avons sur notre serveur le chier 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) Dveloppement Web 2 April 26, 2013 249 / 423
. . . . . .
Communication client/serveur AJAX Sans serveur dynamique
Un exemple sans serveur dynamique : les donnes
Nous avons galement les images associs aux auteurs dans un rpertoire
image du serveur. De plus, pour chaque auteur, nous avons un chier de
la forme suivante :
{ "name" : "Victor Hugo",
"description" : "Victor Hugo, n le 26 fvrier 1802
Besanon et mort le 22 mai 1885
Paris, est un pote, dramaturge et
prosateur romantique considr comme
lun des plus importants crivains
de langue franaise. [wikipedia]",
"born" : "26 fvrier 1802, Besanon",
"died" : "22 mai 1885, Paris"
}
Le nom du chier est donn par les proprits description associes
chaque auteur dans le chier authors.json.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 250 / 423
. . . . . .
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>Dcs : </strong><span id="author_died"></span><br>
</div>
</div></div>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 251 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 252 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 253 / 423
. . . . . .
Communication client/serveur AJAX Avec un serveur crit en PHP
jQuery, AJAX, JSON et PHP
Ct serveur :
header('Content-type: application/json');
$a = array('nom'=>$_POST['nom'],
'maj'=>strtoupper($_POST['nom']));
echo json_encode($a);
Ct client :
$.ajax({
type: "post",
url: "server.php",
data: { nom : "bob" }
}).done(function( msg ) {
alert( msg['nom']+"=>"+msg['maj'] );
});
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 254 / 423
. . . . . .
Communication client/serveur AJAX Avec un serveur crit en PHP
Exemple : autocompletion
Autocompltion sur les mots du franais :
Nous allons utiliser :
La couleur jaune est associe aux lettres mal places mais prsentes
dans le mot trouver.
crer un compte;
sauthentier;
jouer;
Les clients peuvent voir les messages envoys par les autres clients;
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 280 / 423
. . . . . .
Communication client/serveur Comet Problmatique
Problmatique
Problme : En PHP, chaque requte du client est traite indpendamment.
Il ny a donc pas de :
...
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 281 / 423
. . . . . .
Communication client/serveur Comet Cration dun serveur avec Jetty
Jetty Cration dun serveur Web
Cration dun 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) Dveloppement Web 2 April 26, 2013 282 / 423
. . . . . .
Communication client/serveur Comet Cration dun serveur avec Jetty
Jetty Cration dun serveur Web
Gestion des sessions et mises en place de code spcique pour traiter les
requtes 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) Dveloppement Web 2 April 26, 2013 283 / 423
. . . . . .
Communication client/serveur Comet Le serveur
Jetty Classe ChatServer
public class ChatServer {
private List<User> users;
public ChatServer() { users = new ArrayList<User>(); }
public void addUser(User user) { users.add(user); }
public void sendMessage(String msg) {
for (User user : users) user.addMessage(msg);
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 284 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 285 / 423
. . . . . .
Communication client/serveur Comet Le serveur
Jetty Classe ChatServer
public abstract class ChatServlet extends HttpServlet {
protected ChatServer server;
public ChatServlet(ChatServer server) { this.server = server; }
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession(true);
User user = (User)session.getAttribute("user");
if (user==null) { user = new User(); server.addUser(user);
session.setAttribute("user", user);
}
String responses = doAction(user, req);
resp.getWriter().println(responses);
}
protected abstract String doAction(User user, HttpServletRequest req);
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 286 / 423
. . . . . .
Communication client/serveur Comet Le serveur
Jetty Classe SendServlet
public class SendServlet extends ChatServlet {
public SendServlet(ChatServer server) {
super(server);
}
@Override
protected String doAction(User user,
HttpServletRequest req) {
String msg = req.getParameter("msg");
if (msg!=null) server.sendMessage(msg);
return "\"ok\"";
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 287 / 423
. . . . . .
Communication client/serveur Comet Le serveur
Jetty Classe GetServlet
public class GetServlet extends ChatServlet {
public GetServlet(ChatServer server) {
super(server);
}
@Override
protected String doAction(User user,
HttpServletRequest req) {
String msg = user.getMessage();
return msg;
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 288 / 423
. . . . . .
Communication client/serveur Comet Le client
Jetty index.html
<!DOCTYPE html>
<html>
<head><!--- avec Bootstrap et jQuery --->
<script src="index.js"></script>
</head>
<body>
<div class="container">
<div class="fluid-row"><div class="span4">
<form action="#" class="well form-inline">
<input type="text" id="message">
<button class="btn" id="send">Send</button>
</form>
</div><div class="well span3" id="messages"></div>
</div>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 289 / 423
. . . . . .
Communication client/serveur Comet Le client
Jetty index.js
function sendCallback(data) { $("#message").val(""); }
function send() {
$.ajax({ url : "/chat/send",
method : "post",
dataType : "JSON",
data : { msg : $("#message").val() },
success : sendCallback
});
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 290 / 423
. . . . . .
Communication client/serveur Comet Le client
Jetty index.js
function getCallback(data) {
$("#messages").append(data+"<br>");
getMessage();
}
function getMessage() {
$.ajax({ url : "/chat/get",
method : "post",
success : getCallback
});
}
function init() { $("#send").click(send); getMessage(); }
$(document).ready(function() { init(); });
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 291 / 423
. . . . . .
Communication client/serveur Comet Continuations
Jetty Continuations
Problmatique : Dans la premire version, pour supporter un trs grand
nombre de clients, il est ncessaire que le serveur puisse tre en train de
traiter un grand nombre de requtes simultanment.
Premire solution : Dans la premire version, on doit permettre au
serveur de crer un thread pour crer chacune des requtes des clients. En
dautres termes, le nombre de clients possibles est limit par le nombre de
threads que le serveur peut crer.
Les continuations : Elles permettent de mettre en suspend le
traitement dune requte et de le reprendre plus tard.
Consquence : On va pouvoir mettre en place un pool de Threads pour
traiter les requtes (nouvelles ou suspendus).
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 292 / 423
. . . . . .
Communication client/serveur Comet Continuations
Jetty Modication 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) Dveloppement Web 2 April 26, 2013 293 / 423
. . . . . .
Communication client/serveur Comet Continuations
Jetty Modication 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) Dveloppement Web 2 April 26, 2013 294 / 423
. . . . . .
Communication client/serveur Comet Continuations
Jetty Modication 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) Dveloppement Web 2 April 26, 2013 295 / 423
. . . . . .
Communication client/serveur Comet Continuations
Jetty Modication de la cration du serveur
Il est maitenant possible de limiter le nombre de Threads la cration 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) Dveloppement Web 2 April 26, 2013 296 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 297 / 423
. . . . . .
Communication client/serveur WebSocket WebSocket et JavaScript
Client WebSocket et JavaScript
Demande douverture 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) Dveloppement Web 2 April 26, 2013 298 / 423
. . . . . .
Communication client/serveur WebSocket WebSocket et Jetty
Serveur avec Jetty
Cration 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) Dveloppement Web 2 April 26, 2013 299 / 423
. . . . . .
Communication client/serveur WebSocket WebSocket et Jetty
Serveur avec Jetty
La classe qui reoit les notications de connexion :
public class WSHandler extends WebSocketHandler {
@Override
public WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
Client client = new Client();
return client;
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 300 / 423
. . . . . .
Communication client/serveur WebSocket WebSocket et Jetty
Serveur avec Jetty
Le client :
public class Client implements WebSocket.OnTextMessage {
private Connection connection;
public void onOpen(Connection connection) {
this.connection = connection;
}
public void onMessage(String data) { /* ... */ }
public void onClose(int code, String msg) { /* ... */ }
public void send(String data) {
try { connection.sendMessage(data); }
catch (IOException e) { connection.close(); }
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 301 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion index.html
<!DOCTYPE html>
<html>
<head>
<!-- jQuery et dfinition 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) Dveloppement Web 2 April 26, 2013 302 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion index.js
function onMessage(event) {
var message = eval('('+event.data+')');
eval(message.action)(message);
}
function onClick(x,y) { ws.send(JSON.stringify({ x : x, y : y })); }
function initCell(x,y) { $('#c'+x+y).click(function(){onClick(x,y);}); }
$(function() {
ws = new WebSocket('ws://localhost:8080');
ws.onopen = onOpen; ws.onmessage = onMessage; ws.onclose = onClose;
for (var i = 0; i < 3; i++)
for (var j = 0; j < 3; j++)
initCell(i,j);
});
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 303 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion index.js
function onOpen(event) { $("#message").text("Connexion etablie."); }
function onClose(event) { $("#message").text("Connexion perdue."); }
function timeToPlay(message) { $("#message").text(" vous de jouer."); }
function wait(message) { $("#message").text(" l'autre de jouer."); }
function lost(message) { $("#message").text("Vous avez perdu."); }
function win(message) { $("#message").text("Vous avez gagn."); }
function draw(message) { $("#message").text("Match nul."); }
function play(message) {
var x = message.x;
var y = message.y;
var color =(message.position == 0)?"red":"blue";
$('#c'+x+y).css("background-color", color);
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 304 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 305 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion Serveur
public class WSHandler extends WebSocketHandler {
private MorpionServer server = new MorpionServer();
@Override
public WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
Client client = new Client(server);
return client;
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 306 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion Serveur
public class MorpionServer {
Game currentGame = new Game();
public void addClient(Client client) {
currentGame.addPlayer(client);
if (currentGame.isFull())
currentGame = new Game();
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 307 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion Serveur
public class Client implements WebSocket.OnTextMessage {
private Connection connection;
private MorpionServer server;
private Game game; private int position;
public Client(MorpionServer server) { this.server = server; }
public void onOpen(Connection connection) {
this.connection = connection; server.addClient(this);
}
public void setGame(Game game, int position) {
this.game = game; this.position = position;
}
public void onClose(int code, String msg) {
if (game!=null) game.closeGame();
}
public void closeGame() { game = null; connection.close(); }
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 308 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 309 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion Serveur
public class ServerMessage {
private String action;
private int position;
private int x, y;
public ServerMessage(int position, int x, int y) {
action = "play"; this.position = position;
this.x = x; this.y = y;
}
public ServerMessage(String action) { this.action = action; }
}
public class ClientMessage {
private int x, y;
public int getX() { return x; }
public int getY() { return y; }
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 310 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 311 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 312 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 313 / 423
. . . . . .
Communication client/serveur WebSocket Jeu de Morpion
Exemple du jeu de morpion Serveur
public class Game {
/* ... */
private boolean hasWon(int position) {
int j;
for (int i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) if (grid[i][j] != position) break;
if (j==3) return true;
for (j = 0; j < 3; j++) if (grid[j][i] != position) break;
if (j==3) return true;
}
for (j = 0; j < 3; j++) if (grid[j][j] != position) break;
if (j==3) return true;
for (j = 0; j < 3; j++) if (grid[j][2-j] != position) break;
if (j==3) return true;
return false;
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 314 / 423
. . . . . .
Node.js Introduction
Node.js Introduction
Node.js est une plateforme :
WebSocket
Technologie Flash
Forever Iframe
JSONP Polling
Navigateurs supports :
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) Dveloppement Web 2 April 26, 2013 333 / 423
. . . . . .
Node.js Socket.IO Introduction
Node.js Socket.IO
Association de WebSocket et de Express :
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/client.html');
});
/* Configuration du serveur */
server.listen(8080);
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 334 / 423
. . . . . .
Node.js Socket.IO Le serveur
Node.js Socket.IO Serveur Notications
Notication de la connexion dun nouveau client :
io.sockets.on('connection', function (socket) {
/* socket reprsente la connexion entre
le client et le serveur. */
});
Notication de la dconnexion dun client :
socket.on('disconnect', function () { /* ... */ });
Notication de la rception dun message :
socket.on('msgName', function(data) { /* ... */ });
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 335 / 423
. . . . . .
Node.js Socket.IO Le serveur
Node.js Socket.IO Serveur Messages
Envoyer un message via un socket :
socket.emit('msgName', data);
Envoyer un message tous les autres sockets ( lexception de ce socket) :
socket.broadcast.emit('msgName', data);
Envoyer un message tous les sockets :
io.sockets.emit('msgName', data);
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 336 / 423
. . . . . .
Node.js Socket.IO Le client
Node.js Socket.IO Client
Ajout du script :
<script src="/socket.io/socket.io.js"></script>
Connexion :
var socket = io.connect('http://localhost:8080');
Envoyer un message au serveur :
socket.emit('msgName', data);
couter un type de message provenant du serveur :
socket.on('msgName', function (data) { /* ... */ });
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 337 / 423
. . . . . .
Node.js Socket.IO Premier exemple
Node.js Socket.IO Premier exemple
Contenu du chier 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) Dveloppement Web 2 April 26, 2013 338 / 423
. . . . . .
Node.js Socket.IO Premier exemple
Node.js Socket.IO Premier exemple
Contenu du chier 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) Dveloppement Web 2 April 26, 2013 339 / 423
. . . . . .
Node.js Socket.IO Premier exemple
Node.js Socket.IO Premier exemple
Code du serveur :
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
app.use('/', express.static(__dirname + '/static'));
/* Initialisation de la connexion */
server.listen(8080);
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 340 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 341 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Client
<!DOCTYPE html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="index.js"></script>
<style><!-- style --></style>
</head>
<body>
<div id="c00" class="cell"></div>
<!-- ... -->
<div id="c22" class="cell"></div><br>
<div id="message" class="message"></div><br/>
</body>
</html>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 342 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Client
var socket = io.connect('http://localhost:8080');
function play(data) {
var x = data.x;
var y = data.y;
var color =(data.position == 0)?"red":"blue";
$('#c'+x+y).css("background-color", color);
}
function onClick(x,y) { socket.emit("play", {x:x,y:y}); }
function initCell(x,y) {
$('#c'+x+y).click(function() { onClick(x,y); });
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 343 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Client
$(function() {
socket.on('play', play);
socket.on('timeToPlay', function () {
$("#message").text(" vous de jouer.");
});
socket.on('wait', function () { /* ... */ });
socket.on('lost', function () { /* ... */ });
socket.on('win', function () { /* ... */ });
socket.on('draw', function () { /* ... */ });
for (var i = 0; i < 3; i++)
for (var j = 0; j < 3; j++)
initCell(i,j);
});
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 344 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
var express = require('express'); var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var Game = require('./game');
var Player = require('./player');
app.use(express.static(__dirname+'/www'));
var currentGame = new Game();
io.sockets.on('connection', function (socket) {
currentGame.addPlayer(new Player(socket));
if (currentGame.isFull()) currentGame = new Game();
});
server.listen(8080);
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 345 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
var Game = function() {
this.players = [];
this.activePosition = -1;
/* ... */
}
Game.prototype = {
isFull : function() { return this.players.length == 2; },
addPlayer : function(player) {
player.setGame(this, this.players.length);
this.players.push(player);
if (this.isFull()) this.startGame();
}, /* ... */
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 346 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
var Player = function(socket) {
this.socket = socket;
this.game = null;
this.position = 0;
}
Player.prototype = {
sendMessage : function(msg, data) {
this.socket.emit(msg, data);
},
setGame : function(game, position) {
/* ... */
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 347 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
var Player = function(socket) { /* ... */ }
Player.prototype = {
/* ... */
setGame : function(game, position) {
this.game = game;
this.position = position;
this.socket.on('play', function(data) {
game.play(position, data.x, data.y);
});
this.socket.on('disconnect', function() {
game.giveUp(position);
});
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 348 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 349 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
Game.prototype = {
isFull : function() { /* ... */ },
addPlayer : function(player) { /* ... */ },
initGrid : function() { / * ... */ },
setActivePosition : function(position) {
this.activePosition = position;
this.players[position].sendMessage("timeToPlay");
this.players[1 - position].sendMessage("wait");
},
startGame : function() {
this.setActivePosition(0);
}, /* ... */
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 350 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
Game.prototype = {
/* isFull, addPlayer, initGrid, setActivePosition */
play : function(position, x, y) {
if (this.activePosition!=position) return;
if (this.grid[x][y]!=-1) return;
this.grid[x][y] = position;
this.nbEmptyCells--;
for (var p = 0; p < 2; p++)
this.players[p].sendMessage("play",
{ position : position, x : x, y : y });
if (this.hasWin(position)) this.endGameWithAVictory(position);
else if (this.nbEmptyCells==0) this.endGameInADraw(position);
else this.setActivePosition(1 - this.activePosition);
}, /* ... */
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 351 / 423
. . . . . .
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) Dveloppement Web 2 April 26, 2013 352 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
Game.prototype = {
/* isFull, addPlayer, initGrid, setActivePosition, play... */
hasWin : function(pos) {
for (var i = 0; i < 3; i++) {
var ok1 = true, ok2 = true;
for (var j = 0; j < 3; j++) ok1 = ok1 && (this.grid[i][j]==pos);
for (var j = 0; j < 3; j++) ok2 = ok2 && (this.grid[j][i]==pos);
if (ok1 || ok2) return true;
}
var ok1 = true, ok2 = true;
for (var i = 0; i < 3; i++) ok1 = ok1 && (this.grid[i][i]==pos);
for (var i = 0; i < 3; i++) ok2 = ok2 && (this.grid[i][2-i]==pos);
return ok1 || ok2;
}
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 353 / 423
. . . . . .
Node.js Socket.IO Jeu de Morpion
Node.js Socket.IO Morpion Serveur
Organisation du programme du serveur :
Lucie
Bob
Christine
Arthur
#/user/1 :
Bob
age : 22
#/user/2 :
Christine
age : 30
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 386 / 423
. . . . . .
AngularJS Routes
Routes
Pour congurer les routes, on congure 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) Dveloppement Web 2 April 26, 2013 387 / 423
. . . . . .
AngularJS Routes
Routes
Le chier users.html :
<ul>
<li ng-repeat="user in users">
<a href="#/user/{{user.id}}">{{user.name}}</a>
</li>
</ul>
Le contrleur UserListCtrl :
function UserListCtrl($scope) {
$scope.users = users;
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 388 / 423
. . . . . .
AngularJS Routes
Routes
Le chier userlist.html :
<b>{{user.name}}</b>
<ul>
<li>age : {{user.age}}</li>
</ul>
<a href="#/users">Liste des utilisateurs</a>
Le contrleur UserCtrl :
function UserCtrl($scope, $routeParams) {
/* TODO : tester la valeur du paramtre */
$scope.user = users[$routeParams.id];
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 389 / 423
. . . . . .
AngularJS Directives
Directives
Les directives permettent de crer de nouveaux lments 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 dutiliser le nouveau composant dans le HTML :
<body ng-init="bob = {name:'bob', age:22}">
<user src="bob" />
</body>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 390 / 423
. . . . . .
AngularJS Directives
Directives
Il est possible disoler le template dans un autre chier :
var myapp = angular.module('myapp', [])
myapp.directive('user', function(){
return {
restrict: 'E',
replace: true,
scope: { src : '=src' },
template: 'user.html',
}
});
Contenu du chier user.html :
<span>{{src.name}} : {{src.age}}</span>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 391 / 423
. . . . . .
AngularJS Directives
Directives
Il est possible dassocier un contrleur llment :
myapp.directive('userform', function(){
return {
restrict: 'E',
replace: true,
scope: { userList : '=' }, /* attr. user-list */
templateUrl: 'userform.html',
controller : 'UserFormCtrl'
}
});
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 392 / 423
. . . . . .
AngularJS Directives
Directives
Le code du contrleur UserFormCtrl :
function UserFormCtrl($scope) {
$scope.add = function(user) {
$scope.userList.push(user);
}
}
Le contenu du chier 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) Dveloppement Web 2 April 26, 2013 393 / 423
. . . . . .
AngularJS Directives
Directives
Utilisation des balises prcdentes :
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="user in users">
<user src="user" />
</li>
</ul>
<userform user-list="users" />
</body>
Code du contrleur GlobalCtrl :
function MainCtrl($scope) {
$scope.users = [{ name : "Lucie", age : 21}, /*...$*/];
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 394 / 423
. . . . . .
AngularJS Directives
Directives
Supposons que la directive suivante soit dnie :
myapp.directive('message', function(){
return {
restrict: 'E',
replace: true,
scope: { nickname : '=' },
templateUrl: 'message.html',
}
});
Nous souhaitons utiliser la directive de la faon suivante :
<message nickname="bob">Bonjour.</message>
De faon obtenir :
<b>bob</b> : Bonjour.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 395 / 423
. . . . . .
AngularJS Directives
Pour ce faire, il sut de dnir le template de la faon suivante :
<span>
<b>{{nickname}}</b> :
<span ng-transclude></span>
</span>
Le mot-cl ng-transclude permet de copier le contenu prsent dans la
balise dans la balise dsigne laide du mot-cl.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 396 / 423
. . . . . .
AngularJS Directives
Directives
Ralisation dune 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) Dveloppement Web 2 April 26, 2013 397 / 423
. . . . . .
AngularJS Directives
Directives
Dnition 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) Dveloppement Web 2 April 26, 2013 398 / 423
. . . . . .
AngularJS Directives
Directives
Dnition du contrleur :
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 lutilisation du contrleur :
<body ng-controller="MainCtrl">
<grid grid="grid" on-click="play"></grid>
</body>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 399 / 423
. . . . . .
AngularJS Directives
Directives
Le template grid.html :
<div>
<div ng-repeat="l in [0,1,2]">
<div class="cell"
ng-repeat="c in [0,1,2]"
ng-class="grid[l][c]"
ng-click="onClick(l,c)">
</div>
</div>
</div>
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 400 / 423
. . . . . .
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 contrleur 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) Dveloppement Web 2 April 26, 2013 401 / 423
. . . . . .
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 contrleur 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 donne prcdemment ne fonctionne plus ?
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 402 / 423
. . . . . .
AngularJS Directives
Directives
Modication 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) Dveloppement Web 2 April 26, 2013 403 / 423
. . . . . .
AngularJS Directives
Directives
Modication 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 lutilisation 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) Dveloppement Web 2 April 26, 2013 404 / 423
. . . . . .
AngularJS Directives
Directives
Les direntes faons dinsrer 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 -->
Modication 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) Dveloppement Web 2 April 26, 2013 405 / 423
. . . . . .
Dart/TypeScript Dart
Dart Introduction
Objectif : Proposer un nouveau langage ct client (et serveur) qui
permette le dveloppement dapplications de grande taille.
Dart :
etc.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 406 / 423
. . . . . .
Dart/TypeScript Dart
Dart Introduction
Utilisation dun 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) Dveloppement Web 2 April 26, 2013 407 / 423
. . . . . .
Dart/TypeScript Dart
Dart Introduction
Utilisation dun script Dart dans du code HTML :
import 'dart:html';
void main() {
query("#text").text = "Truc";
}
Dans ce code, nous utilisons la librairie html pour interagir avec le DOM.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 408 / 423
. . . . . .
Dart/TypeScript Dart
Dart Introduction
Un autre exemple :
import 'dart:html';
void main() {
query("#text").text = "Truc";
query("#text").onClick.listen(textClick);
}
void textClick(Event e) {
String txt = query("#text").text;
query("#text").text="["+txt+"]";
}
Notez que certaines variables sont types statiquement.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 409 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Il est possible de dnir une classe et de crer 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) Dveloppement Web 2 April 26, 2013 410 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Quelques nouveauts pour faciliter le dveloppement :
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) Dveloppement Web 2 April 26, 2013 411 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Utilisation de la classe dcrite prcdemment :
void main() {
Point p1 = new Point(2,3);
Point p2 = new Point.alongXAxis(2);
Point p3 = new Point.alongYAxis(2);
Point p4 = new Point.fromJson({"x":3, "y":6});
query("#text").text = "${p1} ${p2} ${p3} ${p4}";
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 412 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Il est possible dtendre une classe :
class Pixel extends Point {
num r, g, b;
Pixel(x, y, this.r, this.g, this.b) : super(x,y);
String toString() => "((${super.toString()},"+
"${r},${g},${b})";
}
Quel texte est plac dans la balise text :
void main() {
Pixel pixel = new Pixel(2,3,2.3,3.4,5.0);
Point point = pixel;
query("#text").text = "${pixel} ${point}";
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 413 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Les interfaces implicites :
class Converter {
String convert(String s) => s;
}
class UpperCaseConverter implements Converter {
String convert(String s) => s.toUpperCase();
}
class LowerCaseConverter implements Converter {
String convert(String s) => s.toLowerCase();
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 414 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Utilisation des classes prcdentes :
void main() {
List<Converter> converters =
[
new Converter(),
new UpperCaseConverter(),
new LowerCaseConverter()
];
String txt = "[ToTo]";
query("#text").text =
converters.map((c) => c.convert(txt))
.join(";");
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 415 / 423
. . . . . .
Dart/TypeScript Dart
Dart Programmation objet
Autres fonctionnalits :
classes abstraites;
types gnriques;
Autres exemples :
var names = new List<String>();
names.addAll(<String>['Bob', 'Arthur', 'Louis', 'Bob']);
var nameSet = new Set<String>.from(names);
query("#text").text = nameSet.join(";");
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 416 / 423
. . . . . .
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:json Encoding and Decoding Objects
dart:uri Manipulating URIs
dart:utf Strings and Unicode
dart:crypto Hash Codes and More
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 417 / 423
. . . . . .
Dart/TypeScript Dart
Dart Les librairies
import 'dart:html';
import 'dart:json' as json;
void main() {
var jsonString = '''
[
{ "name" : "bob", "age" : 22 },
{ "name" : "arthur", "age": 45 },
]
''';
var persons = json.parse(jsonString);
var list = persons.map(
(p) => "<li><b>${p["name"]}</b> : ${p["age"]}</li>");
query("#text").innerHtml = "<ul>${list.join()}</ul>"; <!-- $ -->
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 418 / 423
. . . . . .
Dart/TypeScript TypeScript
TypeScript
Objectif : Proposer un nouveau langage ct client qui permette le
dveloppement dapplications de grande taille.
TypeScript :
etc.
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 419 / 423
. . . . . .
Dart/TypeScript TypeScript
TypeScript
TypeScript est un langage orient objet :
interface Converter {
convert(s:string) : string;
}
class LowerCaseConverter implements Converter {
convert(s:string) : string { return s.toLowerCase(); }
}
class UpperCaseConverter implements Converter {
convert(s:string) : string { return s.toUpperCase(); }
}
Bertrand Estellon (AMU) Dveloppement Web 2 April 26, 2013 420 / 423
. . . . . .
Dart/TypeScript TypeScript
TypeScript
Utilisation de linterface et des classes prcdentes :
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) Dveloppement Web 2 April 26, 2013 421 / 423
. . . . . .
Dart/TypeScript TypeScript
TypeScript
Le code TypeScript prcdent 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) Dveloppement Web 2 April 26, 2013 422 / 423
. . . . . .
Dart/TypeScript TypeScript
TypeScript
Le code TypeScript prcdent 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) Dveloppement Web 2 April 26, 2013 423 / 423