Apprendre à programmer

Les Fonctions en PHP : Comprendre et Maîtriser par des Exercices Corrigés

Le langage PHP (Hypertext Preprocessor) est un langage de script largement utilisé pour le développement d’applications web dynamiques. Avec sa syntaxe simple et sa flexibilité, PHP permet aux développeurs de créer des sites web interactifs, de gérer des bases de données, et de manipuler des données en temps réel. Cependant, pour tirer pleinement parti des capacités de PHP, il est essentiel de maîtriser des concepts plus avancés tels que les fonctions, les classes, la gestion des exceptions, et la manipulation des structures de données complexes.

Cet article se propose de vous guider à travers une série d’exercices avancés en PHP. Ces exercices visent à tester et renforcer vos compétences, en vous confrontant à des scénarios réels que vous pourriez rencontrer lors du développement d’applications complexes. Avant de plonger dans les exercices, il est important de revoir certains concepts clés en PHP, qui serviront de base pour aborder les défis à venir.

Rappels

1. Les Fonctions en PHP

Les fonctions en PHP permettent d’encapsuler du code réutilisable. Elles peuvent accepter des arguments, retourner des valeurs, et même être récursives (c’est-à-dire qu’elles peuvent s’appeler elles-mêmes). Voici quelques points essentiels à retenir :

  • Déclaration d’une fonction :
  function nom_de_la_fonction($param1, $param2) {
      // Code à exécuter
      return $resultat;
  }
  • Fonctions anonymes et closures : En PHP, il est possible de créer des fonctions anonymes, c’est-à-dire des fonctions sans nom, souvent utilisées pour des callbacks ou des opérations à court terme.
  $fonction = function($param) {
      return $param * 2;
  };
  echo $fonction(5);  // Résultat : 10

2. Les Classes et Objets

PHP est un langage orienté objet, ce qui signifie qu’il permet de créer des classes pour structurer le code en objets, facilitant ainsi la modularité et la réutilisabilité.

  • Déclaration d’une classe :
  class MaClasse {
      private $propriete;

      public function __construct($valeur) {
          $this->propriete = $valeur;
      }

      public function afficher() {
          echo $this->propriete;
      }
  }
  • Héritage : Les classes en PHP peuvent hériter de propriétés et méthodes d’autres classes.
  class ClasseParente {
      public function direBonjour() {
          echo "Bonjour !";
      }
  }

  class ClasseEnfant extends ClasseParente {
      public function direAurevoir() {
          echo "Au revoir !";
      }
  }

3. Gestion des Exceptions

PHP offre un système de gestion des erreurs basé sur les exceptions, permettant de gérer les erreurs de manière contrôlée et d’éviter que le programme ne s’arrête brutalement.

  • Gestion des exceptions :
  try {
      // Code susceptible de générer une exception
      if ($conditionErreur) {
          throw new Exception("Erreur détectée");
      }
  } catch (Exception $e) {
      echo 'Exception capturée : ',  $e->getMessage(), "\n";
  }

4. Manipulation des Tableaux

Les tableaux sont l’une des structures de données les plus utilisées en PHP. Ils peuvent contenir des valeurs scalaires ou des objets, et peuvent être manipulés de diverses manières (tri, filtrage, recherche, etc.).

  • Création et manipulation des tableaux :
  $tableau = ['pomme', 'banane', 'cerise'];
  array_push($tableau, 'orange');  // Ajoute un élément à la fin du tableau
  sort($tableau);  // Trie le tableau par ordre alphabétique

5. Expressions Régulières

Les expressions régulières en PHP sont des outils puissants pour la recherche et la manipulation de chaînes de caractères. Elles permettent de valider des formats, de rechercher des motifs spécifiques, et bien plus encore.

  • Utilisation des expressions régulières :
  $texte = "Voici un exemple de texte avec un email test@example.com";
  if (preg_match('/[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}/', $texte, $matches)) {
      echo "Email trouvé : " . $matches[0];
  }

