1 Base du PHP

1.1 Objectifs

Nous allons, dans ce premier TP, utiliser le langage PHP comme un langage de script en dehors d’un contexte web :

  • Les variables, les types, les structures de contrôle

  • Les tableaux

  • Les fonctions

1.2 Environnement

Pour pouvoir développer en PHP, il nous faut un interpréteur. Dans un premier temps nous allons vérifier qu’il y a un interpréteur installé sur votre machine. Pour cela vous allez saisir la commande suivante :

php --version

Le résultat de la commande doit vous indiquer la version de l’interpréteur PHP installé sur votre machine sinon une erreur vous indique que la commande n’est pas connue.

Dans la suite nous allons utiliser une version supérieure à la version 7.1.3. Assurez vous que cela correspond à la version installée sur votre machine.

Pour créer vos scripts vous aurez besoin d’un éditeur de texte. L’éditeur Visual Studio Code peut convenir après l’avoir configuré rapidement à l’aide de ce document.

Cependant lorsque nous allons manipuler plusieurs fichiers PHP à l’intérieur d’un projet, un éditeur simple ne suffira plus. Il est possible d’utiliser gratuitement l’IDE (Environnement de Développement Intégré) proposé par JetBrains : PhpStorm. PhpStorm est disponible sur les machines de TP de l’IUT, pour l’utiliser il vous faut une licence d’utilisation qui est distribuée gratuitement pour les étudiants (valable un an renouvelable tant que vous êtes étudiants). Voir ce lien pour obtenir cette licence gratuite.

Dans ce TP nous allons créer un script pour chaque question posée.

1.3 Les variables et les structures de contrôle

Dans un fichier exo1.php placer le code PHP qui permet de répondre aux questions suivantes :

Incrémenter et afficher la valeur d’une variable de 1 à 10.

Ici on utilise une variable que l’on incrémente dans une boucle et que l’on affiche. Proposez plusieurs types de boucles. Proposez plusieurs types d’affichage. Ici quelle est la boucle la plus adaptée ?

Incrémenter une variable de 1 à 50 et afficher sa valeur uniquement quand celle-ci est paire.

On peut reprendre le travail effectué précédemment et y ajouter un test.

1.3.1 Manipulation des types

Pour lire des données saisies au clavier (entrée standard), on pourra utiliser l’instruction suivante :

    $var = trim ( fgets ( STDIN ) );

La constante STDIN désigne l’entrée standard pour le processus en cours (l’interpréteur php de votre script), par défaut le clavier de l’ordinateur. la fonction fgets permet de lire une ligne du fichier donné en paramètre (ici le clavier). La fonction trim traite les espaces avant et après les caractères utiles dans la ligne. Le résultat final est assigné à la variable$var.

Saisir une donnée au clavier et après s’être assuré qu’une valeur a été saisie, afficher son type parmi :

  • entier

  • réel

  • chaîne de caractères

    • Pour s’assurer qu’une donnée a été saisie, on pourra utiliser la fonction qui donne la taille d’une chaîne de caractères : strlen.
    • La fonction empty devra être utilisée avec précaution.
    • Il faut faire la distinction entre la fonction is_numeric et la fonction is_int. La fonction is_numeric renvoie vrai si le paramètre est un nombre ou une chaîne de caractères numériques. La fonction is_int renvoie vrai si le paramètre est de type entier (beaucoup plus restrictif).
    • voir la documentation pour les autres types de données.

Traiter le cas où la chaîne de caractères saisie correspond à un booléen. Si par exemple la chaîne de caractères correspond à : true, false, on, off, n, y alors on affichera le type booléen.

On pourra utiliser la structure de contrôle switch.

1.3.2 Les constantes

Après avoir défini la constante PI = 3.14 calculer la périmètre du cercle, la surface du disque, la surface d’une sphère, le volume de la boule d’un rayon dont on aura saisi la valeur.

    • Pour retrouver les formules de calculs de surface et de volume
    • On utilisera, en autres, les fonctions is_numeric(), strlen() pour vérifier que les données saisies sont bien correctes.

Calculer le plus grand diviseur commun (PGCD) de deux entiers saisis sur l’entrée standard en utilisant l’algorithme suivant:

Afficher("Saisir un entier : ")
Lire(a) 
Afficher ("Saisir un entier :") 
Lire(b) 
si ( a <  b) alors
  x <- b
  y <- a
sinon
  x <- a
  y <- b
fsi
reste <- (x modulo y) 
Tq (r != 0) faire
  x <- y
  y <- reste
  reste <- (x modulo y)
fait
Afficher("Le PGCD vaut ", y)
    • Comme dans l’exercice précédent, on utilisera, en autres, les fonctions is_int(), is_numeric(), strlen() pour vérifier que les données saisies sont bien des entiers strictement positifs.
    • On va manipuler des boucles ici, il faut choisir la plus adaptée.
    • Pour terminer l’exécution en cas d’erreur on pourra utiliser la fonction die()

