# Programmation PHP/Fonctions

* Introduction
* Installer PHP
* Composer
* IDE
** PhpStorm
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Commentaires
** Premier programme
** Variables
** Variables superglobales
** Constantes
** Opérateurs
** Fonctions
** Tableaux
** Structures de contrôle
** Boucles
* Programmation avancée
** Dates
** Sessions
** Cookies
** Cache
*** Memcached
*** Redis
** Formulaire
** Fichiers
*** Objets COM
*** Images
** Mails
** Sécurité
** Programmation orientée objet
** Bases de données
*** Microsoft SQL Server
*** MySQL
*** PDO
*** SQLite
** Expressions rationnelles
** Code de haute qualité
*** Analyse statique de programmes
** Exceptions
** Xdebug
** Mots réservés
* Apprendre par l'exemple
** Utilisation de variables
** Un sommaire simple
** Interaction avec un formulaire
** Afficher le résultat d'une requête BDD
** Modifier une table
** Faire un livre d'or
** Faire un mini forum de discussion
** Parser avec DomXml
** Coder en MVC
** Faire un webservice
** Vérification RIO
** AJAX
** Sommaire en Ajax
** Mise à jour périodique d'un cadre
** Mini CMS
** Introduction
** Développement
*** Les couches choisies
*** Code de service
*** Modélisation
*** Implémentation
*** La vue
*** Ajaxification
*** Premier noyau
*** Fournir les données
*** IHM
** Rétrospective
** Conclusion
* Extensions PHP
** cURL
** DOMDocument
** JSON
** MING
** SPL
* Bibliothèques externes
** ADODB
** DOMPDF
** FPDF
** PHPExcel
** PHPMailer
** PHPWord
** RabbitMQ
* Cadriciels
** CakePHP
** PEAR
** Symfony
** Frameworks de tests
*** PHPUnit
*** SimpleTest
*** Behat
* Logiciels métier
* Problèmes connus
* Introduction
* Installer PHP
* Composer
* IDE
** PhpStorm
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Commentaires
** Premier programme
** Variables
** Variables superglobales
** Constantes
** Opérateurs
** Fonctions
** Tableaux
** Structures de contrôle
** Boucles
* Programmation avancée
** Dates
** Sessions
** Cookies
** Cache
*** Memcached
*** Redis
** Formulaire
** Fichiers
*** Objets COM
*** Images
** Mails
** Sécurité
** Programmation orientée objet
** Bases de données
*** Microsoft SQL Server
*** MySQL
*** PDO
*** SQLite
** Expressions rationnelles
** Code de haute qualité
*** Analyse statique de programmes
** Exceptions
** Xdebug
** Mots réservés
* Apprendre par l'exemple
** Utilisation de variables
** Un sommaire simple
** Interaction avec un formulaire
** Afficher le résultat d'une requête BDD
** Modifier une table
** Faire un livre d'or
** Faire un mini forum de discussion
** Parser avec DomXml
** Coder en MVC
** Faire un webservice
** Vérification RIO
** AJAX
** Sommaire en Ajax
** Mise à jour périodique d'un cadre
** Mini CMS
** Introduction
** Développement
*** Les couches choisies
*** Code de service
*** Modélisation
*** Implémentation
*** La vue
*** Ajaxification
*** Premier noyau
*** Fournir les données
*** IHM
** Rétrospective
** Conclusion
* Extensions PHP
** cURL
** DOMDocument
** JSON
** MING
** SPL
* Bibliothèques externes
** ADODB
** DOMPDF
** FPDF
** PHPExcel
** PHPMailer
** PHPWord
** RabbitMQ
* Cadriciels
** CakePHP
** PEAR
** Symfony
** Frameworks de tests
*** PHPUnit
*** SimpleTest
*** Behat
* Logiciels métier
* Problèmes connus
[ Modifier le sommaire ]

## Définition de fonction