Conclusion des Rappels

Ces rappels couvrent les concepts de base qui seront indispensables pour résoudre les exercices avancés proposés dans cet article. Une bonne compréhension de ces fondements vous permettra d’aborder les défis avec plus de confiance et d’efficacité. Les exercices qui suivent vous pousseront à appliquer ces connaissances de manière pratique, tout en explorant des aspects plus complexes et nuancés de la programmation en PHP.

Voici la série d’exercices avancés avec des solutions détaillées et des commentaires pour chaque étape.

Exercice 1 : Fonction de calcul de puissance avec récursion

Énoncé : Écrivez une fonction récursive puissance($base, $exposant) qui calcule la puissance d’un nombre. Par exemple, puissance(2, 3) devrait retourner 8.

Solution :

function puissance($base, $exposant) {
    if ($exposant == 0) {
        return 1;
    } elseif ($exposant == 1) {
        return $base;
    } else {
        return $base * puissance($base, $exposant - 1);
    }
}

// Appel de la fonction
echo puissance(2, 3);  // Résultat : 8

Commentaire : Cette fonction utilise la récursion pour calculer la puissance. La condition de base gère les cas où l’exposant est 0 ou 1. Lorsque l’exposant est supérieur à 1, la fonction multiplie la base par le résultat de l’appel récursif avec un exposant réduit de 1.

Exercice 2 : Gestion des paramètres par référence

Énoncé : Créez une fonction ajouter_suffixe(&$texte, $suffixe) qui ajoute un suffixe à une chaîne de caractères passée par référence.

Solution :

function ajouter_suffixe(&$texte, $suffixe) {
    $texte .= $suffixe;
}

// Appel de la fonction
$salutation = "Bonjour";
ajouter_suffixe($salutation, " le monde");
echo $salutation;  // Résultat : Bonjour le monde

Commentaire : En passant le paramètre $texte par référence, toute modification apportée à $texte dans la fonction est directement appliquée à la variable d’origine. Ici, la fonction ajoute simplement le suffixe à la chaîne existante.

Exercice 3 : Fonction anonyme et tableau de fonctions

Énoncé : Créez un tableau de fonctions anonymes qui effectuent des opérations mathématiques de base (addition, soustraction, multiplication, division).

Solution :

$operations = [
    'addition' => function($a, $b) { return $a + $b; },
    'soustraction' => function($a, $b) { return $a - $b; },
    'multiplication' => function($a, $b) { return $a * $b; },
    'division' => function($a, $b) { return $a / $b; }
];

function executer_operations($nombre1, $nombre2, $operations) {
    foreach ($operations as $nom => $operation) {
        echo ucfirst($nom) . ": " . $operation($nombre1, $nombre2) . "\n";
    }
}

// Appel de la fonction
executer_operations(10, 5, $operations);

Résultat :

Addition: 15
Soustraction: 5
Multiplication: 50
Division: 2

Commentaire : Les fonctions anonymes sont créées directement dans un tableau associatif. Elles sont ensuite exécutées par la fonction executer_operations(), qui parcourt le tableau et applique chaque opération aux nombres fournis.

Exercice 4 : Closure avec une fonction de rappel (callback)

Énoncé : Écrivez une fonction filtrer_tableau($tableau, $callback) qui prend un tableau et une fonction de rappel en paramètre.

Solution :

function filtrer_tableau($tableau, $callback) {
    $resultat = [];
    foreach ($tableau as $element) {
        if ($callback($element)) {
            $resultat[] = $element;
        }
    }
    return $resultat;
}

// Exemple d'utilisation
$tableau = [1, 2, 3, 4, 5, 6];
$filtre = function($nombre) {
    return $nombre % 2 == 0;  // Retourne vrai pour les nombres pairs
};

$resultat = filtrer_tableau($tableau, $filtre);
print_r($resultat);  // Résultat : [2, 4, 6]