1.4 Tableau

1.4.1 Stockage dans un tableau

Saisir des valeurs à partir de l’entrée standard et les stocker dans un tableau. La saisie se termine quand l’utilisateur valide une chaîne de caractères vide.

Même chose avec une insertion en tête

Ici il faut utiliser la fonction array_unshift().

Trier les éléments du tableau

On souhaite maintenant pouvoir retrouver un élément du tableau à partir d’une clé (Création d’un tableau associatif, les indices ne sont plus des entiers mais des chaînes de caractères).

Saisir pour chaque entrée du tableau, une clé et la valeur associée. Fin de saisie quand l’utilisateur donne une clé vide.

Trier le tableau par ordre croissant des valeurs et ensuite par ordre décroissant des clés

Ici il faut utiliser la fonction asort(),arsort(), ksort() et krsort().

1.4.2 Le crible d’Eratosthène

Donner la liste des nombres premiers plus petit qu’un entier donné à partir de l’entrée standard. On pourra utiliser le crible d’Erastosthène dont voici une version de l’algorithme :

premiers <- vide
Afficher ("Saisir une limite : ")
Lire(limite)
tab <- liste des entiers de 2 à limite
tant que <- tab non vide faire
  premiers <- premiers union tab[0]
  tab <- tab sans les multiples de tab[0]
fait
return premiers
    • La variable premiers est un tableau (vide au départ)
    • La variable limite est un entier positif qui arrête la recherche dès que cette limite est atteinte.
    • La variable tab est un tableau dans lequel on va ranger les entiers compris entre 2 et limite.
    • Pour parcourir le tableau tab, on ne peut pas utiliser la boucle for (pourquoi ?)
    • L’instruction tab <- tab sans les multiples de tab[0] consiste à retirer du tableau tab les éléments qui sont multiples du premier élement (donc pas premier). Il est très dangereux de modifier le contenu d’un tableau alors que l’on est en train de le parcourir. La solution consiste à créer un tableau intermédiaire multiple (qui va contenir tous les multiples du premier élément), puis à la fin du parcours du tableau tab de supprimer d’un coup (à l’aide de la fonction array_diff()) tous les éléménts contenus dans le tableau intermédiaire multiple du tableau tab.

1.4.3 La table de multiplication

On désire afficher la table de multiplication pour les nombres de 1 à 10 et pour cela nous allons utiliser un tableau à deux dimensions.

Créer le tableau à deux dimensions qui contient la table de multiplication pour les entiers de 1 à 10.

Un tableau à deux dimensions est un tableau de tableaux. Il faut donc dans un premier temps créer un tableau (les lignes). Dans un deuxième temps, chaque entrée ajoutée sera un tableau (les colonnes).

Afficher le tableau à deux dimensions (10 colonnes par ligne).

Consiste à faire un parcours du tableau de tableaux. Il y aura deux boucles, une première (externe) qui traite une ligne après l’autre et une deuxième (interne) qui traite une colonne après l’autre. Pour rendre un affichage qui soit bien formatté, on pourra utiliser la fonction sprintf() qui permet de formatter une chaîne de caractères.

1.5 Fonctions

1.5.1 Produits

Dans cet exercice nous allons gérer les valeurs nutritionnelles (Protides, Glucides, Lipides, Calories) de produits. Les produits sont stockés dans un tableau associatif fruits. Le nom du produit est la clé d’accès au produit dans le tableau. Chaque produit est stocké dans un tableau associatif avec les clés nom, protides, glucides, lipides, calories.

    // tableau fruit Pomme 

    Array
    (
      [nom] => Pomme
      [protides] => 0.3
      [glucides] => 12.6
      [lipides] => 0.3
      [calories] => 54
    )

Ecrire la fonction ajouterProduit(nom, protides, glucides, lipides, calories) qui ajoute un produit au tableau global $fruits.

    • Les paramètres de la fonction sont des variables PHP, ne pas oublier de mettre un symbole $ devant le nom de la variable.
    • Le tableau associatif fruits n’est pas un paramètre de la fonction, il faut donc le déclarer comme une variable globale dans la fonction.
    • Les clés sont uniques, il faut donc vérifier que le nom indiqué, en premier paramètre, n’est pas déjà une clé dans le tableau ($fruits[$nom] === NULL, isset($fruits[$nom])).
    • On peut utiliser une valeur pas défaut, si un paramètre autre que nom n’est pas indiqué.
    • Il faut créer un tableau associatif pour stocker le nouveau fruit.

