🐘 PHP#

../../_images/php.svg

Indication

Cette page à pour but de découvrir le langage PHP, sa librairie standard et quelques concepts de base.

Dynamiser le Web ?#

Le besoin initial est de permettre l’interaction avec les utilisateurs, l’accès à une base de données, de faciliter la maintenance et enfin de faciliter la gestion de contenu.

Web statique

Au tout début du World Wide Web (1991), les pages étaient statiques leur contenu était fixé une fois pour toute et ne variait pas. On se contentait de diffuser de l’information mais c’était une véritable révolution pour l’époque.

Les débuts du web dynamique

L’introduction des CGI (Common Gateway Interface) puis la généralisation des scripts exécutables sur le serveur dans différents langages de script (Perl, PHP, Python, Ruby, …) ont permis de faire varier le contenu des pages. On a alors parlé de Web dynamique, le contenu de la page varie en fonction de l’utilisateur, de ses préférences ou du sujet abordé.

Développer pour le Web, est-ce difficile ?

Il faut maîtriser de nombreuses technologies :

  • structure du document: XML, HTML, DOM
    • rendu: CSS (feuilles de style)

    • langage client: Javascript

    • langage serveur: PHP, Perl, Python, …

De plus ces technologies sont en constante évolution et de nouvelles technologies apparaissent tous les ans.

PHP: PHP Hypertext Processor#

Il s’agit d’un acronyme récursif (tout comme GNU). PHP est un langage de script (interprété) créé en 1994 par Rasmus Lerdorf dont la syntaxe est inspirée du C. Son développement est depuis repris par la société Zend.

Celui-ci se veut généraliste, simple d’utilisation et permet l’écriture de pages web dynamique. Les fichiers php possédent l’extension .php et la documentation se trouve sur http://php.net.

Comment ça marche PHP ?#

Reprenons l’architecture client serveur pour une page statique (HTML) :

https://www.plantuml.com/plantuml/svg/NP71Ji9048Rl-nGJk6qY9IHUEAWDiU953UsHX8pT0JPiftLt2l98-Xgyc5jgOkDnyy_t__lFF0H1BstbO2_Ip9GA9Jg2sUHMXOFb1ZrMy8xbOUVhbarPkzg3UEGG9M8PJ1dQOkiagrbUi29OHaefB2KI2sUxuJWejhGDii0e9t-ariEoADv6W05I5UqTbM9h3Z3ARFn8VWv2rLNESgLw7xYvWtGEA_feBzz2LuVvchL-UYmWqReBjKUCIWhZPpOMUKL6fRzSuT56qyx8if1dMlDcanpH9wVJAJ7aS8zdEjTj8BUTMDxMcqrFP_aSjBPiw7Eobyff3VT_QLaEuzUucnrrSV7LvtMLMa__G6Le0FRsVRtOxFBLn1qCcYrg4wyodKPk2APAFH2RU3_r0m==

Requête sur un site#

Pour une page dynamique (PHP) :

https://www.plantuml.com/plantuml/svg/RP71Qi9048Rl-nI3tW8r8lJYePXAguLInEOeX6aowk9cDjtT67ma-nfviKvCXHnwMdRd__wP-NVX0xfGbmOykJEvh3fMIlaS3S5iygZyINE53alumlnqSBRc8hV6EWWEsKk9E0nK1UsnDk7LSlZ0ac0jb5AO1o6MHdTY4GQTwmevmEYpwrexMAVfPWJe8L5YRoWFshA7qMRTFz_6wWtWuGcIEMpfksv_0jtG-OwZQFMIGipK-8ceewZhgiyeYWJ6Rrnev2qLAldZKuSwKDaPQWxac7QSPV4PNTmqJLoGmIDUw69hJsO_qRotMTRJOZ-NJKlaWkI4AFglgrnX_AuFn_1iQbBTzSwksYktLuVTahlEn21KU21rLybyZeALO0R5WeRU_IXz9996Uwqai44QIoleR3gLaOPaejI2k90V_mK=

Le client (navigateur) est incapable de lire du code PHP, mais il sait afficher du code HTML/CSS. PHP est interprété côté serveur :

https://www.plantuml.com/plantuml/svg/JP3BIiDG48RtynH3tHsmbeARBAGXg1LKGisoKAOvenwQp8ddKfz9NwClveG8xNAOx__cieg9GifzXv73aSDk-1oM0B6bZd4vluLuS39Ge1xtr1u-WizYMz_vW2cGH6snf0lAyZlbBZruIQ_KCwur1K1jqaJLkH5MCBdM3IG9Ps_Zs1ncI15Bc0YyliEom0r_vTDlKaVJrCLMZ7cyR_16-3lETKrZHgqxaX8bNZs9TIGRjb3-v-jr3LCnQTLu-Xcyn0jZvQtUkLWOivLATsR9XNPVdW4id_K0AnQhR_e3

On va donc demander à PHP de générer du HTML. On peut aussi utiliser PHP pour générer autre chose : du CSS, du JSON, … !

Quel lien avec JavaScript ?#

JavaScript est un langage de script, tout comme PHP; permet de modifier dynamiquement le contenu HTML/CSS; mais s’exécute généralement côté client et non côté serveur.

Pourquoi utiliser PHP alors ?

Les données sont centralisées sur le serveur (ex. forum) pour des raisons de sécurité certaines données doivent rester inaccessibles au client (mot de passe). Ou encoe de personnalisation chaque utilisateur peut avoir une page différente (horloge).