Outre les dizaines de fonctions natives, PHP permet bien entendu d'écrire ses propres fonctions. Pour en définir une, il suffit d’utiliser le mot-clef function. Comme le langage est faiblement typé, une fonction peut retourner n’importe quel type de valeur (chaîne, entier…) ou ne rien retourner du tout. Enfin, ses arguments peuvent avoir des valeurs par défaut, être nommés (depuis PHP8) et sont limités à 12 par fonction.
Notez que lorsqu'une fonction arrive à un return, elle l'effectue puis se termine, même s'il y a d'autres instructions après.
Contrairement à PHP 8, PHP 7 et antérieur ne permet pas d'appeler certains arguments par leurs noms : si l'on souhaite appeler un des derniers arguments, il faut donc définir tous ceux avant lui, même les optionnels. Toutefois pour éviter ce désagrément, on peut utiliser la classe ReflectionMethod. NB : il existe aussi ReflectionClass.

#### Generator

Par ailleurs, en cas de gros volume de données à retourner, on peut utiliser yield au lieu de return pour les décomposer à l'aide du générateur PHP (classe Generator).
Ne jamais faire de condition "yield" sinon "return" car PHP renverra toujours un Generator mais si elle est fausse (si besoin il faut les séparer dans deux fonctions).

### Portée des variables

Le problème de portée des variables est assez réduit en PHP. Une fonction n'a accès qu’à ses arguments, ses propres variables et aux variables globales importées statiquement (mot clé global). De ce fait, il y a peu de confusion.
Toujours suivant le même principe, les variables utilisées dans une fonction sont toutes détruites à sa sortie (les variables globales non, bien entendu).
* Exemple
* $valeur1=10;
* $valeur2=20;
* function exemple($valeur)
* global $valeur1; // récupération de la valeur globale de $valeur1
* $valeur3=5;
* $calcul=$valeur1+$valeur2+$valeur3+$valeur; // 10 + 0 + 5 + le paramètre qui sera entre parenthèses.
* //$valeur2 n'ayant pas été définie comme valeur globale, la variable $valeur2 est donc vide.
* return $calcul;
* echo exemple(2); // affiche 17
On peut aussi trouver un peu plus compliqué si vous utilisez deux fichiers. L'un pour les variables, l'autre pour les traitements.

#### Espaces de noms

Depuis PHP 5.3.0, des espaces de noms peuvent être définis pour cloisonner certains objets, à l'aide du mot clé namespace utilisé en début de fichier. Exemple de définition :
Soit un fichier TestNS.php suivant :
Le fichier doit être encodé en ANSI ou Unicode sans BOM, mais pas en Unicode seul, sous peine d’avoir l'erreur Namespace declaration statement has to be the very first statement in the script, et d'être obligé de coller le mot "namespace" à "?php").
Exemple d’utilisation :

### Références de variables

Les références sont utiles lorsque l’on souhaite retourner plusieurs valeurs dans une fonction. On utilise alors le passage d'argument par référence, qui fait que quand une fonction modifie un argument, la valeur de la variable du programme principale change aussi.
Pour utiliser un argument en tant que référence, il suffit d'y mettre l'opérateur de référence, le symbole & devant, dans la déclaration de la fonction.
Un exemple concret devrait vous faire comprendre :
* Exemple
* function foo(&$arg1, &$arg2, $arg3)
* $arg1 = 4;
* $arg2 = 6;
* $arg3 = 8;
* foo($var1, $var2, $var3);
* print $var1; //affichera 4
* print $var2; //affichera 6
* print $var3; //affichera NULL car $arg3 n'est pas une référence (pas de &)

## Fonctions variables

