Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox



Faire ses propres fonctions avec PHP : 4ème et dernière partie !

Compatible PHP. Cliquer pour en savoir plus sur les compatibilités.Par zebden (Anthony Lombard), le 28 décembre 2007

Vous voilà fin prêt pour faire vos fonctions, ce tour d'horizon des multiples possibilités offertes par l'écriture de fonctions (1, 2 et 3) n'a pas évoqué tous les autres aspects techniques que nous pouvons agrémenter dans notre programmation. C'est donc dans cette dernière partie, que nous allons découvrir ensemble les autres points non abordés.

global - static ou un aspect de la portée des variables :

Si vous n'avez jamais entendu parler de la portée des variables, cela va devenir un peu complexe mais pas forcement difficile à comprendre (paradoxe de la programmation). Quand vous déclarez une variable, on peut dire que vous lui donnez naissance dans un Monde A, or quand vous établissez une fonction, nous nous trouvons dans le Monde B ainsi tout ce qui peut exister dans le monde A devient obsolète et non utilisable (sauf exceptions).

On a vu précédemment que l'on peut inclure dans notre fonction différents paramètres qui contrairement aux apparences ne sont pas variables proprement dites mais des valeurs que l'on va attribuer à nos paramètres pour les utiliser ensuite (sauf exceptions). Mais il peut s'avérer utile de créer une sorte de passerelle du monde A au monde B pour utiliser une variable déclarée en amont ou bien de garder en mémoire des données dites locales (provenant du monde B) et ainsi incrémenter à volonté des données.

1.a/ global

<?php
// Nous déclarons une fonction quelconque
function ajouterDeuxA() {
// On fait passer la variable du Monde A au Monde B
global $maVariable;
// On retourne le resultat ou on a imputé deux !
return $maVariable + 2;
}
 
// Exemple d'utilisation concrete !
// On déclare une variable
$maVariable = 4;
 
$maVariable = ajouterDeuxA(); // global $maVariable vaut 4
 
echo $maVariable; // retourne 6;
 
$maVariable = ajouterDeuxA(); // global $maVariable vaut 6
 
echo $maVariable; // retourne 8; 
 
$autreVariable = ajouterDeuxA(); // global $maVariable vaut 8
 
echo $maVariable;    // retourne 8;
echo $autreVariable; // retourne 10;
 
$maVariable = ajouterDeuxA(); // global $maVariable vaut 8
 
echo $maVariable; // retourne 10.
?>

Personnellement, je trouve l'utilisation de global inadéquat aux attentes des programmeurs actuels pour une fonction, mais peut s'avérer utile dans les cas ou l'on voudrait faire passer, dans une portée locale (ici donc notre monde B), une variable de type objet ou array, et encore plus dans une méthode lorsqu'on établit une class (POO). Ce n'est pas pour autant un outil à négliger, mais si on peut éviter, c'est pas forcement mal !

Pour une donnée de type standard, je préfère utiliser une constante, qui mise à part le fait qu'elle soit globale (reconnue dans le monde B) ne peut être redéfinie, évidemment bien sûr quand les conditions générales me le permettent.

1.b/ static :

Pour parler simplement, toujours dans notre monde B, nous pouvons faire évoluer une variable et donc une valeur grâce au mot clé static. On parlera alors de portée locale. Je ne vais pas trop détailler, puisque static sera mis en avant dans le second chapitre de cet article, je reprends donc l'exemple du cours de lephpfacile (je change juste les désignations, parce que bon $toto …).

<?php
function evolution() {
 
static $maVariable= 1;
 
echo $maVariable . '<br />';
$maVariable++;
}
 
 
// Dans l'utilisation et toujours pour suivre l'exemple de lephpfacile
for($i=1; $i <= 50; $i++) {
evolution();
}
 
// Cela affichera à l'écran
/*
1
2
3
4
5
... (ici de 6 à 49)
50
*/
?>

On va lui trouver une utilisation toute particulière lorsque que l'on va établir une fonction récursive, hop ça tombe bien, c'est le sujet du 2ème chapitre.

Lien annexe : http://www.lephpfacile.com/cours/index.php?p=22

La récursivité:

Alors la récursivité, concrètement qu'est ce que c'est ? C'est lorsqu'une fonction fait appel à elle-même, finalement une “sorte de boucle” où il ne faudra oublier d'y fixer forcement une limite pour éviter une boucle infinie.

L’exemple suivant va combiner le mot clé static et la récursivité afin de renommer un fichier s'il est déjà présent dans le répertoire ou nous voulons le placer :