Commentaire : La fonction filtrer_tableau() utilise une closure (fonction de rappel) pour filtrer les éléments d’un tableau en fonction du critère défini dans la fonction de rappel. Ici, le critère est de vérifier si le nombre est pair.

Exercice 5 : Fonction générant une suite de Fibonacci

Énoncé : Créez une fonction fibonacci($n) qui génère un tableau contenant les n premiers éléments de la suite de Fibonacci.

Solution :

function fibonacci($n) {
    $suite = [0, 1];
    for ($i = 2; $i < $n; $i++) {
        $suite[] = $suite[$i - 1] + $suite[$i - 2];
    }
    return array_slice($suite, 0, $n); // Limite à $n éléments
}

// Appel de la fonction
print_r(fibonacci(10));  // Résultat : [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Commentaire : La suite de Fibonacci est générée en additionnant les deux derniers éléments de la suite pour obtenir le suivant. La fonction retourne les n premiers éléments de cette suite.

Exercice 6 : Fonction avec des arguments variadiques

Énoncé : Écrivez une fonction moyenne(...$nombres) qui calcule la moyenne de tous les nombres passés en argument.

Solution :

function moyenne(...$nombres) {
    $somme = array_sum($nombres);
    return $somme / count($nombres);
}

// Appel de la fonction
echo moyenne(1, 2, 3, 4);  // Résultat : 2.5

Commentaire : La syntaxe variadique ...$nombres permet de passer un nombre indéfini d’arguments à la fonction, qui sont traités comme un tableau. La fonction calcule la somme des éléments et retourne leur moyenne.

Exercice 7 : Génération de mots de passe aléatoires

Énoncé : Écrivez une fonction generer_mot_de_passe($longueur) qui génère un mot de passe aléatoire.

Solution :

function generer_mot_de_passe($longueur) {
    $caracteres = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $mot_de_passe = '';
    for ($i = 0; $i < $longueur; $i++) {
        $index = rand(0, strlen($caracteres) - 1);
        $mot_de_passe .= $caracteres[$index];
    }
    return $mot_de_passe;
}

// Appel de la fonction
echo generer_mot_de_passe(12);  // Exemple de résultat : G4m7Xz8L3hQ1

Commentaire : Cette fonction génère un mot de passe en choisissant aléatoirement des caractères parmi un ensemble défini. La boucle for construit le mot de passe caractère par caractère.

Exercice 8 : Fonction pour analyser une chaîne en JSON

Énoncé : Créez une fonction analyser_json($json) qui prend une chaîne JSON en entrée, la décode et retourne un tableau associatif.

Solution :

function analyser_json($json) {
    $resultat = json_decode($json, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        return $resultat;
    } else {
        return false;  // Retourne false en cas d'erreur
    }
}

// Appel de la fonction
$json = '{"nom": "Alice", "age": 25}';
$tableau = analyser_json($json);
if ($tableau) {
    print_r($tableau);  // Résultat : Array ( [nom] => Alice [age] => 25 )
} else {
    echo "Erreur lors de l'analyse du JSON";
}

Commentaire : La fonction analyser_json() utilise json_decode() pour transformer une chaîne JSON en tableau associatif. En cas d’erreur, elle retourne false et vérifie les erreurs avec json_last_error().

Exercice 9 : Fonction pour compresser et décompresser des chaînes

Énoncé : Écrivez deux fonctions compresser_chaine($texte) et decompresser_chaine($texte_comprime) pour compresser et décompresser une chaîne.

Solution :

function compresser_chaine($texte) {
    return gzcompress($texte);
}

function decompresser_chaine($texte_comprime) {
    return gzuncompress($texte_comprime);
}

// Appel de la fonction
$texte = "Ceci est un exemple de texte à compresser.";
$texte_comprime = compresser_chaine($texte);
echo $texte_comprime . "\n";

$texte_decompresse = decompresser_chaine($texte_comprime);
echo $texte_decompresse;  // Résultat : Ceci est un exemple de texte

 à compresser.