Nous allons définir des recettes qui seront composées d’un nombre variable de produits sans préciser de quantité. Les recettes sont stockées dans un tableau associatif recettes. Le nom de la recette est la clé d’accés à la recette dans le tableau. Une recette est un tableau associatif avec les clés nom et produits. Le clé nom donne le nom de la recette et la clé produits donne un tableau des fruits qui composent la recette.

    // recette Salade de fruits
    Array
    (
        [nom] => "Salade de fruits"
        [produits] => array(
          [0] => Pomme
          [1] => Banane
          [2] => Orange
        )
    )

Ecrire la fonction afficheFruit(nom) qui affiche les qualités nutritives d’un fruit dont le nom est donné en paramètre.

    • Le tableau associatif fruits n’est pas un paramètre de la fonction, il faut donc le déclarer comme une variable globale dans la fonction.
    • Si le nom de fruit n’est pas dans le tableau fruits ($fruits[$nom] === NULL, isset($fruits[$nom])), on l’indique à l’utilisateur.

Ecrire la fonction ajouterRecette(nom, lesFruits) qui ajoute une recette dans le tableau de recettes. Le paramètre lesFruits est un tableau de noms de fruits. Lors de la création de la recette, on vérifiera que le fruit est dans le tableau fruits. Si le produit n’existe pas, on affichera un message.

    • Le tableau associatif fruits n’est pas un paramètre de la fonction, il faut donc le déclarer comme une variable globale dans la fonction.
    • Le tableau associatif recettes n’est pas un paramètre de la fonction, il faut donc le déclarer comme une variable globale dans la fonction.
    • Pour la vérification de la présence de chaque fruit dans le tableau fruits, il faut mettre en place une boucle for. Si le nom de fruit n’est pas dans le tableau fruits ($fruits[$nom] === NULL, isset($fruits[$nom])), on l’indique à l’utilisateur et on arrête la création de la recette.

Ecrire la fonction valNutRecette(nom) qui affiche pour le nom de la recette donné en paramètre, le total de chacune des valeurs nutritionnelles (naïvement la somme de chacune des valeurs nutritionnelles pour l’ensemble des produits qui composent la recette).

    • Le tableau associatif fruits n’est pas un paramètre de la fonction, il faut donc le déclarer comme une variable globale dans la fonction.
    • Le tableau associatif recettes n’est pas un paramètre de la fonction, il faut donc le déclarer comme une variable globale dans la fonction.
    • Pour faire la somme par valeur nutritionnelle, on pourra définir un fruit virtuel (même structure) avec des valeurs nutritionnelles nulles au départ, puis il faut parcourir les fruits qui composent la recette à l’aide d’une boucle for et pour chaque fruit incrémenter ses valeurs nutritionnelles aux valeur du fruit virtuel.

1.5.2 Trier un tableau d’entiers

Nous allons placer, dans un tableau de taille \(n\), des entiers (compris entre 0 et 2000) obtenus par tirage aléatoire (fonction rand()), afficher le contenu du tableau (10 valeurs par ligne), puis trier les entiers en utilisant le tri à bulles.

  Entrée: tableau tab de taille n
    répéter
      échange <- faux
      pour i <- 0 vers n - 2 faire
        si tab[i] > tab[i + 1] alors
          echanger(tab[i], tab[i + 1])
          échange <- vrai
        fin
      fin
      n <- n - 1
    tant que échange == vrai

Écrire la fonction creeTableau(n) qui renvoie un tableau avec les entiers à trier d’une taille n donnée en argument de la fonction.

    • On utilise ici la fonction rand().
    • Une boucle for pour créer les n éléments.

Écrire la fonction triABulles(tab) le code de l’algorithme de tri à bulles

    • La fonction echanger(a, b) a été donnée en cours, pour illustrer l’appel de fonction avec passage de paramètres par référence.
    function swap(&$a, &$b) {
        $tmp = $a;
        $a = $b;
        $b = $tmp;
    }

Ecrire la fonction affiche(tab) qui affiche le tableau donné en paramètre.

Tester

1.5.3 Lecture d’un fichier texte (A faire si il vous reste du temps)

Dans cet exercice nous allons utiliser des données qui se trouvent dans le fichier data.txt que vous pouvez récupérer ici. Des indications sont proposées tout au long de l’énoncé pour arriver à la solution. Le format du fichier est donné dans le listing suivant, le séparateur de champ est le symbole “;” :

    Nom;Prenom;NuméroEtRue;CodePostal;Ville;Téléphone;AdresseMail;DateDeNaissance