Il existe bien sûr d’autres concurrents: C# (ASP), Ruby, Python, Java (JSP), …

Syntaxe de base de PHP#

L’extension de fichier doit être {ttfamily .php}, les instructions doivent être placées entre les balises {ttfamily <?php} et {ttfamily ?>} et se terminent par {ttfamily ;}. PHP est sensible à la casse.

<?php
print('Hello World'); /* Affiche Hello World */
echo('Hello World'); // Affiche Hello World
?>

L’instruction {ttfamily echo} est un emph{mot-clé} PHP. Il permet d’écrire la chaîne de caractères qui suit dans la sortie (comparable à {ttfamily printf()} en $C$). Toutefois notre script ne génère pas du HTML (pas de doctype, aucune balise), il s’agit de texte brut (type mime: {ttfamily text/plain}).

Variables en PHP#

On déclare une variable à l’aide du caractère {ttfamily $} (dollar), à l’inverse du $C$ ou du $Pascal$, il n’y a pas besoin de préciser de type, l’interpréteur le détecte lorsque l’on affecte un contenu à la variable.

On peut également déclarer des constantes à l’aide de la fonction {ttfamily define}.

<?php
$bool = TRUE; // un booléen
$str = 'The Goonies'; // une chaîne de caractères
$int = 42; // un entier
$decimal = 3.14 // un nombre décimal;
define ("PI", 3.14159265358979323846264);

Chaînes de caractères en PHP#

Une chaîne de caractères peut être déclarée avec des quote simples ou doubles.

Indication