Commentaire : La fonction compresser_chaine() utilise gzcompress() pour compresser une chaîne, et decompresser_chaine() utilise gzuncompress() pour la décompresser. Cela peut être utile pour réduire la taille des données stockées ou transmises.

Exercice 10 : Fonction avec des expressions régulières

Énoncé : Créez une fonction extraire_emails($texte) qui prend un texte en paramètre et retourne un tableau contenant tous les emails trouvés.

Solution :

function extraire_emails($texte) {
    $emails = [];
    preg_match_all('/[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/', $texte, $emails);
    return $emails[0];
}

// Appel de la fonction
$texte = "Voici deux emails : test@example.com et exemple@test.org.";
$emails = extraire_emails($texte);
print_r($emails);  // Résultat : Array ( [0] => test@example.com [1] => exemple@test.org )

Commentaire : La fonction extraire_emails() utilise preg_match_all() avec une expression régulière pour extraire toutes les adresses email présentes dans un texte. Le résultat est un tableau contenant toutes les correspondances trouvées.


Ces solutions permettent de pratiquer des concepts avancés en PHP tout en consolidant les bases. En appliquant ces exercices, vous pourrez développer des compétences solides et une meilleure compréhension des fonctions en PHP.

Voici une série d’exercices complexes en PHP, conçus pour approfondir votre compréhension et vos compétences en programmation. Les solutions sont accompagnées de commentaires détaillés pour vous aider à comprendre chaque étape du processus.

Exercice 1 : Implémentation d’un système de cache simple

Énoncé : Créez une classe Cache qui permet de stocker des données dans un tableau associatif en mémoire. La classe doit inclure des méthodes pour :

  • Ajouter une donnée au cache avec une clé (set($key, $value)).
  • Récupérer une donnée par clé (get($key)).
  • Supprimer une donnée par clé (delete($key)).
  • Vérifier si une clé existe dans le cache (exists($key)).
  • Implémenter un mécanisme pour expirer les données après un certain temps.

Solution :

class Cache {
    private $cache = [];
    private $expiration = [];

    public function set($key, $value, $ttl = 60) {
        $this->cache[$key] = $value;
        $this->expiration[$key] = time() + $ttl;
    }

    public function get($key) {
        if ($this->exists($key)) {
            return $this->cache[$key];
        }
        return null;
    }

    public function delete($key) {
        if (isset($this->cache[$key])) {
            unset($this->cache[$key]);
            unset($this->expiration[$key]);
        }
    }

    public function exists($key) {
        if (isset($this->cache[$key]) && time() < $this->expiration[$key]) {
            return true;
        }
        $this->delete($key);  // Supprime la clé si expirée
        return false;
    }
}

// Utilisation de la classe Cache
$cache = new Cache();
$cache->set('user_1', 'Alice', 120);  // Expire dans 120 secondes

if ($cache->exists('user_1')) {
    echo $cache->get('user_1');  // Résultat : Alice
} else {
    echo 'Clé expirée ou non trouvée.';
}

Commentaire : Cette classe Cache stocke les données en mémoire avec un temps d’expiration (TTL – Time To Live). La méthode exists() vérifie si une donnée est encore valide avant de la retourner, sinon elle la supprime du cache.

Exercice 2 : Gestion d’un panier d’achat avec des réductions complexes

Énoncé : Créez une classe Panier qui permet d’ajouter des articles, de calculer le total, et d’appliquer une réduction complexe :

  • Une réduction de 20% pour les commandes supérieures à 200 euros.
  • Une réduction supplémentaire de 10% pour les clients VIP.
  • Une méthode pour afficher le récapitulatif du panier.

Solution :

class Panier {
    private $articles = [];
    private $client_vip = false;

    public function ajouterArticle($nom, $prix, $quantite = 1) {
        $this->articles[] = [
            'nom' => $nom,
            'prix' => $prix,
            'quantite' => $quantite
        ];
    }

    public function definirClientVIP($est_vip) {
        $this->client_vip = $est_vip;
    }