On appelle "fonction variable" une fonction dont on ne peut prédire le nombre d'arguments. Ce genre de fonction pourra se révéler pratique pour exécuter certains codes répétitifs ou le programmeur n'a pas envie de recopier le nom de la fonction pour n valeurs.
Pour cela, il faut retenir deux fonctions importantes :
* func_num_args : permet de compter le nombre d'arguments (retourne true ou false).
* func_get_args : permet de récupérer la valeur d’un argument (retourne un tableau de valeur).
Ces deux fonctions ne peuvent s'utiliser qu’à l'intérieur d’une fonction; dans le cas contraire un message d'erreur s'affichera.
* Exemple
* function afficher_variables
* $nb_args = func_num_args;
* $list_args = func_get_args;
* for ($i = 0; $i < $nb_args; $i++) {
* echo $list_args[$i].' ';
* $var1 = 'programmeur';
* afficher_variables('Je suis', $var1, ', c\'est utile', ', c\'est intéressant.'); // Et on peut en rajouter autant que nécessaire.
Le code se comprend de lui-même. Il affichera : Je suis programmeur, c’est utile, c’est intéressant.

## Fonctions de rappel

Pour passer une fonction en argument d'une autre, il faut utiliser call_user_func. Ex :

## Fonctions anonymes

Une fonction sans nom peut être stockée dans une variable permettant de l'appeler. Le mot clé use permet d'injecter des variables globales dedans. Ex :

## Fonctions fléchées

Depuis PHP7.4, on peut définir une fonction anonyme avec l'opérateur "=>" et le mot réservé fn. Ex :

## Fonctions prédéfinies

Voici une liste des fonctions globales prédéfinies en PHP les plus usuelles.
* print (alias echo) : affiche le contenu de la variable placée en paramètre.
* printf et dérivés (ex : sprintf) : print formaté, affiche un texte dont on remplace les marqueurs, numérotables, par les variables en paramètre. Exemple :
Les types suivants sont généralement utilisés :
* d : digit
* f : float
* s : string
* Pour échapper les "%" pour sont interprétés par ces fonctions, ce n'est pas "\" mais "%".
* Ne pas utiliser les doubles quotes sous peine de Undefined variable: d.
* sleep($secondes) : attend un certain nombre de secondes (utilisation déconseillée quand un humain doit attendre un résultat).
* call_user_func_array('maFonction', 'mesArguments') : exécute une fonction à partir de son nom en chaîne de caractères.
* getenv : affiche toutes les variables d'environnement, ou celle demandée en paramètre.
* ignore_user_abort(true) : ("false" par défaut) continue l'exécution d'un script lancé par un utilisateur, même s'il change de page ou clique annule le chargement.
* header : ajoute une clé dans l'en-tête HTTP de la réponse.
* ini_get : lit le php.ini.
* ini_set : modifie le php.ini le temps de l'instance.
* set_time_limit : redéfinit la limite de temps du php.ini.
* require : importe le code PHP d'un autre fichier, avec une erreur si c'est impossible.
* require_once : idem en garantissant que chaque fichier n'est ajouté qu'une fois.
* include : importe le code PHP d'un autre fichier, sans erreur si c'est impossible.
* include_once : idem en garantissant que chaque fichier n'est ajouté qu'une fois.
* getmypid : retourne l'ID du processus courant dans l'OS.

### Sur les chaînes

* trim($string) : supprimer les espaces et retours chariots en début et fin de chaîne par défaut. Son second paramètre permet de remplacer les symboles à retirer.
* strip_tags : supprime les balises HTML de la chaîne mentionnée en paramètre 1, en conservant ceux en paramètre 2 (sous la forme d'une chaine comme '<p><br>').
* ucfirst : met une majuscule en début de chaîne.
* lcfirst : met une minuscule en début de chaîne.
* strtoupper : met en lettres capitales toute la chaîne.
* strtolower : met en bas de casse toute la chaîne.
* strlen : compte la taille d'une chaîne en octets. Pour avoir le nombre de caractères, utiliser mb_strlen (pour multibyte).
* str_contains($chaine, $cle) : cherche si une chaîne contient une sous-chaîne.
* <codestr_starts_with($chaine, $cle) : vérifie si une chaîne commence par une sous-chaîne.
* str_replace($ancien, $nouveau, $texte) : remplace des caractères par d'autres dans un texte ou un tableau.
* str_ireplace($ancien, $nouveau, $texte) : fait la même chose en ignorant la casse.
* strtr($texte, $ancien, $nouveau) (string translate) : réputée plus rapide que str_replace.
* strpos($meubleDeFoin, $aiguille) : première position d'une sous-chaine. Attention : ne jamais utiliser comme si elle renvoyait un booléen (if (strpos)) car si la recherche est en première position (0) elle sera considérée comme fausse avec le typage faible. Il faut tester l'existence avec if (false !== strpos).
* stripos($meubleDeFoin, $aiguille) : fait la même chose en ignorant la casse.
* strrpos($meubleDeFoin, $aiguille) : dernière position d'une sous-chaine.
* substr($texte, $debut , $fin) : tronque un texte en sous-chaine. Utiliser mb_substr en Unicode.
    Pour accéder à un seul caractère d'une chaine, PHP peut la considérer comme un tableau (ex : $chaine[0]).
    Ex :
* substr_count($chaine, $sous-chaine) : compte le nombre de sous-chaine dans une chaine.
* str_pad : complète une chaine avec un caractère pour qu'elle atteigne la taille demandée si ce n'était pas le cas. Ex :
* eval($chaine) : exécute une chaine comme un script PHP.
* count_chars($chaine) : renvoie un tableau avec en clés chaque caractère de la chaine, et en valeur son nombre d'occurrences. Pratique pour détecter les anagrammes.

#### Encodage

    Pour plus de détails voir : Coder avec Unicode/Conversion#PHP.
* utf8_encode($chaine) et utf8_decode($chaine) sont dépréciée en PHP 8.2, il faut utiliser à la place mb_convert_encoding($chaine, 'UTF-8') et mb_convert_encoding($chaine, 'ISO-8859-1').

#### URLs

* parse_url : découpe une chaîne en partie d'une adresse URL (protocole, domaine et chemin d'accès).
* http_build_query : crée une URL à partir d'un tableau d'arguments GET. Par défaut le séparateur est "&" (3e argument). Cette fonction échappe les séparateurs. Ex :

### Sur les nombres

* pow($nombre, $exposant) (power) : élève un nombre à la puissance de l'exposant donné.
* sqrt($nombre) (square root) : racine carrée.
* max($nombre1, $nombre2, ...) : affiche le plus grand nombre parmi ceux en paramètres.
* min($nombre1, $nombre2, ...) : affiche le plus petit nombre d'une liste.
* round($nombre) : arrondit un nombre à l'entier le plus proche, ou selon une précision en deuxième paramètre s'il est renseigné. Exemple :
* number_format($nombre, 2, ',', ' ') : formate un nombre donné, où "2" représente le nombre de chiffres après la virgule, "," le séparateur décimal et " " le séparateur de milliers.
Ne jamais comparer des nombres issus du number_format car les séparateurs faussent les calculs. Exemple :

### Bufferisation de sortie

La bufferisation de sortie bloque l'envoie de données au client HTTP pour les mettre dans une mémoire tampon à la place.
* ob_start : démarre l'utilisation du tampon.
* ob_get_contents : affiche le contenu du tampon.
* ob_clean : efface le tampon sans l'envoyer.
* ob_flush : envoie le tampon au client.

## Références

* ↑ http://php.net/manual/fr/indexes.functions.php
* ↑ http://php.net/manual/fr/reflectionclass.getdoccomment.php
* ↑ http://php.net/manual/fr/language.generators.syntax.php
* ↑ http://php.net/manual/fr/language.namespaces.rationale.php
* ↑ http://php.net/manual/fr/ref.funchand.php
* ↑ http://php.net/manual/fr/function.sprintf.php
* ↑ https://www.alsacreations.com/article/lire/254-le-point-sur-la-fonction-include-php.html
* ↑ http://php.net/manual/fr/function.str-replace.php
* ↑ https://www.keycdn.com/blog/php-performance#10-use-the-strongest-str-functions
* ↑ http://php.net/manual/fr/function.strpos.php
* ↑ http://php.net/manual/fr/function.max.php
* ↑ http://php.net/manual/fr/function.round.php
* ↑ https://www.php.net/manual/fr/ref.outcontrol.php