Les fonctions
Tuto original de FABRICE POTEC, revu par LionZion, Molokai et Raf en août 2004 1 . Introduction
Dans le cours numéro 8 nous avions vu une brève introduction sur le principe
d'utilisation des fonctions.
Une fonction est ce que l'on peut appeler un sous programme, une procédure. On distingue deux types
de fonctions : les "fonctions intégrées" ou "built-in" qui sont incluses par défaut avec les distributions
de PHP comme print, echo et les fonctions définies par le programmeur, dites aussi "fonctions utilisateur".
Les fonctions ont plusieurs buts:
- Eclaircir le code en regroupant certaines fonctionnalités d'un programme qui se répètent dans une même fonction.
- Pouvoir créer des fonctions génériques qui pourront être utilisées dans d'autres programmes, ce qui évite de répéter pour chaque projet le même code
- Possibilité d'évolution du code plus facile dans la mesure où lorsque vous modifiez le contenu d'une fonction, les répercussions sont effectuées sur l'ensemble du programme sans que vous ayez à le modifier dans la plupart des cas (sauf si vous rajoutez des paramètres etc).
2 . Syntaxe de déclaration
Une fonction se déclare de la manière suivante :
<?php
function name_fonction ($params1, $params2, $params3, ... , $paramsN)
{
// code de la fonction
return ($une_variable) // facultatif
}
?>
Analysons cette syntaxe de déclaration :
- L'instruction function qui déclare une fonction.
- Le nom de la fonction name_fonction.
- (...) La liste des paramètres séparés par une virgule, les arguments sont facultatifs, tout dépend du but de votre fonction.
- Une instruction return facultative qui permet de renvoyer une variable.
3 . Organiser l'écriture d'une fonction
Voici les différentes étapes nécessaires à la bonne élaboration d'une fonction simple à l'intérieur d'un script
php:
1- Un en-tête qui regroupe des infos sur la fonction
/*
** Function : nom de votre fonction qui doit être court et explicatif
** Input : paramètre(s) en entrée entre () (ne pas trop en mettre)
** Output : paramètre(s) en sortie (la fonction ne peut renvoyer qu'une seule variable ou alors un tableau).
** Description : l'utilité de cette fonction
** Creator : le créateur de la fonction
** Date : date de création
*/
2- Déclaration de la fonction.
La fonction à ici pour nom ma_fonction, comme input $ma_var1, $ma_var2 et $ma_var3, en paramètre de sortie une variable boléenne (qui ne peut prendre que 2 valeurs true ou false), l'utilité étant de faire une comparaison sur les paramètres d'entrée.
<?php
function ma_fonction ($ma_var1, $ma_var2, $ma_var3)
{
if ($ma_var1 == $ma_var2)
return (TRUE);
else if ($ma_var1 > $ma_var3)
return (FALSE);
}
?>
4 . Voir l'utilité d'une fonction avec un exemple précis
Alors tout d'abord créer une fonction simple. Prenons l'exemple du code suivant:
1- le code brut dans le programme index.php par exemple :
<html> <body>
<?php
// afficher un menu de login membre simple
echo '
<table> <form action="liens.php" method="post" name="login_form"> <tr> <td>Votre login</td> <td><input type="text" name="login" value="" size="20" maxlength="42"></td> </tr> <tr> <td>Votre password</td> <td><input type="password" name="pass" value="" size="20" maxlenght="12"></td> </tr> <tr> <td> <input type="submit" name="valider" value="val"> <input type="reset" name="annuler" value="anu"> </td> </tr> </form> </table> ';
?>
</body> </html>
Jusqu'ici rien de compliqué, bon vous me direz pourquoi utiliser une fonction dans ce cas-là vu que le code est court et simple ?
Et bien si vous avez besoin de créer des formulaires de login membre dans plusieurs projets, au lieu de répéter le code à chaque fois dans le .php il vous suffit de stocker ce code dans une fonction et d'appeler simplement cette fonction avec les paramètres voulus.
2 - Créer une fonction à partir de ce code :
<?php
/*
** Function : form_login_member
** Input : aucun pour l'instant
** Output : aucun
** Description : affichage d'un formulaire de login de membre
** Creator : polom
** Date : 25/10/2001
*/
function form_login_member()
{
echo '<table>';
echo '<form action="liens.php" method="post" name="login_form">';
echo '<tr>';
echo '<td>Votre login</td>';
echo '<td><input type="text" name="login" value="" size="20" maxlength="42"></td>';
echo '</tr>';
echo '<tr>';
echo '<td>Votre password</td>';
echo '<td><input type="password" name="pass" size="20" maxlenght="12"></td>';
echo '</tr>';
echo '<tr>';
echo "<td>;
echo '<input type="submit" name="valider" value="val">';
echo '<input type="reset" name="annuler" value="anu">';
echo '</td>';
echo '</tr>';
echo '</form>';
echo '</table>';
}
?>
3 - Utiliser cette fonction dans le code précédent vu en 1 :
Plusieurs possibilités s'offrent à vous pour utiliser cette fonction à la place du code dans index.php, je vous propose deux possibilités pour
intégrer cette fonction, sachant que la deuxième est préférable.
- Déclarer la fonction au début du fichier index.php, elle sera appelée ensuite dans le script.
- Créer un fichier qui regroupera vos fonctions ce qui permet de les retrouver facilement, vous ferez appel à ce fichier à l'aide de include ("fonctions.inc.php") ou require ("fonctions.inc.php") si votre fichier de fonctions s’appelle fonctions.inc.php bien sur :) toujours avant de faire appel à la fonction dans index.php
4 - le nouvel index.php avec la fonction :
Nous allons opter pour la deuxième solution, cad mettre notre fonction dans le fichier fonctions.inc.php, je ne mettrai pas le code,
c'est le même que précédemment :), et faire appel à la fonction dans notre fichier index.php
<html>
<body>
<?php
include ("fonctions.inc.php");
form_login_member();
?>
</body>
</html>
Et voila c'est tout de même plus beau non ? Vous possédez un fichier index.php faisant appel à votre fichier fonctions.inc.php contenant
votre fonction d'affichage de formulaire de login. Vous pourrez donc réutiliser cette fonction où bon vous semble en faisant appel au fichier .inc.php :)
5 . Amélioration de votre fonction, utilisation des paramètres
On appelle paramètres d'une fonction, les variables qui lui sont passées en argument c'est à dire entre (), ils sont
séparés par une virgule, la fonction n'est pas obligée de recevoir des paramètres.
Supposons maintenant que nous voulons faire évoluer la fonction précédente avec des paramètres :
- La page vers laquelle sera redirigé le formulaire apres validation.
- Une valeur par défaut pour le champ login.
- Des nouveaux noms pour les boutons submit.
- Les descriptifs des champs à remplir.
1 - Passer les paramètres à la fonction :
L'en-tête change : on définit l'input, il est conseillé de préciser le type de la variable même si php n'est pas un langage extrêmement typé,
ça pourra vous aider plus tard si vous ne savez plus à quoi correspondent les différentes variables.
<?php
/*
** Function : form_login_member
** Input : STRING $action, STRING $login_def, STRING $sub_name, STRING $reset_name
** Output : aucun
** Description : affichage d'un formulaire de login de membre
** Creator : polom
** Date : 25/10/2001
*/
function form_login_member($action, $login_def, $sub_name, $reset_name, $login_txt, $pass_txt)
{
echo '<table>';
echo '<form action="'.$action.'" method="post" name="login_form">';
echo '<tr>';
echo '<td>'.$login_txt.'</td>';
echo '<td><input type="text" name="login" value="'.$login_def.'" size="20" maxlength="42"></td>';
echo '</tr>'
echo '<tr>'
echo '<td>'.$pass_txt.'</td>'
echo '<td><input type="password" name="pass" size="20" maxlenght="12"></td>';
echo '</tr>';
echo '<tr>';
echo '<td>';
echo '<input type="submit" name="'.$sub_name.'" value="val">';
echo '<input type="reset" name="'.$reset_name.'" value="anu">';
echo '</td>';
echo '</tr>';
echo '</form>';
echo '</table>';
}
?>
2 - Utiliser la fonction avec les paramètres :
Toujours dans notre fichier principal index.php :
<html>
<body>
<?php
include ("fonctions.inc.php");
$action = "ma_page_de_validation.php";
$login_def = "Ici votre login";
$sub_name = "Envoyer";
$reset_name = "Annuler la saisie";
$login_txt = "Votre login :";
$pass_txt = "Votre password :";
form_login_member($action, $login_def, $sub_name, $reset_name, $login_txt, $pass_txt);
?>
</body>
</html>
Et voila vous avez une belle fonction qui affiche un formulaire de login paramétrable propre et clair.
Rien ne vous empêche de modifier vous-même maintenant cette fonction pour la faire évoluer :) vous pouvez par exemple passer les tailles des boutons, des champs etc...
Ps : Vous pouvez bien sûr appeler des fonctions à l'intérieur d'autres fonctions.
Ps2 : Il n'est pas obligatoire de nommer les variables passées dans la déclaration de la fonction de la même façon que celles passées dans le script principal, cependant cela demeure plus clair d'utiliser les mêmes noms de variables dans les 2 cas.
Ps3 : Vous pouvez affecter des valeurs par défaut aux paramètres en les déclarant comme ceci : function toto($nbr, $nbr2 = "42") et la si vous ne précisez pas le paramètre $nbr2 il sera mis à 42 par défaut. Ceci est valable
uniquement pour les variables passées par valeur (voir ci-dessous).
6 . Paramètres par valeur ou par référence
Les paramètres d'une fonction peuvent être passés de deux façons différentes :
- Par valeur, c'est a dire que s'ils ont une valeur à l'extérieur de la fonction, seule la valeur est transmise à la fonction,
si la variable subit des modifications à l'intérieur de la fonction, ces modifications ne seront pas perçues dans le programme principal.
- Par référence, avec le signe & avant la variable (ex : &$cpt). Dans ce cas-là, l'adresse mémoire de la variable dans le programme
est passée à la fonction et toute modification de cette variable dans la fonction aura des répercutions à l'extérieur du programme.
Voici un exemple de programme utilisant une fonction avec un passage par valeur et ensuite par référence :
<?php
function modif_tab($tab)
{
$tab[0] = "j'aime le perl mais je préfere le php.";
}
?>
<html>
<body>
<?php
$tab = array("salut", "j'aime le fortran et le cobol");
// passage de $tab par valeur, la boucle for affichera
// salut, j'aime le fortran et le cobol
modif_tab($tab);
for ($i = 0; $tab[$i]; $i++)
echo "$tab[$i] ";
// passage de $tab par référence, la boucle for affichera
// salut, j'aime le perl mais je préfere le php.
modif_tab(&$tab);
for ($i = 0; $tab[$i]; $i++)
echo $tab[$i] ;
?>
</body>
</html>
Voilà j'espère que vous avez compris la nuance entre les deux types de passage :)
7 . Retourner des valeurs dans une fonction
Nous allons utiliser un exemple d'operations sur 2 nombres : addition, multiplication, division par exemple toujours dans un fichier index.php.
Le résultat de l'opération entre ces 2 nombres sera calculé dans la fonction puis retourné à l'aide de l'instruction return($result)
(NB: une fois arrivé à l'instruction return, tout traitement qui suit est arreté).
1 - le programme dans index.php qui fait appel à la fonction :
<html>
<body>
<?php
include ("functions.inc");
// operations "add", "sou" "mul"
$operation = "add";
$nbr1 = 42;
$nbr2 = 69;
$result = 0;
// recuperation du resultat de 42 + 69
$result = do_op($nbr1, $nbr2, $operation);
// affichage du resultat;
echo $result;
// affiche 111
?>
</body>
</html>
Donc ici nous initialisons les 2 nombres ainsi que l'opération à effecuter, puis on fait appel à la fonction do_op
contenue dans le fichier inclus dans fonctions.inc.php
2 - La fonction qui effectue les opérations :
<?php
/*
** Function : do_op
** Input : INT nbr1, INT nbr2, STRING operation
** Output : INT result
** Description : effectue une opération addition, multiplication ou division
** Creator : polom
** Date : 25/10/2001
*/
function do_op($nbr1, $nbr2, $operation)
{
if ($operation == "add")
return ($nbr1 + $nbr2);
else if ($operations == "mul")
return ($nbr1 * $nbr2);
else if ($operations == "div")
return ($nbr1 / $nbr2);
return (NULL);
}
?>
La fonction reçoit donc les 2 nombres et l'opération à faire, elle retourne le résultat une fois l'opération faite.
Vous pouvez aussi ne pas retourner directement le résultat dans la fonction précédente et le stocker, puis le retourner à la fin de la fonction.
Sachez que une seule valeur peut être retournée dans une fonction, si vous voulez retourner plusieurs valeurs, il faut à ce moment là utiliser
un tableau ou des variables globales (voir ci-dessous).
8 . Variables globales et statiques
Nous avons vu comment passer des variables à une fonction, il existe 2 types particuliers de variables utilisées souvent
dans les fonctions. Ce sont les variables globales et statiques.
Une variable globale déclarée à l'intérieur d'une fonction à l'aide de l'instruction global permet à une variable
d'être accessible en dehors de la fonction, vous pouvez accéder à cette fonction par son nom ou à l'aide du tableau $GLOBALS.
1 - Variables globales :
<?php
function glob_fonc()
{
global $cpt;
$cpt = 1;
}
?>
Ici $cpt sera accessible en dehors de glob_fonc après son appel et il aura la valeur 1, vous pouvez aussi y accéder
avec sa valeur dans le tableau de globales c'est à dire $GLOBALS["cpt"].
2 - Variables statiques :
Une variable statique déclarée à l'intérieur d'une fonction à l'aide de l'instruction static permet à une variable de garder
sa valeur à chaque appel de la fonction. L'initialisation d'une variable statique se fait au début de la fonction et à chaque appel
de la fonction dans le script elle gardera la valeur du dernier appel.
<html>
<body>
<?php
function stat_fonc()
{
static $cpt = 0;
$cpt++;
echo $cpt;
}
stat_fonc();
// affiche 1 c'est-à-dire premier appel à la fonction, $cpt est initialisé à 0 une seule fois
// et incrementé de 1
stat_fonc();
// affiche 2, $cpt a gardé la valeur précédente et l'incrémente de 1.
?>
</body>
</html>
?>
9 . Récursivité
Qu'est ce que la récursivité ? La récursivité est le fait d'une fonction qui se rappelle elle-même au moins une fois jusqu'à atteindre un résultat voulu.
Prenons un exemple simple pour expliquer ce principe à travers le calcul de la puissance d'un nombre entier.
1 - Le code dans index.php :
<html>
<body>
<?php
$nbr = 2;
$puissance = 4;
$result = puissance($nbr, $puissance);
echo $result;
?>
</body>
</html>
On affiche donc ici le résultat de 2 à la puissance 4 c'est à dire 16.
2 - la fonction normale sans récursion :
<?php
/*
** Function : puissance
** Input : INT nbr, INT puissance
** Output : INT result
** Description : effectue la puissance d'un nombre entier
** Creator : polom
** Date : 25/10/2001
*/
function puissance ($nbr, $puissance)
{
for ($total = $nbr; $puissance > 1; $puissance--)
$total = $total * $nbr;
return ($total);
}
?>
Donc là rien de bien compliqué on initialise le résultat au nombre
donc si on a par exemple 2 puissance 4 on a la trace suivante (une trace est l'état de vos variables tout le long de votre
programme, c'est une méthode intéressante pour suivre l'évolution de vos variables et débuger entre autre) :
-> départ $total = 2;
4 > 1 ok
$total = 4;
3 > 1 ok
$total = 8;
2 > 1 ok
$total = 16;
1 n'est pas > à 1 donc on arrète le traitement
-> fin $resultat = 16
3 - La même fonction en récursif :
Le principe est de rappeler toujours la fonction recurse_puissance
tant qu'on est pas arrivé à une puissance 1 comme dans le "for" précédemment.
On appellera cette fois-ci la fonction puissance de cette façon toujours dans le même programme vu avant :
-> recurse_puissance(2, 4, 2);
<?php
function recurse_puissance($nbr, $puissance, $total)
{
if ($puissance > 1)
return (recurse_puissance($nbr, $puissance - 1, $total * nbr));
return ($total);
}
?>
Et encore plus fort et plus beau en une seule ligne :
<?php
function recurse_puissance($nbr, $puissance, $total)
{
return (($puissance > 1) ? recurse_puissance($nbr, $puissances - 1, $total * $nbr) : $total);
}
?>
Il s'agit dans le deuxième exemple d'une utilisation d'une expression ternaire qui s'explique de la façon suivante.
On teste si $puissance est supérieur à 1, si c'est le cas on rappelle la fonction avec $puissance décrémentée de 1 et
le nouveau total, sinon on renvoie le $total final de l'opération.
Voici la trace de notre fonction récursive pour comprendre son utilité et son fonctionnement :
-> départ $puissance = 4, $total = 2;
4 > 1 ok
on renvoie la fonction avec $puissance décrémenté de 1 cad 3 et le $total de 2 * 2 = 4;
$total = 4;
3 > 1 ok
on renvoie la fonction avec $puissance décrémenté de 1 cad 2 et le $total de 4 * 2 = 8;
$total = 8;
2 > 1 ok
on renvoie la fonction avec $puissance décrémenté de 1 cad 1 et le $total de 8 * 2 = 16;
$total = 16;
1 pas supérieur à 1 on arrête de renvoyer la fonction, on renvoie $total et voila :)
La récursivité est donc une fonctionnalité qui permet de construire des algorythmes puissants, rapides
et souvent plus réduits qu'en passant par la technique normale littérale.
10 . Fonctions dynamiques et bonus track :)
Vous pouvez vous trouver dans le cas où vous ne savez pas quelle fonction devra être appelée à
tel moment du script.
Pour pouvoir gérer ça, il vous suffit de placer dans une variable le nom d'une fonction,
puis d'utiliser cette variable comme une fonction. Un exemple :
<?php
function write($text)
{
print($text);
}
function writeBold($text)
{
print("<b>$text</b>");
}
$fonction_var = "write";
$fonction_var("toto"); // affiche toto
$fonction_var = "writeBold";
$fonction_var("toto"); // affiche toto en gras
?>
Il existe 3 fonctions utiles dans la gestions des arguments passés dans une fonction dans php4.
Il s'agit de :
- func_get_arg qui permet de lire un argument spécifique.
- func_get_args pour obtenir l'ensemble des arguments sous forme d'une matrice ou tableau.
- func_num_args pour connaître le nombre d'arguments reçus par la fonction.
|