function renameFichier($fichierNom, $repertoireATester) {
 
	// On initialise un compteur avec comme valeur 0
	// pour éventuellement le faire évoluer.
	static $compteur = 0;
 
	// On test si le fichier existe dans le répertoire
	if(is_file($repertoireATester. $fichierNom)) {
 
		// Il existe nous allons donc le renommer.
		// Deux possibilités, le compteur est à 0, le fichier
		// n'a pas encore été renommé
		if(0 == $compteur) {
 
			// On incrémente d'une part le compteur
			$compteur++;
 
			// Masque du fichier
			$masque1  = '`(.*?)\.([a-z]{1,4})`i';
 
			// On va y inclure la chaîne [1]
			// 1 étant la valeur du compteur.
			$nouveauNom = preg_replace($masque1,
                                                  "$1".'['.$compteur.'].'."$2",
                                                   $fichierNom);
 
			// On aura alors une chaîne : fichier[1].ext
			// intervient alors notre récursivité 
			// pour tester ce nouveau nom s'il n'existe pas lui aussi.
			$fichierNom = renameFichier($nouveauNom, $repertoireATester);
 
			return $fichierNom;
			}
 
		// Notre fichier a déjà été testé au moins une fois
		// le nom est déjà présent
		else {
 
			// On incrémente encore notre compteur
			$compteur++;
 
			// On impute [n] à notre masque, 
			// n étant une valeur numérique exclusivement
 
			$masque2    = '`(.*?)\[([0-9]+)\]\.([a-z]{1,4})`i';
			$nouveauNom = preg_replace($masque2, 
                                                   "$1".'['.$compteur.'].'."$3", 
                                                   $fichierNom);
 
			// On continue de tester les noms retournés.
			$fichierNom = renameFichier($nouveauNom, $repertoireATester);
 
			}
		}
 
	// Nous ne sommes pas rentrer dans la condition
	// Fin de la fonction, on retourne le nouveau nom
	return $fichierNom;
	}
 
// -----------------------------------------------------------------------
// Utilisation :
 
/*
J’ai un répertoire qui contient les fichiers suivants
ici des photos.
fichier.jpg
fichier[1].jpg
fichier[2].jpg
fichier[3].jpg
fichier[5].jpg
*/
 
// Je précise le répertoire ou sont mes photos.
$pathToFichier = './path/to/image/';
// Le nom de fichier à tester.
$fichier = 'fichier.jpg';
 
// On récupère soit le nom originale s'il n'existe pas
// Soit un nouveau nom pour ne pas écraser l'ancien
$nouveauNom = renameFichier($fichier, $pathToFichier);
 
echo $nouveauNom; // Va retourner fichier[4].jpg (le 5 avait été mis exprès)
 
// Ensuite je n'aurais plus qu'à copier mon fichier avec son nouveau nom
copy($fichierAlaBase, $pathToFichier . $nouveauNom);
 
// J'ai un second fichier du même nom
$fichier = 'fichier.jpg';
 
// Nous testons comme au dessus
$nouveauNom = renameFichier($fichier, $pathToFichier);
 
echo $nouveauNom; // Va retourner fichier[6].jpg 
 
// On peut copier notre fichier sans ecraser fichier[5].jpg
?>

Note : un nom quelque il soit pour identifier n'importe quel élément doit être logiquement complètement abstrait pour ne jamais interférer avec l'utilisation en elle-même, par exemple les clefs numériques dans une base de données, donc ne vous compliquez pas la vie !

Les mauvaises langues diront que l'on pouvait faire plus simple pour renommer un fichier, mais étant donné que le but de l'article est de montrer la puissance de la récursivité surtout couplée au mot clé static, je dirais qu'au moins ça a le mérite de bien mettre en avant leur puissance respective. En revanche, je vous accorde qu'il faille un petit niveau pour bien assimiler ces notions. Je dirais alors : “Forgez !!! C’est comme ça que l'on devient … !! ” Je vous laisse deviner la suite !

Conclusion :

La notion de fonction peut-être facilement comprise mais pour le coup à force de pratique, la théorie n'est que là pour épauler et instaurer un socle de connaissance, si vous avez des soucis, reprenez ces 4 parties et exercez vous ! Simplement car ceci sera assez important lorsque nous allons débuter la Programmation Orienté Objet (POO pour les intimes) où nos fonctions deviendront des méthodes mais qui fonctionnent (pléonasme?) à peu près de la même manière !
Je n'ai pas parlé aussi de l'aspect de pointeur (Désignation provenant nottement du C/C++) où, en PHP, on préféra parler de passage par référence, mais ceci fera l'objet d'un article complet !

Bonne programmation !

article original sur http://www.zebden.fr/index.php?2006/05/02/23-faire-ses-propres-fonctions-avec-php-4eme-et-derniere-partie