    public function calculerTotal() {
        $total = 0;
        foreach ($this->articles as $article) {
            $total += $article['prix'] * $article['quantite'];
        }
        return $total;
    }

    public function appliquerReduction() {
        $total = $this->calculerTotal();

        if ($total > 200) {
            $total *= 0.8;  // Réduction de 20%
        }

        if ($this->client_vip) {
            $total *= 0.9;  // Réduction supplémentaire de 10% pour VIP
        }

        return $total;
    }

    public function afficherRecapitulatif() {
        foreach ($this->articles as $article) {
            echo $article['nom'] . " x " . $article['quantite'] . " = " . ($article['prix'] * $article['quantite']) . "€\n";
        }
        echo "Total après réductions : " . $this->appliquerReduction() . "€\n";
    }
}

// Utilisation de la classe Panier
$panier = new Panier();
$panier->ajouterArticle('Ordinateur', 1500);
$panier->ajouterArticle('Souris', 50);
$panier->ajouterArticle('Clavier', 100);
$panier->definirClientVIP(true);

$panier->afficherRecapitulatif();

Commentaire : Cette classe Panier permet de gérer un panier d’achat avec une logique de réduction basée sur le montant total et le statut du client (VIP ou non). Les réductions sont appliquées séquentiellement pour calculer le montant final.

Exercice 3 : Système de gestion de droits d’accès basé sur des rôles

Énoncé : Créez une classe RoleManager qui permet de :

  • Définir des rôles (admin, éditeur, visiteur, etc.).
  • Assigner des permissions à chaque rôle (lire, écrire, supprimer).
  • Vérifier si un utilisateur a une permission spécifique en fonction de son rôle.

Solution :

class RoleManager {
    private $roles = [];
    private $utilisateurs = [];

    public function ajouterRole($nom_role) {
        if (!isset($this->roles[$nom_role])) {
            $this->roles[$nom_role] = [];
        }
    }

    public function ajouterPermissionAuRole($nom_role, $permission) {
        if (isset($this->roles[$nom_role])) {
            $this->roles[$nom_role][] = $permission;
        }
    }

    public function assignerRole($utilisateur, $nom_role) {
        $this->utilisateurs[$utilisateur] = $nom_role;
    }

    public function verifierPermission($utilisateur, $permission) {
        $role = $this->utilisateurs[$utilisateur] ?? null;
        if ($role && in_array($permission, $this->roles[$role])) {
            return true;
        }
        return false;
    }
}

// Utilisation de la classe RoleManager
$roleManager = new RoleManager();
$roleManager->ajouterRole('admin');
$roleManager->ajouterRole('editeur');
$roleManager->ajouterRole('visiteur');

$roleManager->ajouterPermissionAuRole('admin', 'lire');
$roleManager->ajouterPermissionAuRole('admin', 'ecrire');
$roleManager->ajouterPermissionAuRole('admin', 'supprimer');

$roleManager->ajouterPermissionAuRole('editeur', 'lire');
$roleManager->ajouterPermissionAuRole('editeur', 'ecrire');

$roleManager->ajouterPermissionAuRole('visiteur', 'lire');

$roleManager->assignerRole('Alice', 'admin');
$roleManager->assignerRole('Bob', 'editeur');
$roleManager->assignerRole('Charlie', 'visiteur');

echo $roleManager->verifierPermission('Alice', 'ecrire') ? "Autorisé\n" : "Non autorisé\n";  // Résultat : Autorisé
echo $roleManager->verifierPermission('Charlie', 'ecrire') ? "Autorisé\n" : "Non autorisé\n";  // Résultat : Non autorisé

Commentaire : La classe RoleManager permet de gérer des rôles et des permissions de manière flexible. Chaque utilisateur est associé à un rôle, et les permissions sont vérifiées en fonction du rôle attribué.

Exercice 4 : Implémentation d’un générateur de nombres aléatoires uniques

