PHP met à disposition un grand nombre de fonctions internes (str_replace(), array_map(), strlen()...), mais on a très vite besoin de définir ses propres fonctions pour encapsuler une logique réutilisable. L'idée est simple : plutôt que de répéter les mêmes blocs de code à plusieurs endroits du script, on les regroupe dans une fonction que l'on appelle autant de fois qu'on en a besoin.
Définir une fonction
Pour créer une fonction en PHP, on utilise le mot-clé function suivi du nom de la fonction. Ce nom suit les mêmes conventions que les variables : uniquement des caractères alphanumériques et des underscores.
On ne peut pas donner à une fonction un nom déjà utilisé. Si on essaie de définir une fonction str_replace, PHP lèvera immédiatement une erreur car ce nom existe déjà.
Une fois notre fonction définie on peut l'appeler directement comme n'importe quel autre fonction.
Les paramètres
Les paramètres sont les variables que l'on passe à la fonction pour qu'elle puisse travailler. Ils sont listés entre parenthèses, séparés par des virgules.
Paramètres optionnels
On peut définir une valeur par défaut pour un paramètre. Ainsi, si la fonction est appelée sans cet argument, elle utilisera la valeur par défaut plutôt que de lever une erreur.
Sans valeur par défaut, appeler bonjour() sans argument produirait cette erreur :
L'erreur indique l'endroit où la fonction a été appelée et l'endroit où elle a été définie, ce qui facilite le débogage.
La valeur de retour
Une fonction peut simplement afficher quelque chose (avec echo), mais il est souvent plus utile qu'elle retourne une valeur. On utilise pour cela le mot-clé return, ce qui permet de stocker le résultat dans une variable ou de le passer directement à un autre traitement.
Un point important : dès que PHP rencontre un return, il sort immédiatement de la fonction. Tout ce qui est écrit après est ignoré.
C'est un comportement à garder en tête, notamment dans les boucles et les conditions, car un return dans un if fait sortir de la fonction, pas seulement du bloc conditionnel.
La portée des variables
C'est une subtilité importante des fonctions en PHP : une fonction s'exécute dans un contexte isolé. Les variables définies à l'extérieur ne sont pas accessibles à l'intérieur.
Pour PHP, $nom n'existe pas dans le contexte de la fonction et vaut donc null. La bonne pratique est de passer les données dont la fonction a besoin en paramètres :
Il existe le mot-clé global qui permet de forcer l'accès à une variable externe, mais c'est considéré comme une mauvaise pratique. Si on en a besoin, c'est généralement le signe que le code est mal organisé et que la variable devrait être passée en paramètre.
En revanche, les fonctions elles-mêmes sont disponibles globalement : contrairement aux variables, une fonction définie à un endroit du fichier peut être appelée depuis n'importe quelle autre fonction sans passer quoi que ce soit en paramètre.
Composer des fonctions entre elles
L'un des grands avantages des fonctions est de pouvoir les combiner. Une fonction peut appeler d'autres fonctions que l'on a définies au préalable.
Voici un exemple concret : une fonction repondre_oui_non() qui demande à l'utilisateur de taper o pour oui et n pour non, en boucle tant que sa réponse n'est pas valide.
On peut ensuite s'appuyer sur cette fonction dans une autre, demander_creneau(), qui demande à l'utilisateur une heure d'ouverture et une heure de fermeture valides :
On peut ensuite composer une troisième fonction qui utilise les deux précédentes pour collecter plusieurs créneaux :
On voit ici l'intérêt de la décomposition en fonctions : la logique de demander_creneaux() est simple et lisible parce qu'elle délègue les détails aux fonctions déjà définies.
Le typage
Depuis PHP 7, on peut typer les paramètres et la valeur de retour des fonctions. C'est une bonne habitude à prendre dès le départ.
Le type se place avant le nom du paramètre, et le type de retour s'indique après les parenthèses, précédé de :.
Par défaut, PHP autorise les conversions implicites : si on passe un float à une fonction qui attend un string, il sera converti automatiquement. En revanche, passer un tableau à une fonction qui attend une chaîne de caractères lèvera une erreur.
Pour interdire ces conversions et forcer un typage strict, on peut ajouter au tout début du fichier :
Dans ce mode, envoyer un float à une fonction qui attend un string produira une erreur, même si la conversion était techniquement possible.
Types nullables
Depuis PHP 7.1, on peut indiquer qu'un paramètre ou un retour peut être null en préfixant le type d'un ? :
Le typage a deux avantages principaux : il aide PHP à détecter les erreurs d'inattention, et il rend le code plus lisible pour quelqu'un qui le découvre, en indiquant immédiatement ce qu'une fonction attend et ce qu'elle produit.