À l’intérieur des quote simples ('), les variables et caractères spéciaux (t, n, $, \, etc.) ne sont pas interprétés.

À l’intérieur des quote doubles ("), les variables et caractères spéciaux (t, n, $, \, etc.) sont interprétés.

<?php
$movie="The Goonies";
echo "Le dernier film vus est $movie.";
//ou
echo "Le dernier film vus est ${movie}.";
//affiche Le dernier film vus est The Goonies.
echo 'Le dernier film vus est $movie.';
//affiche Le dernier film vus est $movie.

Avertissement

La concaténation n’est pas recommandée pour obtenir un code propre, maintenable et sécurisé. Il convient d’utiliser le formatage de chaîne.

<?php
$movie = "The Goonies";
$output = sprintf("%s%s", $movie, PHP_EOL);

Indication

Beaucoup de fonctions existent pour la manipulation des strings http://www.php.net/manual/fr/ref.strings.php.

Affichage en PHP#

Tout affichage génère une sortie dans la sortie standard, les commandes de base qui peuvent être utilisées sont : {ttfamily echo, print, print_r, printf}.

<?php
print('Hello World'); /* Affiche Hello World */
echo('Hello World'); // Affiche Hello World
?>

Les tableaux (array) en PHP#

Les tableaux sont un type spécial de variable capable de stocker plus d’une valeur. Il existe deux types de tableaux en PHP :

  • Les tableaux numérotés (tableaux simples)

  • Les tableaux associatifs (tableaux clé-valeur)

Les tableaux numérotés#

Ils contiennent des éléments accessibles via leur indice. Les indices démarrent à 0 en PHP. Par exemple, votre tableau pourrait contenir :

clé

valeur

0

Ben Kenobi

1

Luke Skywalker

2

Han Solo

Il existe plusieurs syntaxes pour créer un tableau

<?php
$names = array('Ben', 'Luke', 'Han');
$names2 = ['Ben', 'Luke', 'Han']; //syntaxe courte

$names = array(); // ou []
$names[0] = 'Ben';
$names[1] = 'Luke';

$names = [];
$names[] = 'Han';
$names[] = 'Leia';
$names[] = 'Z6PO';

Pour accéder à un élément du tableau:

<?php
$names[0] = 'Ben';
$names[1] = 'Luke';

echo $names[1];
echo $names[0];

Les tableaux associatifs#

Ils permettent de donner des noms aux clés. Par exemple, votre tableau pourrait contenir :

clé

valeur

firstname

Ben

name

Kenobi

job

Jedi Master

Cette fois les notion de « clé » et de « valeur » prennent tout leur sens.

L’affectation se fait facilement:

<?php
$personnage = array (
   'firstname' => 'Ben',
   'name' => 'Kenobi'
);
//ou
$personnage = array(); // ou []
$personnage['firstname'] = 'Ben';
$personnage['name'] = 'Kenobi';

Pour accéder à un élément du tableau:

<?php
$personnage['firstname'] = 'Ben';
$personnage['name'] = 'Kenobi';
$personnage['job'] = 'Force Spirit';
echo $personnage['job'];

Conversion de type#

Le « cast » existe en PHP : il est possible de convertir une variable d’un type à un autre type. Il suffit de préciser le type après conversion entre parenthèses.

Par exemple :

<?php
$a = '5';
$b = ((int) $a) + 2;
echo $b;

Les conditions en PHP#

Elles permettent de définir des conditions lors de l’exécution de votre script PHP :

Symbole

Signification

==

Est équivalent à

!=

N’est pas équivalent à

> ou >=

Est supérieur, Est supérieur ou égal à

< ou <=

Est inférieur, Est inférieur ou égal à

<?php
$longueur_mdp = 6;
if ($longueur_mdp >= 8) // SI
   $save_mdp = true;
elseif ($longueur_mdp >= 6) // SINON SI
{
   $save_mdp = true;
   echo "Ce mot de passe n'est pas très sûr !\n";
}
else // SINON
{
   echo "Ce mot de passe est trop court !\n";
   $save_mdp = false;
}

Indication

Il est possible de combiner les conditions dans une même instruction :

<?php
if($condition1 && (!$condition2 || $condition3)){

}

Les boucles et opérateurs en PHP#

Il existe trois boucles en PHP: while, for et foreach.

Le while permet d’exécuter la même série d’instructions tant que la condition d’arrêt n’est pas vérifiée.

<?php
$nb_lines = 1;
while($nb_lines <= 10)
{
   echo "Line number $nb_lines";
   $nb_lines++;
}

Le for est semblable au while mais permet de regrouper les conditions initiales, d’arrêt et de l’incrémentation.

<?php
for($nb_lines=0; $nb_lines <= 10; $nb_lines++)
{
   echo "Line number $nb_lines";
}

Le foreach est un peu spécial, en effet les tableaux ne doivent pas être parcourus à l’aide d’une boucle for comme en C ou en Pascal. Les éléments intermédiaires pouvant être supprimés, la contiguïté des éléments n’est pas assurée. La bonne pratique est d’utiliser le foreach.

Parcours d’un tableau simple#
<?php
$prenoms = array('Luke', 'Ben', 'Han');
foreach($prenoms as $element)
{
   echo $element;
}
Parcours d’un tableau associatif#
<?php
$luke = array('name' => 'Luke', 'job' => 'Farmer');
foreach($luke as $key => $value)
{
   echo "$key: $value";
}

Indication

Pour afficher le contenu brut d’un tableau, utiliser la commande print_r ou var_dump. C’est utile pour le debug ou pour comprendre la structure d’un tableau.

Fonctions#

La librairie standard de PHP est très bien fournie en fonctions pour manipuler différentes choses.

Fonctions génériques#

isset($var)

vérifier si une variable existe

empty($var)

vérifier si une variable est vide

filter_var($var, FILTER_VALIDATE_EMAIL)

vérifier si une variable contient un email valide

explode(';', $var)

découper une chaine sur un caractére

file('filepath')

lire le contenu d’un fichier dans un tableau

file_get_contents('filepath')

lire le contenu d’un fichier dans une chaîne

Fonctions sur les tableaux#

count($arr)

nombre d’éléments du tableau

asort($arr)

trie les éléments du tableau

ksort($arr)

trie le tableau selon les clés

array_flip($arr)

transforme les clés en valeurs et les valeurs en clés

array_keys($arr)

renvoie les clés

array_values($arr)

renvoie les éléments

array_key_exists($key, $arr)

vérifie si la clé est présente dans le tableau

in_array($value,$arr)

vérifie si la valeur est présente dans le tableau

Indication

La doc php.net <php.net> est fourni en exemple et précision.

Définir une fonction#

On utilise le mot-clé function pour ce faire:

<?php
function maFonction($param1, $param2)
{
   return $valeur;
}
maFonction('1234', 5678);

Note

Les fonctions peuvent ne rien retourner, dans ce cas on omet l’instruction return.

Indication

Une bonne pratique consiste à définir vos fonctions dans des fichiers séparés, puis de les inclure dans vos pages via la fonction require_once.

<?php
//Permet d'intégrer le contenu de 'page.php'
include('page.php');
//Test pour empêcher une intégration multiple
require_once('page.php');

Interroger une base de données en PHP#

La connexion à la BDD est la première étape nécessaire, c’est aussi le processus d’authentification qui permet de s’assurer que seuls les utilisateurs autorisés peuvent accéder aux données et/ou les modifier. Pour ce faire les SGBD utilisent un vocabulaire spécifique :

  • l’hôte est l’adresse du serveur,

  • la base est le nom de la base de données,

  • user est l’identifiant de l’utilisateur,

  • password est le mot de passe de cet utilisateur.

PHP propose plusieurs fonctionnalités intégrées pour se connecter à une base de données. Les évolutions successives de PHP expliquent l’existence de ses extensions.

La librairie PDO constitue la concrétisation d’un effort d’unification entre les différents SGBD :

  • Générique (différents SGBD mais le même code)

  • Optimisée pour l’orienté objet

<?php
try {
   $db = new PDO('sqlite:bdd_file.sqlite3');

   $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (Exception $e)
{
   exit('Erreur : '. $e->getMessage());
}

Exécuter une requête SQL en PHP#

Suite à la connexion, il est possible d’accéder au contenu de la BDD en suivant ces étapes:

  1. On interroge une base de données grâce à une requête qui spécifie quelle(s) donnée(s) de quelle(s) tables on souhaite récupérer.

  2. Le SGBD se charge de filtrer et trier les données correspondantes à la requête et les collecte dans une structure de données exploitable en PHP (c’est-à-dire un tableau).

Note

Les requêtes sont interprétées par le SGBD, elles sont dont formulées dans le langage qu’il manipule, c’est-à-dire le SQL. Le langage SQL est dédié à l’écriture de requêtes. Sa syntaxe, sous forme de chaîne de caractères, permet de créer des requêtes complexes à partir de quelques mots-clés.

La lecture de données depuis une BDD s’exécute suivant ce protocole :

  1. Connexion à la BDD,

  2. Préparation de la requête,

  3. Interrogation de la BDD via une requête SQL,

  4. Récupération de la réponse complète,

  5. Lecture enregistrement par enregistrement,

  6. Fin de la lecture et libération de la ressource.

<?php
$bdd = connectDb(); //connexion à la BDD
$query = $bdd->prepare('...'); // requête SQL
$query->execute(...); // paramètres et exécution

while ($data = $query->fetch()) // lecture par ligne
{
... // traitement de l'enregistrement
} // fin des données

$query->closeCursor();

Dans la requête, si on veut injecter des paramètres, il faut le spécifier par le caractère anonyme ? ou un identifiant précédé par :.

La fonction execute() exécute la requête avec les paramètres fournis sous la forme d’un tableau simple (paramètres anonymes) ou associatif (paramètres identifiés). Il n’est pas nécessaire de préciser de paramètres si la requête SQL n’en comporte pas.

La fonction fetch() retourne un tableau associatif dont les clés correspondent aux champs sélectionnés par la requête. Lorsqu’il n’y a plus d’entrée, l’affectation dans le while retourne faux : on sort de la boucle.

La fonction closeCursor() permet de libérer la ressource lorsqu’on a fini les traitements sur les données retournées par le SGBD.

Avertissement

Une faille connue nommée « injection SQL » peut être exploitée lorsque l’on utilise des données entrées par l’utilisateur dans des requêtes SQL.

Pour s’en prémunir, il ne faut pas injecter les paramètres à la main avec des concaténations. À la place on les passera TOUJOURS via les fonctions prepare() et execute().

Requête sans paramètres#
<?php
$query = $db->prepare('SELECT * FROM table');
$query->execute();
Requête avec paramètres anonymes#
<?php
$query = $bdd->prepare('SELECT col1, col2 FROM table WHERE col1 = ? AND col4 <= ? ORDER BY col3');
$query->execute(array($x, $y));
Requête avec paramètres nommés#
$query = $bdd->prepare('SELECT col1, col2 FROM table WHERE col1 = :x AND col4 <= :y ORDER BY col3');
$query->execute(array('x' => $x, 'y' => $y));

Ecrire des données en SQL via PHP#

L’écriture de données dans une BDD se fait en suivant les étapes suivantes :

  1. Connexion à la BDD,

  2. Préparation de la requête,

  3. Exécution de la requête.

Trois actions sont possibles pour l’écriture : insertion, modification ou suppression d’un enregistrement.

Exemple générique#
<?php
$db = connectDb(); //connexion à la BDD
$query = $db->prepare('...'); // requête SQL
$query->execute(...); // paramètres et exécution

Gestion des exceptions#

Les exceptions sont rattrapables par une fonction dédiée (mécanisme similaire en Java et VB).

<?php
function exception_manager($exception) {
   //gestion des erreurs
   //affichage d'un message
   //redirection...
   //log système, mail administrateur
}
set_exception_handler('exception_manager');

Hello PHP !#

Note

PHP est un langage de script utilisé principalement dans le développement WEB. Il est bien sûr possible de réaliser uniquement des scripts console avec ce langage. Nous nous concentrerons sur cet aspect dans un premier temps.

Que peut faire PHP ?#

Note

PHP est principalement conçu pour servir de langage de script coté serveur, ce qui fait qu’il est capable de réaliser tout ce qu’un script CGI quelconque peut faire, comme collecter des données de formulaire, générer du contenu dynamique, ou gérer des cookies. Mais PHP peut en faire bien plus.

Il y a deux domaines différents où PHP peut s’illustrer.

  • Langage de script côté serveur. C’est l’utilisation la plus traditionnelle, et aussi le principal objet de PHP.

  • Langage de programmation en ligne de commande. Vous pouvez écrire des scripts PHP et l’exécuter en ligne de commande, sans l’aide du serveur web et d’un navigateur. Il vous suffit de disposer de l’exécutable PHP. Cette utilisation est idéale pour les scripts qui sont exécutés régulièrement (avec un cron sous Unix ou Linux), ou un gestionnaire de tâches (sous Windows). Ces scripts peuvent aussi être utilisés pour réaliser des opérations sur des fichiers texte.

Important

Les fichiers php sont de simples fichiers texte comportant l’extension .php.

Nos premiers fichiers PHP#

Hello PHP#

À faire

Créer un nouveau dossier dans votre répertoire de travail et placer le contenu suivant dans un fichier hello.php.

<?php
print('Hello World');

Pour exécuter notre script il suffit d’appeler la commande php suivie du nom du script à exécuter:

$ php hello.php
Hello World$

Note

Nous remarquons que le résultat n’est pas très propre. En effet la fonction print de PHP ne provoque pas automatiquement un retour à la ligne. Pour ce faire nous devrions ajouter le retour chariot. Fort heureusement PHP nous fournit une constante PHP_EOL qui fournit le retour chariot.

Ainsi nous pouvons modifier notre code pour obtenir un retour à la ligne:

<?php
printf('%s%s', 'Hello World', PHP_EOL);

Exécuter à nouveau votre script, que constatez-vous ?

Demander des informations à l’utilisateur#

Afficher Hello World c’est bien mais ne serait-ce pas mieux de demander à l’utilisateur son prénom et de lui souhaiter le bonjour ?

Indication

PHP intégre une fonction qui permet de lire une chaîne de caractères depuis le terminal, il s’agit de la fonction readline

<?php
print("What's your name ? ");
$name = readline();
print($name);

À faire

À vous de modifier le script précédent pour afficher  » Hello <name>! Have a nice day !  » où <name> est la valeur passée par l’utilisateur dans le terminal.

Conditions#

À faire

En reprenant le script hello.php ajouter les conditions suivantes une fois le nom saisi:

  • Si la valeur est égale à Luke afficher  » May The Force Be With You « 

  • Sinon si la valeur est égale à Ben afficher  » I’m old.. « 

  • Sinon afficer  » Hello <name>! Have a nice day ! « 

Boucles#

À faire

Dans un nouveau script, expérimenter les structures itératives:

  • Créer une boucle déterministe pour afficher de 0 à 10

  • Créer une boucle indéterministe pour réaliser la même opération

Ajouter à votre script la possibilité de saisir pour l’utilisateur les bornes de début et de fin via la fonction readline. Attention readline renvoie un string qu’il convient de convertir/caster en int, de plus vérifier que la borne max est supérieure à la borne min.

Manipulation de chaînes de caractères#

À faire

Créer un script qui:

  • Permets la saisie d’une adresse email

  • Affiche la longueur de celle-ci

  • Sépare l’utilisateur et le nom de domaine dans deux variables, par exemple: samy.delahaye@ugaritic.fr -> samy.delahaye et ugaritic.fr

  • Affiche la valeur de ces deux variables

Indication

<?php
strlen($str) # nombre de caractères contenus dans $str
explode(';', $str) # Coupe la chaine de caractère sur le delimiter ; et retourne les sous-chaînes dans un tableau

Les tableaux en PHP#

Parcours de tableau#

Le but de cet exercice est de vous faire manipuler les tableaux en langage PHP.

Pour ce faire nous allons créer un nouveau dossier (tp2 par exemple) dans notre répertoire de travail.

Créer deux fichiers: index.php et data.php.

Astuce

Voici le contenu du fichier data.php:

<?php
$names = array(
   'Luke',
   'Han',
   'Leia',
   'Ben',
);

$arr_names = array();
$arr_names[0] = 'Ben';
$arr_names[1] = 'Luke';
$arr_names[2] = 'Han';
$arr_names['Organa'] = 'Leia';

$luke = array(
   'nom' => 'Skywalker',
   'prenom' => 'Luke',
   'job' => 'unknow',
);
$ben = array(
   'nom' => 'Kenobi',
   'prenom' => 'Ben',
   'job' => 'Old man euh.. old jedi master',
);
$han = array(
   'nom' => 'Solo',
   'prenom' => 'Han',
   'job' => 'smuggler',
);

$chars = array(
   $luke,
   $ben,
   $han,
);

À faire

Créer un script php qui:

  • Inclut le fichier data.php (pour rappel utilisation de la fonction require_once)

  • Parcours du premier tableau avec une boucle for

  • Parcours du deuxième tableau avec un foreach en affichant le couple clé/valeur

  • Parcours du troisième tableau en affichant les informations de chaque personnage sous la forme d’une carte d’identité

Parcours d’un fichier#

Soit le fichier dwarfs.txt suivant:

Balin
Bifur
Bofur
Bombur
Dori
Dwalin
Fíli
Glóin
Kíli
Nori
Óin
Ori
Thorin

Première itération#

À faire

À partir du fichier précédent crée un script php permettant de lire le fichier et d’afficher les lignes une à une précédées du numéro de ligne.

Astuce

La fonction file($filename) retourne un tableau contenant chaque ligne du fichier $filename(une ligne est un ensemble de caractères terminés par r, n ou les deux).

Deuxième itération#

À faire

En vous basant sur la page wikipedia Thorin et Cie, ajouter une description à la suite de chaque nain (sans retour à la ligne) en séparant la description et le nom du nain avec un caractère (;, ,, etc.).

En reprenant le script précédent:

  • Afficher les noms des nains sous la forme d’un menu

  • Tant que l’utilisateur saisit un entier, afficher le nom et la description du nain correspondant à l’entrée dans le menu

  • Si l’utilisateur tape q, exit ou quit on quitte le programme

  • Si l’utilisateur saisit un entier invalide on affiche un message d’erreur mais l’exécution se poursuit

  • Si l’utilisateur saisit autre chose qu’un entier, q, exit ou quit on affiche un message d’erreur mais l’exécution se poursuit

Indication

<?php
array_key_exists(1, $arr) # Check if given key (1) exists in $arr

Les fonctions en PHP#

Note

Une fonction est une série d’instructions qui effectue des actions et qui retourne une valeur.

Syntaxe des fonctions#

Appeler une fonction

En PHP, on appelle une fonction par son nom:

<?php
sayHello();

La fonction sayHello n’existe pas pour le moment dans la librairie PHP, nous la créerons plus tard dans la suite de ce tp.

Lors de cet appel nous ne passons aucune variable à notre fonction, voici donc la syntaxe pour lui passer une variable:

<?php
sayHello('Ben Kenobi');

Certaines fonctions peuvent fonctionner sans paramètres, dans le cas présent nous voulons que notre fonction accepte ou non un paramètre en entrée.

Pour récupérer la valeur en retour d’une fonction, la syntaxe est la suivante:

<?php
$str = sayHello('Ben Kenobi');

Les fonctions existantes#

PHP propose des centaines de fonctions prêtes à l’emploi. La documentation PHP les répertorie toutes, classées par catégories.

Un petit aperçu des fonctions qui existent :

  • Rechercher et de remplacer des mots dans une variable

  • Envoyer un mail

  • Crypte des mots de passe

  • Manipuler des dates, heures, ..

  • Et bien plus

Manipulation de fonctions PHP#

À faire

Créer un script php qui demande à l’utilisateur son prénom puis:

  • Afficher la longueur d’une chaîne via strlen

  • Rechercher et remplacer un caractère ou une chaine dans une chaine puis afficher le résultat via str_replace

  • Mélanger les lettres avec str_shuffle

  • Mettre en capitales puis en minuscules via respectivement strtoupper et strtolower

Création de nos propres fonctions#

Créer un nouveau script hello.php

Corps de la fonction sayHello#
<?php
function sayHello($name){
    return "Hello  $name";
}

À faire

  • Cette fonction sera écrite dans un fichier functions.php qui sera ensuite inclut dans notre script hello.

  • Appeller à plusieurs reprises la fonction sayHello avec des valeurs différentes puis afficher le résultat retourné.

  • Appeller cette fonction sans paramètres, que se passe t’il ?

Paramètre par défaut#

Il est possible de passer un paramètre par défaut en PHP de cette manière:

<?php
function sayHello($name=null)

À faire

Par défaut le nom sera à null, modifier donc le corps de la fonction pour gérer le cas ou $name est null et afficher Hello John Doe

Des fonctions utilitaires pour nos scripts PHP#

Nous allons créer une suite de fonctions utilitaires pour nos script php, nous appellerons le fichier contenant ces fonctions cli.php.

À faire

Dans le fichier cli.php créer les fonctions suivantes:

  • write($str) affiche la chaine de caractère sans retour à la ligne

  • writeline($str) affiche la chaine de caractère avec un retour à la ligne

  • readint() récupére un entier depuis le terminal

Astuce

Pensez à utiliser la constante PHP_EOL et la fonction sprintf cela vous sera utile.

Des fonctions sur des tableaux#

À faire

En reprenant le fichier data.php, créer les fonctions suivantes:

  • Affichage des valeurs d’un tableau

  • Affichage des clés/valeurs d’un tableau

  • Recherche d’un élèment à partir de sa clé dans un tableau (si l’élèment n’existe pas on retourne null).

Astuce

Pensez à utiliser les fonctions que nous avons créer plus tôt.

Des fonctions plus complexes#

À faire

En reprenant le fichier dwarfs.txt, créer les fonctions suivantes:

  • Lecture et affichage des lignes (avec leurs numéros) d’un fichier

  • Lecture d’un fichier et stockage des différentes valeurs (séparés par un caractére) dans un tableau, le caractére sera passé en paramètre en plus du chemin du fichier

Astuce

Pensez à utiliser les fonctions que nous avons créer plus tôt.

SQL, SQLite & PHP#

Keyforge#

Note

KeyForge est un JCE à Deck unique créé par Richard Garfield (le papa de Magic!) et publié par Fantasy Flight Games.

Dans ce jeu, les joueurs jouent le rôle d’Archontes dans le monde du Creuset. Le premier joueur à collecter suffisamment d“« Æmber » pour forger trois clés est déclaré vainqueur.

Le jeu dans sa version de lancement comporte 371 cartes différentes.

https://www.plantuml.com/plantuml/svg/fLBBQiD03BphAuIFXPYsq4jEWKB9gQVUYxmhsoBxC5gPD8JyUvs4FaoJIwhJxingHiDgLOpKnXYWE0gCZ_KJb8saWPGYDkGsdUOnUPT3LZIbL2QAa_rwvRcbCTXBJlPAaN4zTK7Wrj0ogdIzeHTbPv8JK0Xv-nxbGr8702vGAVXCwd4FEDM-5Gx-WEANACcuOvtXQN9OOZ4zzi-8CLx4bLHiTv4YZWthPPyXRwzHf35Vene9OiBbs-_mbV5jD_0j6Ny4bCJ-fR3EOxbr1ZZzKNLNuMA1rKDr5lk37bFEmVkwdawduG5wyOoHhS--d2zEr0K6M77oqnf-0W==

Diagramme UML de la base de données keyforge#

Lecture de la base de données#

Lecture simple#

À faire

En utilisant la base de données SQLite keyforge.sqlite3.

  • Créer une fichier .php contenant la fonction de connexion à la BDD de Keyforge,

  • Récupérer la liste des cartes avec la requête adéquate (uniquement les données de la table Cards pour le moment),

  • Récupérer le nombre de cartes présent en base de données,

  • Afficher les résultats avec une « belle » présentation.

Rappel Syntaxe SQL

/* Sélection */
SELECT [ * / columns_name ] FROM tablename;

/* Compter */
SELECT COUNT(column_name) FROM table_name;

/* Trier */
SELECT column_name(s) FROM table_name ORDER BY column_name(s) ASC|DESC

Rappel Syntaxe PHP

Gestion des exceptions#
<?php

//Connexion à la base de données avec gestion des exceptions
try {
   $db = new PDO('sqlite:database_filepath');
} catch(Exception $e){
   die('Erreur : ' . $e->getMessage());
}

//Execution d'une requête
$query = $db->prepare("SELECT * FROM jeux");
$query->execute();
while ($donnees = $query->fetch()){
   echo($donnees['nom'] . $donnees['description'];
}
$query->closeCursor();

Jointure(s)#

À faire

Récupérer la liste des cartes en effectuant une jointure avec la table Type, House puis avec la table Trait et afficher les informations complémentaires.

Écriture dans la base de données#

À faire

Toujours en utilisant la base de données SQLite précédente.

  • Créez une fonction qui permet l’ajout d’une carte,

  • Les données envoyées doivent être insérées dans la table cards de votre BDD,

  • Ajoutez les tests nécessaires au traitement des données entrée,

  • Si l’utilisateur entre un nom de cartes déja existant dans la table, appliquer une requête de modification avec les nouvelles données (empêchez la création de doublons).

Rappel Syntaxe SQL

Insertion#
/* INSERTION */
INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, value2, value3,...);
/* MAJ */
UPDATE table_name SET column1=value, column2=value2,... WHERE some_column=some_value;

Rappel Syntaxe PHP

Un exemple d’exécution d’une requête préparée avec l’utilisation de variables#
<?php
//On suppose que les variables $nom, $type, $desc et $note ont été initialisées

$query = $db->prepare('INSERT INTO jeux(nom, type, description,note) VALUES(:nom, :types, :descr, :note)');

$query->execute(array(
   'nom' => $nom,
   'types' => $type,
   'descr' => $desc,
   'note' => $note,
));

PHP en mode serveur#

Note

Nous avons découvert PHP, sa syntaxe et ses structures de données. Avant cela nous avions découvert le couple HTML/CSS qui nous permet de créer des pages statiques.

Avertissement

Cette méthode de développement  » historique  » n’est de nos jours plus utilisée. Il s’agit une mauvaise pratique de développement qui conduit à la création de site web souvent buguée, peu voir pas maintenable et surtout donc le code source est un gloubi-boulga de code PHP, SQL et HTML.

Cette (mauvaise) façon de faire ne vous est présenté que pour découvrir l’utilisation du serveur de développement intégré à PHP et pour vous sensibiliser à d’anciennes pratiques de développement.

Le serveur de développement embarqué#

Note

PHP intégre nativement un serveur de développement (depuis la version 5) qui permet facilement et rapidement de monter un serveur de développement pour tester son site web lors de la phase de développement.

$ php -S 127.0.0.1:5000

La commande précédente lance un serveur de développement qui aura pour racine le dossier courant.

Premier exemple de serveur PHP#

À faire

  • Créer un fichier index.html et un fichier hello.html dans un dossier

  • Depuis ce dossier lancer le serveur de développement de PHP

  • Rendez-vous sur http://127.0.0.1:5000, que constatez-vous ?

  • Renommer index.html en accueil.html,

  • Rendez-vous sur http://127.0.0.1:5000, que constatez-vous ?

Indication

Voici le contenu du fichier index.html:

<h1>It works!</h1>
<a href="hello.html">Go to hello page</a>

et le contenu du fichier hello.html

<img src="https://www.ugaritic.fr/_static/img/hellothere.gif" alt="Hello there!">
<a href="index.html">Go to index page</a>

Deuxième exemple avec un peu de code#

À faire

  • Renommer le fichier accueil.html en index.php

  • Rendez-vous sur http://127.0.0.1:5000, que constatez-vous ?

  • Modifier le fichier index.php avec le contenu suivant:

<h1>It works!</h1>
<p><?php
   printf("Today is %s", date("Y/m/d"));
?><p>
<a href="hello.html">Go to hello page</a>

Quelques données#

À faire

Dans un fichier data.php créez un tableau arr_articles contenant plusieurs articles:

Voici le début du tableau

<?php
   $arr_articles = array();
   $arr_articles[0] = array(
      'title' => 'Useless title',
      'description' => 'Description ..',
      'author' => 'John Doe',
   );

Dans le fichier articles.php:

  • Inclure le fichier data.php via l’instruction include

  • Générer l’ensemble d’articles du tableau via les balises HTML5 vu précédemment

Indication

Il peut vous être utile de connaître la syntaxe alternative des structures de contrôle en PHP. Le principe est de remplacer l’accolade d’ouverture par deux points (:) et l’accolade de fermeture par endif; , endwhile; , endfor; , endforeach; , ou endswitch; .

Par exemple:

<ul>
   <?php for($i=0; $i<10; $i++): ?>
      <li><?php echo $i; ?></li>
   <?php endfor; ?>
</ul>

<?php foreach($persos as $perso): ?>
   <h2><?php printf("Name: %s", $perso['name']); ?></h2>
<?php endforeach; ?>

L’intéret de cette syntaxe est de rendre votre mélange de PHP et d’HTML un peu plus lisible.

Rappel HTML5

Squelette de base HTML5#
<!DOCTYPE html>
<html>
   <head>
      <title>..</title>
      <meta charset='utf-8' />
   </head>
   <body>
      <header>
      </header>
      <main>
      </main>
      <footer>
      </footer>
   </body>
</html>
Squelette de base d’un article en HTML5#
<article>
   <h3>..</h3>
   <img src='..' alt='..' />
   <p>..</p>
   <a href='..' title='..'>Lire la suite</a>
</article>

PHP & les données d’URL#

Introduction aux données d’URL#

Prenons en exemple l’url suivante:

http://www.google.fr/search?q=star wars

Note

Dans cet exemple, les informations après le point d’interrogation sont des données que l’on fait transiter d’une page à une autre.

Des paramètres dans l’URL#

Nous possédons le nom de domaine ugariticnews.com et nous souhaitons accéder à la page hello.php.

L’url sera donc ugariticnews.com/hello.php, rien de bien nouveau jusque là ce que nous voulons faire c’est passer des paramètres à notre page hello.php.

ugariticnews.com/hello.php?name=Kenobi&firstname=Ben

Note

Après le point d’interrogation, ce sont des paramètres que l’on envoie à la page PHP. Celle-ci peut récupérer ces informations dans des variables. Le point d’interrogation sépare le nom de la page PHP des paramètres. Ensuite, ces derniers s’enchaînent selon la forme nom=valeur et sont séparés les uns des autres par le symbole &.

Récupération des paramètres d’URL#

Indication

Nous allons modifer notre page hello.php pour prendre en compte les paramètres d’URL. PHP va automatiquement créer un array $_GET . Il s’agit d’un array associatif dont les clés correspondent aux noms des paramètres envoyés via l’URL.

<p>Hello <?php echo $_GET['firstname']; ?> <?php echo echo $_GET['name']; ?> !</p>

À faire

  • Accéder à /hello.php?name=Kenobi&firstname=Ben

  • Dans la page index.php créer des liens pour accéder à la page hello.php sous différents nom/prénom

  • Retirer un des paramètre (par exemple name) de l’url que se passe t’il ?

  • Corriger cela en testant l’existance d’un index dans $_GET grâce à la fonction isset

  • Rajouter un paramètre d’url nommé repeat qui permet de répéter la phrases selon sa valeur (pensez à caster la valeur de repeat)

  • Tester votre script avec une valeur pour repeat de l’ordre de 199999999

  • Corriger cela en ajoutant un contrôle sur la valeur de repeat

PHP & les formulaires#

Introduction au formulaires avec PHP#

Note

Les formulaires HTML sont la base de l’intéractivité sur les sites web moderne. De ce fait HTML & PHP sont intiment liés.

Formulaire HTML#

<form method='POST' action=''>
</form>

Nos champs seront insérés entre les balises form mais avant de poursuivre la conception de notre formulaire revenons sur l’élément form. Celui-ci posséde deux attributs à connaitre: le verbe method et l’url cible action.

La méthode#

Note

Il existe deux (en réalité plus) méthodes pour envoyer les données du formulaire:

  • GET : les données transiteront par l’URL comme on l’a appris précédemment.

  • POST : les données ne transiteront pas par l’URL. Cette méthode permet d’envoyer autant de données que l’on veut, ce qui fait qu’on la privilégie le plus souvent. Néanmoins, les données ne sont pas plus sécurisées qu’avec la méthode GET et il faudra toujours vérifier si tous les paramètres sont bien présents et valides. On ne doit pas plus faire confiance aux formulaires qu’aux URL.

L’url cible#

L’attribut action sert à définir la page appelée par le formulaire. C’est cette page qui recevra les données du formulaire et qui sera chargée de les traiter.

Les champs de formulaire#

Dans un formulaire on peut insérer de nombreux champs de types différents:

  • Des champs texte

  • Des champs de mot de passe

  • Des zones de texte

  • Et bien d’autres

Indication

Voici un simple formulaire pour envoyer notre nom

<form action="" method="POST">
   <input type="text" name="name" />
   <input type="submit" value="Send" />
</form>

Notez la présence d’un champ de type submit qui permet d’afficher un bouton d’envoi du formulaire.

Traitement côté serveur#

Maintenant que notre formulaire côté HTML est prêt il est temps d’implémenter la gestion de celui-ci côté serveur.

Note

Comme pour les variables de type GET, PHP créé automatiquement un array de valeur pour les variables POST à savoir $_POST, toutefois celui-ci n’est créé que si une requête post (un envoi de formulaire) est parvenue au serveur.

Pour ce faire il faut dans un premier temps vérifier que l’array $_POST existe:

<?php
   if isset($_POST){
   }

Une fois cela fait nous pouvons récupérer les variables depuis notre formulaire et les afficher, par exemple:

<?php
   if isset($_POST){
      if isset($_POST['name']){
            echo $_POST['name'];
      }
   }

Mise en oeuvre#

À faire

  • Réaliser le formulaire précédent avec le traitement associé pour afficher la valeur transmise par l’utilisateur

  • Manipuler des champs de formulaire de type texte, mot de passe, liste déroulantes et zone de texte afin de simuler un formulaire d’inscription

Un exemple plus complexe: Les impots#

On souhaite faire une page simple permettant à un utilisateur de calculer le montant de son impôt.

Calcul du nombre de part

parts = nbEnfants/2+1 (pas marié)
parts = nbEnfants/2+2 (marié)

Calcul du revenu imposable (S est le salaire)

R = 0.72 * S

Calcul du quotient familial

Q = R / parts

Le montant de l’impot est alors remultiplié par le nombre de parts nbParts.

Les tranches du barème sont les suivantes, appliquée au montant du quotient familial Q :

0 à 5614

5615 à 11198

11199 à 24872

24873 à 66679

66680 et plus

0%

5.5%

14%

30%

40%

À faire

  • Créer un formulaire permettant à l’utilisateur de rentrer ses informations

  • Calculer le montant prévisionnel de son impôt

  • Afficher le résultat