Énoncé : Créez une classe GenerateurUnique qui génère une série de nombres aléatoires uniques dans une plage donnée. La classe doit inclure :

  • Une méthode pour générer un nombre unique (generer()).
  • Une méthode pour réinitialiser le générateur et permettre de regénérer les mêmes nombres.

Solution :

class GenerateurUnique {
    private $nombres = [];
    private $plage;

    public function __construct($min, $max) {
        $this->plage = range($min, $max);
        $this->nombres = $this->plage;
    }

    public function generer() {
        if (empty($this->nombres)) {
            throw new Exception("Tous les nombres ont été générés.");
        }
        $index = array_rand($this->nombres);
        $nombre = $this->nombres[$index];
        unset($this->nombres[$index]);
        return $nombre;
    }

    public function reinitialiser() {
        $this->nombres = $this->plage;
    }
}

// Utilisation de la classe GenerateurUnique
$generateur = new GenerateurUnique(1, 10);

try {
    for ($i = 0; $i < 11; $i++) {
        echo $generateur->generer() . "\n";
    }
} catch (Exception $e) {
    echo $e->getMessage();  // Résultat : Tous les nombres ont été générés.
}

$generateur->reinitialiser();  // Perm

et de régénérer les nombres

Commentaire : La classe GenerateurUnique garantit que chaque nombre généré est unique dans la plage définie. Une fois tous les nombres générés, elle lève une exception. La méthode reinitialiser() permet de recommencer le processus.

Exercice 5 : Calcul de statistiques avancées sur un ensemble de données

Énoncé : Créez une classe Statistiques qui accepte un tableau de nombres et calcule :

  • La moyenne (calculerMoyenne()).
  • La médiane (calculerMediane()).
  • L’écart-type (calculerEcartType()).

Solution :

class Statistiques {
    private $nombres;

    public function __construct(array $nombres) {
        $this->nombres = $nombres;
        sort($this->nombres);
    }

    public function calculerMoyenne() {
        return array_sum($this->nombres) / count($this->nombres);
    }

    public function calculerMediane() {
        $count = count($this->nombres);
        $milieu = floor($count / 2);

        if ($count % 2) {
            return $this->nombres[$milieu];
        } else {
            return ($this->nombres[$milieu - 1] + $this->nombres[$milieu]) / 2;
        }
    }

    public function calculerEcartType() {
        $moyenne = $this->calculerMoyenne();
        $somme = 0;

        foreach ($this->nombres as $nombre) {
            $somme += pow($nombre - $moyenne, 2);
        }

        return sqrt($somme / count($this->nombres));
    }
}

// Utilisation de la classe Statistiques
$statistiques = new Statistiques([5, 10, 15, 20, 25]);

echo "Moyenne : " . $statistiques->calculerMoyenne() . "\n";  // Résultat : Moyenne : 15
echo "Médiane : " . $statistiques->calculerMediane() . "\n";  // Résultat : Médiane : 15
echo "Écart-type : " . $statistiques->calculerEcartType() . "\n";  // Résultat : Écart-type : 7.0710678118655

Commentaire : La classe Statistiques permet de calculer des mesures statistiques importantes à partir d’un tableau de nombres. Elle calcule la moyenne, la médiane, et l’écart-type, fournissant ainsi une vue d’ensemble complète de la distribution des données.


Ces exercices complexes sont conçus pour renforcer vos compétences en PHP tout en abordant des concepts de programmation avancés. En les résolvant, vous serez mieux préparé à relever des défis de programmation plus sophistiqués.

Autres articles

Exercices de Programmation Corrigés sur le Microprocesseur...
Le microprocesseur Motorola 6809 est un processeur 8 bits très...
Read more
Programmation ISO (ou G-code) : Guide
La programmation ISO (ou G-code) est un langage standard utilisé...
Read more
Exercices Corrigés Programmation ISO en tournage CNC
Voici une série d'exercices corrigés sur la programmation ISO en...
Read more

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *