Sommaire du site
Présentation
Comment apprendre
L'équipement
La page web
Styles et CSS
HTML, structure de la page
HTML, éléments du corps
Le langage JavaScript
JavaScript, objets "core"
JavaScript, DOM, les bases
JavaScript, DOM, node
JavaScript, compléments
Le langage PHP, les bases
PHP, fonctions utiles
PHP pour le web
PHP, compléments
SQL, introduction
MySQL et PHP pour le web
MySQL, plus loin...
Applications AJAX
Annexes utiles
Fichier .htaccess
Sécurité des sites web
Conception d'un site web
Référencement,
syndication
Page mise à jour le : 12-08-2015
Une des applications les plus fréquentes de PHP est la gestion des formulaires web que soumet l'utilisateur.
Soyez prudents pour l'utilisation des données issues de formulaires car il se peut que des utilisateurs "indélicats" vous envoient du JavaScript ou des instructions de manipulation de bases de données.
La récupération des informations de formulaire se fait depuis les trois tableaux prédéfinis :
$_POST si l'attribut 'method'' du formulaire était 'post' ;
$_GET si l'attribut 'method'' du formulaire était 'get' ;
$_FILES si le formulaire transmet des fichiers.
La méthode 'get' ne présente pas un grand intérêt pour les formulaires. Car elle transmet les informations avec l'adresse de la page (URL). Ces informations sont limités en taille.
En revanche, il est parfois intéressant de transmettre des informations comme données complémentaires d'URL (QUERY_STRING ou chaîne de requête) depuis un lien. Dans ce cas elles seront récupérées comme si elles provenaient d'un formulaire dans le tableau '$_GET'.
Ce sont des tableaux associatifs ils sont indexés selon le nom des champs (attribut 'name') dans le cas des formulaires ou par les identifiants dans le cas de données complémentaires de l'URL.
Une démonstration sera probablement plus claire que de laborieuses explications :
formulaire avec méthode 'post' (nouvelle fenêtre
ou onglet).
Pour que la liste à choix multiples puisse être traitée correctement par le PHP, il faut que l'attribut 'name' de l'élément 'select' soit défini sous forme de tableau.
On remarque que les cases non cochées ne sont pas dans le tableau '$_POST', il en est de même pour les boutons de validation non activés. Le tableau issu de la liste à choix multiples ne contient que les éléments sélectionnés, si aucun n'est sélectionné ce tableau ne se trouve pas dans '$_POST'.
Le tableau '$_GET' se gère de la même façon que '$_POST'.
Cependant certains caractères de la chaîne de requête (QUERY_STRING) sont codés de façon particulière dans l'URL
. Le décodage est implicite et le tableau '$_GET' contient des informations correctes.
Démonstration du formulaire avec méthode 'get' (nouvelle fenêtre ou onglet).
L'utilisation de '$_GET' depuis l'URL est très proche de ce que l'on vient de voir. Si l'URL est :
...ma_page.php?nom=machin&age=25
On obtiendra le tableau '$_GET" :
[nom]=> machin
[age]=> 25
En savoir plus sur les tableaux '$_POST' et '$_GET' :
http://www.php.net/manual/fr/language.variables.external.php
Ce tableau existe quand le formulaire dispose d'au moins un champ où l'attribut 'type" est égal à 'file'. Donc quand le formulaire transmet un fichier.
Pour que la transmission du fichier se fasse il est nécessaire de placer dans l'élément 'form" l'attribut : 'enctype="multipart/form-data" ' et que la méthode soit 'post'.
A l'envoi chaque fichier sera transmis au serveur qui le place dans un répertoire temporaire.
La page d'exploitation du formulaire recevra un tableau associatif '$_FILES' dont chaque composant est un tableau associatif indicé par le nom des champs de type 'file' du formulaire. Il y en a donc au moins un car chacun caractérise un fichier transmis.
Chacun de ces tableaux a cinq composantes :
Index | Contenu |
name | nom du fichier tel qu'il est sur la machine de l'utilisateur |
type | type MIME du fichier transmis |
tmp_name | chemin complet d'accès au fichier placé sur le serveur |
error | code d'erreur : 0 indique que tout s'est bien passé |
size | taille du fichier en octets sur le serveur |
* Il est souhaitable de placer dans le formulaire un champ caché de nom 'MAX_FILE_SIZE' et ayant pour valeur la taille maximale des fichiers à transmettre (en octets) :
Dans ce cas si le fichier dépasse cette taille il n'est pas envoyé (on évite de perdre du temps de transfert) et le code 'error' vaut 2.(constante PHP 'UPLOAD_ERR_FORM_SIZE').
Cependant comme il n'est pas certain que tous les navigateurs gèrent ce champ, il est utile de vérifier aussi la taille du fichier transmis.
* Sur certains postes utilisateur (notamment Windows), le type MIME du fichier transmis est basé sur son extension. Celle-ci peut être incorrecte. Il est prudent de faire une vérification complémentaire du type de fichier.
Comme le fichier a été transmis dans un répertoire temporaire du serveur et qu'il y a un nom arbitraire, il est nécessaire de le placer dans un répertoire adapté avec un nom correct. Pour cela on peut utiliser une des fonctions du système de fichiers :
copy (source, destination);
ou
rename(ancien, nouveau);
formulaire d'envoi de fichiers (nouvelle fenêtre ou onglet).
En savoir plus sur le tableau '$_FILES' :
http://www.php.net/manual/fr/features.file-upload.post-method.php
Les textes envoyés par les formulaires peuvent poser des problèmes d'exploitation s'ils contiennent des caractères tels que les apostrophes, guillemets ou caractères spéciaux de l'HTML ('<').
La neutralisation des guillemets et apostrophes est importante si le texte doit être entré dans une base de données car les ordres du système de gestion utilise ces caractères comme délimiteurs. On a aussi le problème si ces textes doivent être insérés dans du code HTML.
La fonction qui neutralise ces caractères est :
addslashes(texte); elle renvoie 'texte' avec les apostrophes, guillemets et
anti-slashs échappés.
et :
stripslashes(texte); qui réalise la fonction inverse.
Malheureusement ce n'est pas si simple. En effet, certaines configurations de serveur réalisent implicitement la
fonction 'addsclashes' lors de la transmission des données de formulaire. Il ne faut donc pas réaliser cette
action deux fois. Pour le savoir, on utilise la fonction :
get_magic_quotes_gpc(); (sans paramètre) elle renvoie 'TRUE' si la neutralisation
est active.
Une solution plus simple consiste à tester sur son serveur et à construire le code adapté. Mais dans ce cas vos fichiers ne seront plus portables.
Voici une discussion intéressante sur ce sujet :
http://www.php.net/manual/fr/security.magicquotes.php
Si le texte reçu doit être mis dans une page HTML, il faut aussi se protéger aussi des caractères tels que '<', '&', ...
htmlentities(texte, ENT_QUOTES); va réaliser la conversion du paramètre 'texte'.
Cette fonction neutralise aussi les guillemets et apostrophes. Donc si les données viennent d'un formulaire il faut savoir si ces caractères n'ont pas déjà été traités.
Un cookie (ou témoin) est une information enregistrée sur la machine de l'utilisateur. Elle a un nom et une valeur. Le cookie est associé à un domaine (Internet) et a une date de péremption au delà de laquelle le cookie est effacé du poste.
Les utilisateurs peuvent configurer leur navigateur afin qu'il n'accepte pas les cookies ou seulement certains. Les utilisateurs peuvent aussi effacer les cookies.
Le cookie est un élément important si l'on souhaite que des informations soient conservées lorsque l'utilisateur navigue sur les pages d'un site (par exemple pour conserver ses droits d'accès). Pour cela un mécanisme plus perfectionné est mis en place, celui de sessions.
Vu du développeur une session correspond à un tableau associatif $_SESSION dans lequel il est possible de stocker des informations qui seront accessibles depuis les différentes pages du site.
Du point de vue du système, les informations de session sont dans un fichier situé sur le serveur et associé à l'utilisateur connecté au site. Ce fichier a un nom qui 'identifie la session. Il s'agit donc de faire en sorte que l'identifiant de session soit accessible sur toutes les pages du site et qu'il corresponde bien à l'utilisateur connecté.
Pour cela le mécanisme des cookies est intéressant. Un cookie placé sur le poste de l'utilisateur contient l'identifiant de session. Ce cookie a une date d'expiration nulle ce qui fait qu'il sera automatiquement supprimé si l'utilisateur ferme son navigateur. Cette méthode est simple et efficace elle a toutefois un inconvénient car le monde n'accepte pas les cookies !
Donc une autre possibilité existe : passer l'identifiant de session dans l'adresse en complément de l'URL. C'est un peu plus lourd à gérer.
session_start(); cette fonction sans paramètre crée une nouvelle session ou ouvre celle existante. Elle doit être appelée avant tout accès aux variables de session (le tableau $_SESSION n'existe pas avant l'appel de cette fonction).
Si l'on souhaite utiliser le mécanisme des cookies cette fonction doit être appelée avant toute sortie d'information.
Cette fonction ne doit être appelée qu'une fois par page.
session_id(); utilisée sans paramètre, cette fonction renvoie l'identifiant de session actuel.
session_id(id); remplace l'identifiant de session par celui transmis en paramètre. Cela doit être fait
avant l'appel de 'session_start()'.
SID S'il s'agit de sessions sans cookies, cette constante, définie après l'ouverture de session, contient la chaîne complète
d'identification de session à transmettre dans l'URL. Dans ce cas de sessions avec cookies, elle contient la
chaîne vide.
Attention, même si les cookies sont admis mais que l'on utilise la méthode "sans cookies", SID contient une
information valide.
Exemple 1, session par cookies (PHP en rouge).
Exemple 2, session sans cookie (PHP en rouge, les ajouts sont soulignés).
On voit que cette méthode est un peu plus lourde que la précédente. Par ailleurs il n'existe pas de méthode simple pour savoir si les cookies sont acceptés ou non.
La fonction "htmlspecialchars()" neutralise les éventuels caractères spéciaux HTMLen cas d'attaque du site.
Si la configuration du PHP a défini l'option 'session.use_trans_sid', l'identifiant de session (SID) sera ajouté automatiquement aux URL relatives.
Si vous destinez votre site à un large public et que des informations doivent être conservées durant la
navigation (type "panier de courses"), la méthode sans cookies est indispensable.
Par contre, si les informations à conserver ne concernent que quelques internautes (utilisateurs privilégiés par
exemple) la méthode avec cookies peut convenir dans la mesure où ces utilisateurs sont prévenus de cette
nécessité.
Paradoxe
Certains internautes désactivent les cookies dans un but de protection de la vie privée.
Malheureusement, les attaques de sites par vol de session sont plus faciles à réaliser lorsque l'identifiant de
session est placé dans l'URL.
On a vu que l'on pouvait conserver des informations avec la technique des sessions. Cependant ces informations sont perdues si l'internaute quitte son navigateur. Dans certains cas on souhaite les garder plus longtemps, par exemple pour enregistrer des préférences.
Dans ce cas il faut gérer les cookies.
setcookie(nom, valeur, expire); pose un cookie nommé 'nom' avec pour contenu 'valeur' et dont l'expiration sera fixée à 'expire', c'est un 'timestamp' (nombre de seconde après le 1° janvier 1970 à 0h).
Si 'expire' n'est pas présent, il est considéré valoir 0, dans ce cas le cookie sera détruit à la fermeture du navigateur.
Si 'valeur' est aussi absente, le cookie 'nom' est effacé.
Cette fonction doit être appelée avant toute sortie d'information.
Tout simplement dans le tableau associatif '$ _COOKIE'.
Au début de tout envoi vers la machine de l'utilisateur, le serveur transmet un en-tête conforme au protocole HTTP. Il indique notamment la nature du document ou des informations de redirection ou d'erreur.
Dans certains cas, il peut être utile de créer un en-tête particulier. PHP le permet avec la fonction 'header();'.
Cette fonction produit 'texte' comme en-tête.
Cette fonction doit être appelée avant toute autre sortie.
Voyons quelques utilisations.
Le paramètre doit commencer par "Location : " qui sera suivi par l'adresse absolue de la page :
header("Location: http://www.site.com/nouvelle_page.php";
Cette possibilité est utile dans le cas où selon le déroulement du script (instructions 'if' ou 'switch') on veut envoyer une ou autre page.
S'il s'agit d'une redirection permanente, il est préférable de la faire directement au niveau du serveur par le fichier '.htaccess".
Pour que l'utilisateur soit invité à télécharger un fichier plutôt que de l'afficher dans la fenêtre du navigateur, il faut envoyer deux en-têtes, l'une pour indiquer le type du document, l'autre pour définir le nom du fichier à sauvegarder.
Il s'agit d'un document "PDF", l'utilisateur sera invité à l'obtenir sous le nom 'notice.pdf'. La fonction 'include' produit le document.
Le PHP dispose d'une fonction pour envoyer un message électronique. Notez cependant que parfois cette fonction est limitée par le gestionnaire du serveur afin d'éviter la production de "spams".
Envoie à l'adresse électronique 'dest' le texte 'corps' avec comme objet 'sujet', le dernier paramètre 'cpl' permet de compléter l'en-tête du message (voir ci-dessous). Cette fonction renvoie TRUE si elle a réussi.
S'il y a plusieurs destinataires, leurs adresses électroniques doivent être séparées par une virgule suivie d'un espace.
Il s'agit de lignes, séparées par '\n' et commençant par un mot-clef, utiles à l'acheminement du message, en voici quelques uns.
Mot clef | Rôle |
From: | Généralement obligatoire, adresse de l'expéditeur. |
Reply-To: | Adresse pour la réponse |
Cc: | Destinataires en copie |
Bcc: | Destinataires invisibles |
Il peut y en avoir d'autres, notamment si le message est au format HTML.
L'en-tête doit se terminer par un double saut de ligne : "\n\n".
Exemple :
Notons, dans l'en-tête, l'utilisation des guillemets, non seulement pour évaluer les variables mais aussi pour que '\n' soit traité correctement.
La fonction 'htmlentities' pour le corps du message protège des caractères spéciaux pour l'HTML.
* Remarque concernant cet exemple qui est utilisé pour un formulaire d'envoi : le message est envoyé à l'expéditeur (accusé d'envoi) et le destinataire le reçoit en copie cachée.
Il faut être prudent si l'on crée un formulaire d'envoi de message afin qu'il ne soit pas utilisé par des producteurs de SPAM.
.Encore quelques fonctions de la bibliothèque PHP