| Chapitre 9 |
PHP : Visite guidée du langage |
|
Avant d'aller plus loin, nous allons vérifier si votre installation
fonctionne correctement. Pour celà, nous allons écrire ensemble notre
premier script PHP3. C'est parti.
Ouvrez votre éditeur préféré, Emacs,
VI ou Notepad, et tapez ce qui
suit :
<HTML><BODY>
<?php
phpinfo();
?>
</BODY></HTML>
Sauvez maintenant le tout sous le nom de phpinfo.php3 dans le
répertoire racine des documents de votre serveur HTTP, soit
htdocs pour Apache ou wwwroot pour PWS.
Lancez ensuite un navigateur et entrez l'URL suivante :
http://localhost:80/phpinfo.php3. Si tout
fonctionne correctement, vous devriez voir dans des tableaux colorés
des informations précieuses sur le paramétrage de votre PHP3
accompagnées de courts extraits de la license GPL.
(Cette introduction est inspirée de celle fournie avec la
documentation officielle de PHP3 que vous pouvez trouver à cette
adresse : http://www.php.net/).
Nous avons déjà écrit un notre première page HTML contenant du
code PHP3 embarqué dans le paragraphe précédent,
mais pour ne pas faire entorse à la coutume, nous allons écrire notre
version du célèbre "Hello, world !" en PHP3.
<HTML><BODY>
<?php
echo "Hello World<P>";
?>
</BODY></HTML>
Facile, non ? Le code PHP3 est placé directement dans le code source
HTML, il est encadré par deux balises spéciales qui sont
destinées à être reconnues par l'interprêteur
PHP3. On aurait pu tout aussi bien utiliser les balises
<SCRIPT LANGUAGE="php"> et </SCRIPT> comme on le
fait pour du javascript.
Enfin, vous pouvez également utiliser les tags sous leur forme courte
(<? et ?>), mais cette possibilité n'est pas activée par
défaut. Il vous faudra donc modifier le paramétrage de PHP3 sur votre
machine. Cette possibilité est intéressante si vous voulez utiliser un
éditeur Wysiwyg tel que MS Frontpage.
Attention, il ne faut pas confondre PHP3 et JavaScript. Il s'agit de
deux choses différentes : PHP3 est un langage de script destiné à être
exécuté par le serveur, alors que le JavaScript est
chargé et exécuté dans le navigateur. PHP3 est donc comparable à
l'ASP de Microsoft dans le sens où il s'exécutent tous les deux "côté
serveur".
Quand on affiche dans le navigateur le source HTML d'une page générée
par PHP3, on ne voit que le code HTML résultant (et éventuellement du
code JavaScript transmis au navigateur).
Si vous regardez le source de la page précédente dans votre
navigateur, vous ne verrez que ça :
<HTML><BODY>
Hello World<P>
</BODY></HTML>
| 9.1 |
Syntaxe et Constructions |
|
La syntaxe de PHP3 n'a vraiment rien de déroutante
puisqu'elle est très proche de celle du langage C. On place
généralement une instruction par ligne. Une instruction est terminée
par un point-virgule en fin de ligne.
Comme pour les sources de C, on prendra soin à utiliser de façon
systématique l'indentation, ce qui augmente la
lisibilité. Il faut penser que dans un script PHP3 on peut trouver
pêle-mêle du HTML, du script PHP3 ainsi que du JavaScript. On a donc
tout interêt à se soucier de la lisibilité du code.
Les types de données données standard en PHP3 sont : integer,
double, string, array et object.
PHP3 n'est pas un langage fortement typé. C'est PHP3 qui décide à
l'exécution, en fonction de son contenu, quel type est sera le plus
indiqué pour la variable.
Quand vous utilisez une variable, vous n'avez pas besoin de la
déclarer au préalable.
La maitrise du programme restant toutefois au programmeur, vous avez
la possibilité de forcer le transtypage en
«castant» les variables vers le type de votre choix. Les
casts autorisés sont les suivants :
-
(int), (integer) : cast en un integer
- (real), (double), (float) :
cast en un double
- (string) : cast en une chaîne
- (array) : cast en un tableau
- (object) : cast en un objet
De même, une variable peut changer de type
en fonction de son contenu. Nous allons voir comment jongler avec les
différents types de variables.
$foo = "0"; // $foo is string (ASCII 48)
$foo++; // $foo is the string "1" (ASCII 49)
$foo += 1; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a double (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
Conclusion? Eh bien, si l'interprêteur PHP3 s'en sort plutôt bien,
nous, humains, avons la plupart du temps du mal à imaginer ce que
représente d'ajouter des choux et des carottes, ou bien d'additionner
un entier et une chaîne de caractères. Ce genre de construction ne
sera jamais utilisé en pratique. Du moins, il faut souligner c'est à
déconseiller. A moins que vous ne soyez le seul à maintenir votre code
PHP3, utiliser de telles «bidouilles» n'est pas un beau cadeau pour
vos collaborateurs...
| 9.3 |
Opérateurs et Expressions |
|
(Cette partie est assez fastidieuse, je l'ai donc directement
reprise de la doc officielle de PHP3 : http://www.php.net/manual/).
| 9.3.1 |
Opérateurs arithmétiques |
|
Quelques exemples valent souvent mieux qu'un long discours...
|
Exemple |
Opération |
Effet |
$a + $b |
Addition |
Somme de $a et $b |
$a - $b |
Soustraction |
Reste de la différence de $b et $a |
$a * $b |
Multiplication |
Produit de $a par $b |
$a / $b |
Division |
Dividende de $a par $b |
$a % $b |
Modulo |
Reste de la division entière de $a par $b |
|
|
| 9.3.2 |
Opérateurs sur les chaînes |
|
Il n'existe qu'un seul opérateur en PHP3 sur les
chaînes, c'est l'opérateur de
concaténation. C'est tout me direz vous?
Rassurez-vous, PHP3 dispose en standard de toutes les fonctions
nécessaires. Elles sont décrites plus loin dans ce tutoriel.
Référez-vous à la documentation PHP3 au chapitre «XL. String
functions» (http://www.php.net/manual/ref.strings.php).
$a = "Hello ";
$b = $a . "World!"; // maintenant $b contient "Hello World!"
Il est à noter que vous pouvez spécifier une chaîne en l'encadrant
entre des simples ou des doubles quotes. Dans le second cas, PHP3
tentera d'interprêter le contenu de la chaîne. La différence au niveau
performance existe, mais est mineure.
$val='Pengo';
echo 'Hello $val'; // Affiche Hello $val
echo "Hello $val"; // Affiche Hello Pengo
L'utilisation de l'opérateur arithmétique
d'addition en vue de concaténer deux chaînes de caractères est
interdite. Un paramètre de PHP3.ini permet de signaler ces
mauvaises utilisations de l'opérateur «+».
warn_plus_overloading = Off ; warn if the + operator is used with strings
| 9.3.3 |
Opérateurs Binaires |
|
Il s'agit des opérateurs binaires dits «bit à
bit», et non pas des opérateurs logiques
booléens.
|
Exemple |
Opération |
Effet |
$a & $b |
Et |
Les bits qui sont à 1 dans $a ET dans $b sont mis à 1 |
$a | $b |
Ou |
Les bits qui sont à 1 dans $a OU dans $b sont mis à 1 |
~ $a |
Non |
Les bits sont inversés |
|
|
Quelques exemples :
$a = 5; // 0000 0101
$b = 12; // 0000 1100
$c = $a & $b; // $c vaut donc 0000 0100 soit 4
$d = $a | $b; // $d vaut donc 0000 1101 soit 13
$e = ~ $a; // $e contient le complément de 5, soit 1111 1010
// (avec devant autant de 1 que vous voulez)
// ce qui vaut -6
| 9.3.4 |
Opérateurs Logiques |
|
Chose originale avec PHP3, il existe deux versions des
opérateurs logiques ET et OU, avec des
précédences différentes.
|
Exemple |
Opération |
Effet |
$a and $b |
Et |
Résultat vrai si $a ET $b sont vrais |
$a or $b |
Ou |
Résultat vrai si $a OU $b est vrai (ou les deux) |
$a xor $b |
Ou Exclusif |
Résultat vrai si $a OU $b est vrai, mais pas si les deux sont vrais |
! $a |
Négation |
Résultat vrai si $a est faux, et réciproquement |
$a && $b |
Et |
Résultat vrai si $a ET $b sont vrais |
$a || $b |
Ou |
Résultat vrai si $a OU $b est vrai (ou les deux) |
|
|
Les opérateurs || et ""or" n'ont pas la même
précédence. Cela permet d'écrire la chose suivante
sans avoir besoin d'utiliser des parenthèses qui allourdissent le code :
Ainsi :
$a = foo() || bar() or die();
est équivalent à :
($a = foo() || bar() ) or die();
Mais si vous écriviez ça :
$a = foo() || bar() || die()
PHP3 comprendrait :
$a = (foo() || bar() || die())
| 9.3.5 |
Opérateurs non documentés |
|
Pour les nostalgiques des notations binaires et langages machines,
deux opérateurs de décalage existent en
PHP3, mais ils sont bizarrement absents de la documentation de
référence :
-
$a << $b : Décale les bits de $a de $b pas
vers la gauche (chaque pas signifie «multiplier par 2»)
-
$a >> $b : Décale les bits de $a de $b pas
vers la droite (chaque pas signifie «diviser par 2»)
Au passage, on notera qu'on peut utiliser les notations
binaires, héxadécimales et
octales. Les trois variables suivantes représentent la
même valeur dans les trois notations (MAXINT).
$a = 017777777777; // octal
$b = 0x7fffffff; // hexadécimal
$c = 2147483647; // décimal
| 9.3.6 |
Opérateurs de comparaison |
|
Encore du classique. Sans surprise pour les habitués de la syntaxe C.
|
Exemple |
Opération |
Effet |
$a == $b |
Égal |
Résultat vrai si $a est égal à $b |
$a != $b |
Différent |
Résultat vrai si $a est différent de $b |
$a < $b |
Inférieur |
Résultat vrai si $a est strictement inférieur à $b |
$a > $b |
Supérieur |
Résultat vrai si $a est strictement supérieur à $b |
$a <= $b |
Inf ou égal |
Résultat vrai si $a est inférieur ou égal à $b |
$a >= $b |
Sup ou égal |
Résultat vrai si $a est supérieur ou égal à $b |
|
|
| 9.4 |
Instructions conditionnelles |
|
Une petite application des opérateurs de comparaison que l'on vient de
voir.
Le IF est
l'instruction conditionnelle de
base. Elle permet de n'exécuter une ou plusieurs instructions que si
une condition (ou une expression contenant plusieurs
conditions) est remplie.
if ($a > $b)
print "a est supérieur à b";
// ne s'affichera que si $a est supérieur à $b
if (($a > 4) and ($b > 4))
print "a et b sont supérieurs à 4";
// ne s'affiche que si $a et $b sont supérieurs à 4
if ($a > $b)
{ // plusieurs instructions conditionnées
print "a est supérieur à b";
print "b est inférieur à a";
}
: PHP3 offre une autre syntaxe possible pour
spécifier un bloc d'instructions.
Il s'agit de IF(): ... ENDIF;
Dans cette construction, le A = 5 n'est pas une instruction
d'affectation mais du texte HTML qui ne sera affiché que si la
condition est remplie. Cela permet de rendre des parties en pur HTML
mois lourdes à lire (on n'a pas besoin de placer des echo à
chaque ligne).
<?php if ($a==5): ?>
A = 5
<?php endif; ?>
if ($a==5) {
echo "A = 5"; }
Le IF...ELSE permet de spécifier un ensemble
d'instructions à effectuer aussi bien si la condition est vraie que si
la condition est fausse.
if ($a > $b) {
print "a est supérieur à b";
} else {
print "a n'est pas supérieur à b";
}
Le ELSEIF permet de mettre en cascade plusieurs
conditions. Le ELSEIF en «un seul mot» peut être utilisé
tout aussi bien que ELSE IF séparés par un espace.
if ($a > $b) {
print "a supérieur à b";
} elseif ($a == $b) {
print "a égal à b";
} else {
print "a inférieur à b";
}
Ou avec une indentation plus lisible ;-)
if ($a > $b)
{
print "a supérieur à b";
}
elseif ($a == $b)
{
print "a égal à b";
}
else
{
print "a inférieur à b";
}
Le langage PHP3 comporte également toutes les instructions
"classiques" de boucle :
DO...WHILE,
FOR,
BREAK,
CONTINUE et
SWITCH
Vous pourrez consulter le manuel de référence pour voir la syntaxe de
ces instructions ainsi qu'un rapide exemple. Il serait inutile et
fastidieux de les détailler ici.
Pourquoi les tableaux sont-ils si importants en PHP3? Parce les
fonctions qui retournent plusieurs valeurs le font généralement sous
la forme de tableaux. C'est la cas des fonctions liées aux bases de
données. Il est donc particulièrement intéressant de bien maitriser
les tableaux en PHP3.
Il existe en PHP3 deux types de tableaux.
Premier type : les tableaux que l'on pourrait nommer «Classiques» dans
lesquels on se déplace en utilisant l'indice de l'élément, comme en
langage C. Le premier élément porte comme en C l'indice zéro.
On peut remplir un tableau en adressant chaque élément un par un, ou
d'un coup en fournissant toutes les valeurs :
$tab[0] = "P";
$tab[1] = "H";
$tab[2] = "P";
$tab[3] = "3";
Ce qui est équivalent à :
$tab = array("P","H","P","3");
| 9.5.1 |
Tableaux associatifs |
|
L'autre type de tableau disponible en PHP3 est concerne les
tableaux associatifs (comme en
Perl). Qu'est-ce qu'un tableau associatif? C'est
un tableau qui contient pour chaque élément une valeur associée qui
sert de clé d'accès. Quel en est l'interêt?
Prenons le cas d'un tableau contenant les quantités d'un produit vendu
sur la semaine écoulée. Si on utilise un tableau classique, il faudra
prendre une convention pour représenter chacun des sept jours de la
semaine sous la forme d'un entier de 0 à 6. Cela donnerait
quelquechose comme ça :
// 0 -> Lundi, ... , 6 -> Dimanche
$vente_hebdo[6] = 0; // Aucune vente le Dimanche
$vente_hebdo[2] = 1562 ; // 1562 ventes le ??????
Ceci ne rend pas le code très lisible, d'une part, et peut ne pas
répondre à tous les besoins. L'utilisation de tableaux associatifs
change grandement les choses :
$vente_hebdo["dimanche"] = 0; // Aucune vente le Dimanche
$vente_hebdo["mardi"] = 1562 ; // 1562 ventes le Mardi
De la même façon que pour les tableaux classiques, on peut affecter
plusieurs valeurs d'un coup :
$vente_hebdo = array("lundi"=>1742,"mardi"=>1562,"mercredi"=>1920,
"jeudi"=>1239,"vendredi"=>2012,"samedi"=>720) ;
Question : Bon, tout cela est très bien. Je vois comment on peut
décrire les éléments d'un tableau classique en utilisant un
indice, mais comment faire pour un tableau associatif
?
Réponse : En utilisant les fonctions dédiées aux tableaux :
each() et reset() en
particulier. Si on reprend l'exemple précédent, cela donne :
<?php
$vente_hebdo = array("lundi"=>1742,"mardi"=>1562,"mercredi"=>1920,
"jeudi"=>1239,"vendredi"=>2012,"samedi"=>720) ;
$vente_totale = 0;
reset($vente_hebdo);
while (list($key, $value) = each($vente_hebdo)) {
echo "<BR> Vente de $key : $value unités\n";
$vente_totale += $value;
}
echo "<BR>Vente sur la semaine : $vente_totale unités\n";
?>
Ce qui produira l'affichage suivant :
Vente de lundi : 1742 unités
Vente de mardi : 1562 unités
Vente de mercredi : 1920 unités
Vente de jeudi : 1239 unités
Vente de vendredi : 2012 unités
Vente de samedi : 720 unités
Vente sur la semaine : 9195 unités
| 9.5.2 |
Tableaux à deux dimensions |
|
C'est très simple, il s'agit simplement d'un tableau dont chaque
élément est lui même un tableau.
Exemple :
$tab[] = array(1, "un", "premier");
$tab[] = array(2, "deux", "second");
$tab[] = array(3, "trois", "troisième");
$tab[] = array(4, "quatre", "quatrième");
$tab[] = array(5, "cinq", "cinquième");
list($entier, $chaine1, $chaine2) = $tab[2];
$c = count($tab);
for ($i=0; $i<$c; $i++)
{
list($entier, $chaine1, $chaine2) = $tab[$i];
echo "<BR>Contenu du tableau : $entier , $chaine1 , $chaine2 ";
}
On utilise ici une boucle FOR en adressant chaque élément par
son indice. Pour savoir combien de tours de boucle on doit faire, on
lit le nombre d'éléments du tableau avec count().
Les fonctions de manipulation de tableaux comportent également les
fonctions current(), next() et prev() qui
permettent respectivement de connaitre la position actuelle du
pointeur, d'avancer et de reculer ce pointeur d'un élément. Toutefois,
ces fonctions sont à utiliser avec prudence car elles retournent
false au premier élément dont la valeur est «0» ou
«""».
La meilleure méthode pour parcourir les éléments d'un tableau est
d'utiliser each().
| 9.5.3 |
Tri sur les tableaux |
|
Les fonctions sur les tableaux sont très complètes. Elles comportent
même des fonctions prêtes à l'emploi pour trier le contenu d'un
tableau selon ses valeurs ascendentes ou descendantes, et, pour les
tableaux associatifs, des fonctions de tris dans les deux sens sur les
valeurs ou sur la clé.
L'exemple suivant va monter l'utilisation de sort() sur un
tableau simple, ainsi que les effets pervers de next() :
<?php
$tab = array("P","H","P","L","I","N","U","X");
asort($tab);
echo "<BR>Parcours avec next() :<BR> " ;
for(reset($tab); $key = key($tab); next($tab)) {
echo "tab[$key]=".$tab[$key]."\n";
}
echo "<BR>Parcours avec each() :<BR> " ;
reset($tab);
while(list($key,$value) = each($tab)) {
echo "tab[$key]=".$tab[$key]."\n";
}
?>
Ce qui donne
Parcours avec next() :
tab[1]=H tab[4]=I tab[3]=L tab[5]=N tab[2]=P
Parcours avec each() :
tab[1]=H tab[4]=I tab[3]=L tab[5]=N tab[2]=P tab[0]=P tab[6]=U tab[7]=X
En utilisant next(), le premier élément du tableau
$tab[0]="P"
ne s'affiche pas car next() retourne false.
Au passage, on remarque qu'un tableau ordinaire tel que $tab
est en fait équivalent à un tableau associatif dont la clé n'est autre
que l'indice de l'élément.
La fonction sort() ordonne le tableau suivant l'ordre
croissant de ses valeurs. Inversement, la fonction rsort()
effectue le tri par ordre décroissant (reverse).
Pour les tableaux associatifs, les fonctions asort() et
ksort() permettent d'effectuer des tris sur la valeur ou sur
la clé du tableau. La fonction inverse de asort() est
arsort().
| 9.5.4 |
Tri suivant des fonctions utilisateur |
|
Ces fonctions de tri opèrent sur l'ordre alphabétique ou numérique des
valeurs. Pour faire des tris complexes, il faut utiliser les fonctions
de tris basées sur des fonctions utilisateur. Basiquement, pour trier
plusieurs valeurs, il suffit de pouvoir comparer deux valeurs. Pour
faire un tri suivant un ordre défini par l'utilisateur, il suffit donc
de fournir une fonction de comparaison de deux éléments. Les fonctions
de tri utilisateur sont usort() pour les tableaux ordinaires
et uksort(), uasort() pour les tableaux associatifs.
L'exemple suivant montre comment faire un tri basé sur le troisième
caractère de l'élément. Le tableau contient un ensemble de prénoms
masculins, l'idée est de faire le tri en ne tenant pas compte des
caractères accentués. Voici le code correspondant :
<?php
function replace_car($a) {
if ((($a >= "a") and ($a <="z"))
or (($a >= "A") and ($a <="Z"))) {
return $a ;
}
// Il en manque, c'est juste pour l'exemple...
switch($a) {
case "é" :
return "e"; break;
case "è" :
return "e"; break;
case "ê" :
return "e"; break;
case "à" :
return "a"; break;
case "î" :
return "i"; break;
case "ï" :
return "i"; break;
case "ô" :
return "o"; break;
}
}
function cmp($a,$b) {
$car_a = replace_car($a[2]);
$car_b = replace_car($b[2]);
if ($car_a == $car_b) return 0;
return ($car_a < $car_b) ? -1 : 1;
}
$a = array("Jean","Gilles","Louis","Paul","Albert",
"Stéphane","Michel","Loïc");
usort($a, cmp);
while(list($key,$value) = each($a)) {
echo "<BR> ($value[2]) $key: $value\n";
}
?>
Ce qui produit les résultats suivants :
(a) 0: Jean
(b) 1: Albert
(c) 2: Michel
(é) 3: Stéphane
(ï) 4: Loïc
(l) 5: Gilles
(u) 6: Paul
(u) 7: Louis
Pour effectuer le tri dans l'ordre inverse, il suffit de définir la
fonction une comparaison inverse :
<?php
function rcmp($a,$b) {
$car_a = replace_car($a[2]);
$car_b = replace_car($b[2]);
if ($car_a == $car_b) return 0;
return ($car_a > $car_b) ? -1 : 1;
}
?>
Exercice : Modifiez le code ci-dessus pour remplacer le vilain
switch par strtr().
| 9.6 |
Autres mots réservées |
|
Rédaction en cours...
| 9.7 |
Fonctions couramment utilisées |
|
Rédaction en cours...