PHP on line - Leçon n°4 :
Les fonctions en PHP

Recoucou mes p'tits biquets et mes p'tites biquettes. Bon avant tout, je vous souhaite à toutes et à tous la bienvenue pour ce quatrième volet de : Mes Aventures en PHP. Celles et ceux qui ont survécu à la précédente leçon, vont pouvoir continuer de se "prendre le chou" avec la présente leçon sur les fonctions. Mêmes motifs, même punition. De quoi allons-nous parler ?

Une fonction est un bloc de code défini une fois, puis invoqué à partir d'autres endroits du programme. Elle accepte un ou plusieurs arguments, accomplit un ensemble d'opérations prédéfinies selon ces arguments puis envoie une valeur en résultat. Elles permettent d'écrire des applications modulaires et structurées. Un morceau de code devant normalement être répété à de nombreuses reprises peut ainsi être appelé depuis n'importe quel endroit dans le reste du programme.

En écrivant et en testant des fonctions réutilisables, vous gagnerez du temps et diminuerez le nombre de bogues de votre code. PHP dispose de nombreuses fonctions internes, telles que gettype () et isset(). Dans ce tutorial, je vais vous apprendre à créer vos propres fonctions... Vous êtes contents ?

Comment ça marche...

Les fonctions sont déclarées à l'aide de l'instruction function. Pour calculer par exemple le cube d'un nombre.

<?php
// Declaration et definition de la fonction
function cube($nbr) {

            return $nbr * $nbr * $nbr;       // Renvoie $nbr eleve a la puissance 3
}
// Invoque la fonction cube() :
echo (cube(6));                                 // Imprime
?>

Enregistrez ce code sous le nom de fichier fonctions.php et exécutez le. Vous devez obtenir le résulat ci-dessous. Facile non !

La première ligne de code ci-dessus est de la forme :

                 function nom_fonction (paramètres) {
                       corps de la fonction
                 }

Le nom de la fonction "cube" suit le mot clé function, tandis que les paramètres (s'il en existe) sont placés entre parenthèses, séparés par des virgules. Le corps de la fonction doit ensuite figurer entre accolades. Pour invoquer une fonction, il suffit d'utiliser son nom suivi de deux parenthèses entre lesquels figurent les éventuels arguments.

Remarque

En PHP3, la déclaration d'une fonction doit être présente dans le code
avant toute invocation de la fonction. Ce n'est plus une contrainte avec PHP4 puisque la fonction peut être appelée avant sa déclaration.

L'invocation de la fonction cube (6) de l'exemple se résout en une expression dont la valeur est de 216. La "valeur" de la fonction est déterminée par l'instruction return placée dans le corps da la fonction. Lors de l'éxécution de return, la fonction s'arrête et l'exécution revient à la ligne ayant invoqué la fonction, substituant à l'appel de fonction la valeur renvoyée. Ainsi, la ligne echo (cube (6)); se résout en echo (216);. Une fonction ne doit pas nécessairement renvoyer une valeur. La fonction suivante par exemple n'utilise pas d'instruction return :

<?php
function js_alert($msg) {
     // crée une alerte Javascript à l'aide de $msg

echo (
     "\n<SCRIPT LANGUAGE='Javascript'>\n" .
     " <!-- \n" .
     " alert (\"$msg\");\n" .
     " // --> \n" .
     "</SCRIPT>\n"
  );

}

// Invoquer js_alert():
js_alert ("Mot de passe incorrect.");
?>


Il est également possible d'utiliser return afin de stopper l'exécution d'une fonction, même si aucune valeur n'est renvoyée. La fonction js_alert() ci-dessous a été modifiée afin de s'arrêter si $msg renferme une chaîne vide :

<?php
function js_alert($msg) {
     // cree une alerte Javascript a l'aide de $msg

     if ($msg == "") return;     // Arrete l'execution

echo (
     "\n<SCRIPT LANGUAGE='Javascript'>\n" .
     " <!-- \n" .
     " alert (\"$msg\");\n" .
     " // --> \n" .
     "</SCRIPT>\n"
  );

}

// Invoquer js_alert():
js_alert ("Mot de passe incorrect.");
js_alert ("");                     // cette ligne ne genere pas le code javascript
?>

Transmettre des arguments...

Les arguments constituent un moyen de transmettre des données à la fonction. Lors de l'écriture du code de cube (6), "6" est l'argument. Ce dernier est accessible à l'intérieur de la fonction en tant que paramètre $nbr. Le paramètre reçoit la valeur de l'argument correspondant, transmis à la fonction lors de son invocation. la fonction cube() utilise alors cette valeur pour calculer la valeur à renvoyer. L'exemple sautligne() ci-dessous reçoit un argument, 3, utilisé pour déterminer combien de sauts de lignes doivent être imprimés. A l'interrieur de la fonction, c'est le paramètre $x qui représente la nombre de lignes (ici,3).

<?php
function sautligne($x) {

// Imprime <BR> $x fois
for ($i = 0; $i < $x; ++$i) {
echo ("<BR>\n");
}

}

echo ("Anouchka, AZDS, Batmat, Ctrl@ltSuppr, Madcow, Petrucci");
sautligne(3);
echo ("sont les adorables et dévoués membres de la Team du Petrucciweb");
sautligne(3);
echo ("Ils représentent les amis idéaux !");
?>

Par défaut, les arguments sont transmis par valeur. Cela signifie que la variable paramètre interne à la fonction contient une copie de la valeur qui lui a été transmise. Si la valeur du paramètre change, cela ne modifie pas la valeur de la variable de l'instruction d'appel. Exemple.

<?php
function imprime_double($n) {
          $n = $n * 2;
          echo ($n);
}

$a = 5;
echo ("$a <BR>\n");            // Imprime 5
imprime_double($a);           // Imprime 10
echo ("<BR>\n");
echo ($a);                         // Imprime de nouveau 5
?>

La valeur de $a n'est pas modifiée, même après avoir été transmise à imprime_double(), puisque l'argument a été transmis comme valeur. En revanche, si un argument est transmis par référence, toute modification apportée à la variable paramètre modifie la variable de l'instruction d'appel. Une esperluette (&) est placée avant le nom du paramètre afin d'indiquer que l'argument doit être transmis par référence :

<?php
function augmentation(&$salaire, $pourcent) {
          // Augmente $salaire de $pourcent
           $salaire += $salaire * $pourcent/100;
}

$sal = 50000;
echo ("Salaire avant augmentation : $sal<BR>\n");       // Imprime 50000

augmentation($sal, 8);
echo ("Salaire après augmentation : $sal<BR>\n");       // Imprime 54000
?>

Il est également possible d'affecter une valeur par défaut à un paramètre, rendant de la sorte facultatif l'argument. Pour cela, il suffit d'affecter une valeur au paramètre au moment de la déclaration de la fonction :

<?php
function sautligne($x = 1) {

// Imprime <BR> $x fois
for ($i = 0; $i < $x; ++$i) {
echo ("<BR>\n");
}

}

echo ("Anouchka, AZDS, Batmat, Ctrl@ltSuppr, Madcow, Petrucci");
sautligne();    // Imprime <BR> une fois
echo ("sont les adorables et dévoués membres de la Team du Petrucciweb.");
sautligne(2);  // Imprime <BR> deux fois
echo ("Ce sont des êtres merveilleux et exquis !");
?>

Dans la déclaration de la fonction, il est important de faire figurer tous les paramètres possédant des valeurs par défaut à droite des paramètres qui en sont dépourvus. Le code suivant produirait une erreur :

<?php
function augmentation($pourcent = 8, &$salaire) {
          // Augmente $salaire de $pourcent
           $salaire += $salaire * $pourcent/100;
}

$sal = 50000;
echo ("Salaire avant augmentation : $sal<BR>\n");       

augmentation($sal);
echo ("Salaire après augmentation : $sal<BR>\n");       
?>

Cela aboutit au message suivant :

PHP interprète $sal comme étant le premier paramètre, soit $pourcent. Manifestement, c'est faux. Placer les éléments facultatifs à la fin évite cette confusion :

<?php
function augmentation(&$salaire, $pourcent = 8) {
          // Augmente $salaire de $pourcent
           $salaire += $salaire * $pourcent/100;
}

$sal = 50000;
echo ("Salaire avant augmentation : $sal<BR>\n");       

augmentation($sal);
echo ("Salaire après augmentation : $sal<BR>\n");       
?>

Attention vous devez être conscient du fait que si un argument est passé comme référence, il doit être une variable, et ni un littéral ni une constante, car ni l'un ni l'autre ne sont censés pouvoir changer de valeur :

<?php
function augmentation(&$salaire, $pourcent = 8) {
          // Augmente $salaire de $pourcent
           $salaire += $salaire * $pourcent/100;
}

$sal = 50000;
echo ("Salaire avant augmentation : $sal<BR>\n");       

augmentation(50000);
echo ("Salaire après augmentation : $sal<BR>\n");       
?>

Remarque

Attention ! Le message d'erreur affiché par votre système peut être différent si vous utiliser PHP3.

Portée et durée de vie d'une variable...

La portée d'une variable détermine quelles parties du programme y ont accès. Examinons l'exemple suivant :

<?php
$poste = "a";

function change_pos() {
          $poste ="b";
}

change_pos();
echo ("$poste");        // Imprime "a"
?>

Ce code imprime "a". La variable $poste à l'intérieur de la fonction possède une portée locale, et est de ce fait différente de la variable $poste externe à la fonction. La variable extérieure à la fonction possède une portée globale, car elle peut être atteinte et modifiée par tout fragment du code du script général, hors d'une fonction. pour accéder à une variable globale depuis une fonction, servez-vous de l'instruction global. Celle-ci indique à PHP que nous ne créons pas une nouvelle variable locale $poste, mais que nous souhaitons utiliser la variable $poste employé ailleurs dans la page.

<?php
$poste = "a";

function change_pos() {
          
        global $poste;

        $poste ="b";

}

change_pos();

echo ("$poste");        // Imprime "b"
?>

Le code imprime maintenant "b", parce que $poste fait référence à la même variable, à l'intérieur et à l'extérieur de la fonction. Nous pourrions également avoir recours au tableau intégré $GLOBALS, qui contient toutes les variables globales du script :

<?php
$poste = "a";

function change_pos() {
          
        $GLOBALS["poste"] = "b";

 }

change_pos();

echo ("$poste");        // Imprime "b"
?>

Les esprits vifs, et ceux qui s'interessent à ce que je raconte auront noté, que l'opérateur $ ne figure pas avant le mot poste lors de l'utilisation de ce tableau.

outre la portée, il convient de tenir compte de la durée de vie d'une variable. Il est parfois souhaitable qu'une variable locale de fonction conserve sa valeur d'une invocation à une autre. Dans le code qui suit, la variable locale $compteur est créée et fixée à zéro lors de chaque invocation de la fonction :

<?php

function compteur () {
          $compteur = 0;
          ++ $compteur;
}

?>

Mais cela serait inutile dans ce contexte. Il faut faire de $compteur une variable statique. Une variable statique conserve sa valeur précédente chaque fois qu'une fonction est invoquée :

<?php

function compteur () {
          static $compteur = 0;
          ++ $compteur;
}

?>

En déclarant une variable à l'aide de static, vous indiquez à PHP que vous souhaitez que sa valeur soit conservée entre deux invocations de la fonction. Lors du tout premier appel de la fonction, la variable statique va être créée et se voir affecter de la valeur spécifiée (ici 0), mais par la suite elle conservera sa valeur entre chaque appel de la fonction. La variable ne sera pas réinitialisée. Soyez conscient que cette valeur n'est mémorisée que le temps de l'exécution du script : si l'utilisateur recharge la page web, exécutant ainsi à nouveau le script PHP, la variable sera réinitialisée encore une première fois lors du tout premier appel à la fonction, lors de l'exécution du script.

Fonctions imbriquées et récursivité...

Les fonctions peuvent être imbriquées, ce n'est pas très utile de le faire, sauf à des fins d'organisation. On peut vouloir qu'une fonction en renferme d'autres dont elle dépendra. Toutes les fonctions du script sont cependant "globales", même les fonctions imbriquées. Autrement dit, chaque fonction peut être appelée à partir d'un autre emplacement du script. Un exemple valant toujours mieux que de longs discours, analysons la chose :

<?php

function vol($r) {
       // Renvoie le volume d'une sphère à partir de son rayon $r

       function cube($nbr) {

       // Renvoie $nbr élevé à la puissance 3
       return $nbr * $nbr * $nbr;
   }

   return 3.14159265358 * cube($r);

 }

$rayon = 2;
echo (vol($rayon));         // Imprime 25.13274122864
echo("<br>");
echo (cube(4));              // Imprime 64

?>

Bien que cube() soit imbriquée dans vol(), il est possible de l'invoquer à parir du script principal. Il est plus simple et surtout plus clair d'écrire :

<?php

function cube($nbr) {
       // Renvoie $nbr élevé à la puissance 3
       return $nbr * $nbr * $nbr;

}

function vol($r)  {  
// Renvoie le volume d'une sphère à partir de son rayon $r
 return 3.14159265358 * cube ($r); 
 }     

$rayon = 2;
echo (vol($rayon));         // Imprime 25.13274122864
echo("<br>");
echo (cube(4));              // Imprime 64

?>

Mais comme PHP est un langage puissant, vous vous doutez bien que la valeur de pi est une constante interne pour lui, nommée M_PI, si bien qu'il est possible de définir la fonction vol() :

   function vol($r) {
      // Renvoie le volume d'une sphère à partir de son rayon $r
   return M_PI * cube($r);

La récursivité est ce qui se produit lorsqu'une fonction s'invoque elle-même. Cette définition circulaire mène à des algorithmes simples. Le problème à résoudre est décomposé en une tâche élémentaire, répétée un nombre de fois donné. La récursivité est très fréquente dans le domaine des maths, comme par exemple les exposants. Mais n'étant pas un matheu de haute volée je vous évite une explication aussi hasardeuse qu'inutile, vu que je n'y entrave que dalle. Tout ce que j'peux vous dire c'est qu'en termes de vitesse de traitement il vaut mieux utiliser les boucles que la récursivité !

Affecter une fonction à une variable...

PHP dans sa grande bonté nous autorise à ce qu'une variable fasse référence à une fonction. Cela peut être fort pratique lorsque que des conditions dynamiques doivent définir quelle fonction doit être appelée dans une situation donnée. lorsqu'une variable fait référence à une fonction, celle-ci peut être invoquée en plaçant les arguments (s'il y en a) entre parenthèses, après le nom de la variable.

Dans l'exemple qui va suivre, vous ne pouvez savoir à l'avance quelle fonction doit être invoquée pour charger la page (en suppossant que l'URL de la page ait déjà été affectée à la variable $URL), si bien qu'il faut tester la valeur d'une autre variable ($type_nav) et affecter la fonction appropriée à $fonction_charge. Pigé ? Non ! Voyons ça de plus près.

<?php

switch ($type_nav) {
    case "NN":                                        // Netscape Navigator
        $fonction_charge = "load_nn";
         break;
    case "IE":                                         // Internet Explorer
        $fonction_charge = "load_ie";
         break;
    default:                                            // Tous les autres
        $fonction_charge = "load_generic";
  }

// Appeler maintenant la fonction de chargement adéquate :
$fonction_charge ($URL);

?>


Allez j'vous laisse tranquille avec mes histoires de PHP. Je vous souhaite à toutes et à tous de passer de bonnes et heureuses vacances, de me revenir en pleine forme à la rentrée. Attention aux coups de soleil et aussi aux coups d'lune ce sont les pires ! Profitez de la vie au maximum !

Asta La Vista I'll be back.

CtrlAltSuppr

Copyright Ctrl@ltSuppr | Tutorial Php 04 | Petrucciweb.com | PHP Online | Juin 2002.