Écrire la fonction tableauNoms($fichier) qui crée un tableau qui contient le nom des personnes du fichier de données, la variable $fichier contient le nom du fichier au format indiqué dans le listing qui précéde.

    • Pour cela il faut lire le fichier ligne par ligne (tant que l’on a encore une ligne à lire faire).
      • On utilisera la fonction file() qui stocke dans un tableau les lignes contenues dans le fichier donné en paramètre de la fonction. la fonction file() permet de lire un fichier texte composé de lignes (chaîne de caractères terminée par un le caractère ‘\n’). Les lignes sont rangées dans un tableau. Il suffit de parcourir le tableau pour traiter toutes les lignes du fichier.
    • Ensuite il faut isoler le champ dans la ligne qui contient le nom de la personne, c’est à dire le premier champ. Pour transformer une chaine de caractères (la ligne lue dans le fichier) en tableau de champs on utilisera la fonction explode($sep, $var). Une fois le tableau de champs à votre disposition, il sera facile de récupérer le premier.

Écrire la fonction cinqColonnesALaUne($tab) qui affiche sur 5 colonnes, le nom de chaque personne contenu dans le tableau de noms donné en paramètre.

On pourra utiliser la fonction sprintf() qui permet de formater une chaîne de caractères qui contient des paramètres.

Écrire la fonction explodePersonne($ligne) qui crée un tableau qui contient toutes les informations d’une personne stockée dans la ligne donnée en paramètre et qui respecte le format indiqué dans le listing précédent.

Écrire la fonction tabDesPersonnes($fichier) qui crée un tableau $personnes qui contient toutes les informations de toutes les personnes contenues dans le fichier donné en paramètre.

Ajouter une personne en début de tableau

Viens;Gaston;9, rue des Nations Unies;92210;SAINT-CLOUD;01.23.81.22.72;GastonViens@dayrep.com;30/07/1966

Ajouter une personne en 5ième position dans le tableau

Hughes;Roslyn;3, rue Pierre Motte;97180;SAINTE-ANNE;05.52.17.06.81;RoslynHughes@rhyta.com;21/06/1938

La fonction array_splice($tab,$offset, $number, $tabRemplace) est utilisée pour remplacer des éléments du tableau $tab par $number éléments du tableau $tabRemplace à partir de l’indice $offset. L’usage suivant

~~~{.php }
$a = ["a", "b", "c"];
array_splice($a,1,0,array("coucou"));
var_export($a); // affiche array ( 0 => 'a',1 => 'coucou',2 => 'b',3 => 'c',)
~~~

Écrire la fonction tabAssoPersonne($ligne) qui renvoie un tableau associatif avec comme clés les valeurs suivantes

nom, prenom, numRue, codePostal, ville, telephone, mail, ddn
 

avec les informations d’une personne stockée dans la ligne donnée en paramètre et qui respecte le format indiqué dans le listing prédédent.

array (
  'nom' => 'Viens',
  'prenom' => 'Gaston',
  'numRue' => '9, rue des Nations Unies',
  'codePostal' => '92210',
  'ville' => 'SAINT-CLOUD',
  'telephone' => '01.23.81.22.72',
  'mail' => 'GastonViens@dayrep.com',
  'ddn' => '30/07/1966',
)

Écrire la fonction tabAssoDesPersonnes($fichier) qui crée un tableau associatif $assoPersonnes qui à la clé nomPersonne qui correspond au nom d’une personne associe le tableau créé à l’aide de la fonction tabAssoPersonne().

array (
  'Asselin' => 
  array (
    'nom' => 'Asselin',
    'prenom' => 'Campbell',
    'numRue' => '80, boulevard Amiral Courbet',
    'codePostal' => '01100',
    'ville' => 'OYONNAX',
    'telephone' => '04.05.29.05.64',
    'mail' => 'CampbellAsselin@jourrapide.com',
    'ddn' => '30/12/1956',
  ), ... ,
  'Laframboise' => 
  array (
    'nom' => 'Laframboise',
    'prenom' => 'Roch',
    'numRue' => '47, rue Pierre Motte',
    'codePostal' => '88100',
    'ville' => 'SAINT-DIÉ',
    'telephone' => '03.86.91.63.07',
    'mail' => 'RochLaframboise@teleworm.us',
    'ddn' => '24/03/1948',
  ),
)

Écrire la fonction qui trie le tableau donné en paramètre par ordre alphabétique du nom des personnes

1.6 Indications supplémentaires

  • La commande suivante vous permet de récupérer la liste des noms des personnes dans une variable (dans l’exemple, la variable liste).

    liste=`awk -F";" '{print $1}' data.txt`
  • L’interpreteur PHP stocke dans le tableau $argv, la liste des paramètres fournis lors du lancement du script (voir cours de SE en première année). Si le script suivant est stocké dans le fichier arg.php

      #!/opt/local/bin/php -f
      <?php
        print_r($argv)

    alors l’exécution de la commande suivante

      php arg.php un deux trois

    affichera :

      Array
      (
          [0] => arg.php
          [1] => un
          [2] => deux
          [3] => trois
      )
  • La commande php tp1.php < data.txt permet de rediriger le contenu du fichier comme entrée standard du script tp1.php

 

IUT de Lens Département Informatique

2018