Cpm Affiliation : la régie publicitaire au Cpm

Transmettre des variables

Après dix chapitres intensifs sur le PHP, vous commencez tout doucement à avoir un peu d'expérience. Jusqu'à maintenant, vous créiez votre code, vous alliez sur la page et vous regardiez simplement le résultat sans demander plus.
Et si on donnait un peu de vie à tout ça en donnant la possibilité au visiteur d'interagir avec votre script sans le modifier ?

Bienvenue dans le monde magique et maléfique (très important, ce mot  ) des formulaires et de la transmission de variables.

35, rue machin

Il existe plusieurs méthodes pour transmettre des variables, mais on va commencer par la plus simple : les adresses (URL).

Pour l'instant, l'URL vous permet juste de dire à votre navigateur quel fichier appeler, mais les URL vous cachent bien des choses, car elles peuvent transmettre des variables !

Créez un fichier PHP, appelez-le url.php et tapez ce code :

Code PHP :

<?php

echo '<pre>';
print_r($_GET);
echo '</pre>';

?>

Si vous avez bien suivi le chapitre sur les arrays, vous devez savoir que print_r() est une fonction qui permet d'afficher joliment un array. Vous pouvez donc en conclure que $_GET est un array. Mais vous remarquez aussi que je n'ai pas défini $_GET. Vous pourriez donc penser que vous aurez une erreur en testant ce script : qui veut tenter le diable ?

Faites-le tous.

Pour arriver sur cette page, vous taperez dans votre navigateur une URL du style http://localhost/alias/url.php ou encore http://127.0.0.1/alias/url.php. Quand vous arrivez sur cette page, quelle chance, pas d'erreur et on a même du texte ! On voit ceci :

Array
(
)

Ça ne fera pas de vous les rois du monde, mais ça vous indique quelque chose : $_GET est un array, est défini, alors que je ne l'ai pas fait dans mon script.
Ne faites pas ces grands yeux, c'est tout à fait normal. En effet, le PHP crée lui-même des variables, on les appelle des superglobales.

C'est l'occasion de faire un petit écart et d'introduire une nouvelle notion : la portée des variables. Vous vous souvenez de ce que j'ai dit à propos des variables et des fonctions ?
Je vous ai dit de ne jamais utiliser de variables déclarées hors d'une fonction dans une fonction ou l'inverse. Si j'ai dit ça, c'est à cause de la portée des variables.

Il existe trois « genres » de variables : les variables superglobales, les variables globales et les variables locales.
On va prendre un code tout simple :

Code PHP :

<?php

function machin()
{
$a = $_GET;
return $a%2;
}

$b = machin();
if(true)
{
var_dump($b);
}

?>

Les trois genres de variables sont présents dans ce simple code. Mais quelle variable représente quel genre ? $_GET est une variable superglobale, $b est une variable globale et $a est une variable locale.
La différence entre ces trois genres est simple. La variable locale n'existe que dans le bloc d'instructions (délimité par des accolades ({})) dans lequel elle a été définie. Si vous tentez d'y accéder en étant hors de ce bloc d'instructions, vous aurez une erreur. Les variables que vous définissez dans une fonction sont locales. Mais celles que vous définissez dans des structures de contrôle ne le sont pas, elles sont globales.
Une variable globale est accessible partout, sauf dans les blocs d'instructions qui créent des variables locales (pour le moment, seul le bloc d'instructions d'une fonction peut faire ça).

Ces deux principes expliquent pourquoi, si je déclare une variable dans une fonction, je ne peux y accéder de l'extérieur de ma fonction, et pourquoi, si je déclare une variable hors d'une fonction, je ne peux l'utiliser dans une fonction.

ATTENTION : Les paramètres d'une fonction sont aussi des variables locales.

Reste le troisième « genre », les superglobales. Comme vous l'avez peut-être deviné, ce sont des variables qui sont accessibles absolument partout, même dans les fonctions. C'est pourquoi mon code précédent fonctionne, d'ailleurs.

ATTENTION : Vous ne pouvez pas créer de variables superglobales, mais vous pouvez modifier celles qui existent déjà.

Voilà, ce court passage sur la portée des variables se termine, c'est assez important de saisir cette notion.

Mais revenons à nos moutons. Je vous ai dit que le PHP créait lui-même des variables, des superglobales ; dans la version actuelle du PHP, ces variables sont au nombre de neuf : $_SERVER, $_ENV, $_COOKIE, $_SESSION, $_GET, $_POST, $_FILES, $_REQUEST et enfin $GLOBALS.
Vous voyez qu'elles sont très faciles à reconnaître : en effet, elles sont toutes en majuscules et leur nom commence (à une exception près) par un underscore.
Faites des print_r() de ces variables pour voir toutes les informations qu'elles recèlent, une vraie mine d'or !

Pour l'instant, on ne s'intéresse qu'à une d'entre elles : $_GET. Reprenez votre script de tout à l'heure, et au lieu d'aller à l'adresse http://localhost/alias/url.php ou encore à http://127.0.0.1/alias/url.php, allez à l'adresse http://localhost/alias/url.php?test=1&amp;bla=2 ou encore à http://127.0.0.1/alias/url.php?test=1&amp;bla=2. Et voilà, vous venez de transmettre des variables par une URL. Vous pouvez voir que le tableau $_GET contient deux associations.

Mais comment ça fonctionne ? C'est simple : pour transmettre des variables avec des URL, il vous suffit d'ajouter un point d'interrogation, puis de mettre l'association clé / valeur ainsi : cle=valeur. Si vous voulez mettre plusieurs associations, il faut les séparer par un &amp; (dans le code source HTML, il faut mettre &amp;amp; et non &amp; pour que le code HTML soit valide).

Testez un peu tout et n'importe quoi, ?truc=4&amp;true=bla&amp;r=5.45, ?hihan=meuh, etc. pour vous familiariser avec ça. Exemple (le fichier s'appelle url.php et se trouve au chemin http://localhost/url.php, modifiez chez vous au besoin) :

Code PHP :

<?php

if(isset($_GET['nom']))
{
echo $_GET['nom'];
}

echo '<a href="http://localhost/url.php?nom=Eve">Je m\'appelle Eve</a>';
echo '<a href="http://localhost/url.php?nom=Audrey">Je m\'appelle Audrey</a>';
echo '<a href="http://localhost/url.php?nom=Leslie">Je m\'appelle Leslie</a>';
echo '<a href="http://localhost/url.php?nom=Flore">Je m\'appelle Flore</a>';

?>

Vous remarquerez que j'ai utilisé la fonction isset() qui, comme vous devez le savoir, vérifie si une variable existe. Si j'ai fait ça, c'est pour éviter une erreur. En effet, si je met directement echo $_GET['nom'] mais qu'au lieu d'aller à l'adresse http://localhost/url.php?nom=quelque_chose je vais à l'adresse http://localhost/url.php, que se passe-t-il ? L'association qui porte la clé nom n'est pas créée étant donné qu'elle n'est pas dans mon URL sous la forme cle=valeur, je vais donc tenter d'utiliser une association qui n'existe pas : le PHP me retournera une erreur d'undefined index
$_GET est un array. Désolé d'écrire si gros, mais je suis obligé.  Beaucoup de personnes viennent et demandent de l'aide sur les fonctions $_GET, $_POST ou autres. Mais $_GET et les autres superglobales ne sont pas des fonctions (il y aurait des parenthèses), ce sont des arrays et rien d'autre !

Gardons la forme !

Pour cette partie, si vous n'avez pas de bases en HTML, vous ne comprendrez rien. Donc si vous ne savez pas ce qu'est un formulaire, je vous invite à aller voir un autre tutoriel, sans quoi vous n'irez nulle part.

Bon, si vous savez ce qu'est un formulaire (des zones de texte, des cases à cocher, etc.), reprenez votre page url.php et mettez ce code :

Code PHP :

<?php

echo '<pre>';
print_r($_POST);
echo '</pre>';

?>

Vous savez ce qu'est $_POST, c'est un array. Oups, mauvais bouton. 
Sans plus attendre, jouons avec les formulaires (form en anglais) :

Code PHP :

<?php

echo '<pre>';
print_r($_POST);
echo '</pre>';

?>
<form action="./url.php" method="post">
<p>
<input type="text" name="test" value="Oh Yeah" />
<br />
<textarea name="lala" rows="5" cols="5">Bonjour le monde</textarea>
<br />
<input type="checkbox" name="ohoh" checked="checked" /> J'aime le rose
<br />
<select name="euh">
<option value="1">Meuh</option>
<option value="2">La</option>
<option value="3" selected="selected">Vache</option>
</select>
<br />
<input type="radio" name="prout" value="1" checked="checked" /> Oui
<input type="radio" name="prout" value="0" /> Non
<br />
<input type="hidden" name="ninja" value="ramen" />
<br />
<input type="submit" value="Valide-moi !" name="valid" />
</p>
</form>

Amusez-vous à changer les valeurs, cocher et décocher les cases, etc., et regardez ce que devient $_POST.
Vous pouvez constater qu'en fonction de ce que vous mettez dans votre formulaire, les associations de l'array $_POST changent. C'est tout à fait normal. En effet, $_POST est un array vide à la base. Mais quand vous soumettez un formulaire, votre ordinateur envoie une requête particulière au serveur (un header), et en fonction des éléments du formulaire et de leur valeur, le PHP remplit $_POST avec les associations qui conviennent.

On va donc expliciter le rôle de chacun d'eux.

Les zones de texte

Cet élément du formulaire permet de créer une zone de texte d'une ligne.

Code HTML :

<input type="text" name="machin" value="truc" />


Quand je mets ce code HTML, mon navigateur me crée une zone de texte et la préremplit avec la chaîne de caractères qui se trouve dans l'attribut value, truc dans l'exemple.

Quand vous soumettez le formulaire, cet élément va créer une association dans $_POST, la clé sera la valeur de l'attribut name (machin dans l'exemple) et la valeur sera le texte qui est dans la zone de texte. Rien de bien compliqué. Si on fait un echo $_POST['machin'];, ça nous affichera ce qu'il y a dans la zone de texte par exemple.

Les zones de texte multi-lignes

Cet élément du formulaire permet de créer une zone de texte de plusieurs lignes.

Code HTML :

<textarea name="lala">Bonjour, je suis une valeur par défaut</textarea>

Le texte qui se trouve entre les deux balises sera mis dans la zone de texte automatiquement (et s'il n'y a rien, il n'y aura pas de texte par défaut). L'attribut name servira de clé dans $_POST alors que la valeur sera ce qui est contenu dans la zone de texte.

INFORMATION : Quand vous faites un retour à la ligne, votre navigateur insère un \n (nouvelle ligne, rappelez-vous) dans la chaîne de caractères.

Un echo $_POST['lala']; affichera le texte qui se trouve dans la zone de texte.

Les cases à cocher

Cet élément du formulaire permet de créer une case à cocher.

Code HTML :

<input type="checkbox" name="oh" checked="checked" />

Là, deux cas sont possibles : si la case est cochée, le PHP créera une association dans $_POST dont la clé sera la valeur de l'attribut name et la valeur sera la chaîne de caractères 'on' ; mais si la case n'est pas cochée, le PHP ne créera pas d'association. Pour savoir si une case est cochée ou non, il faut donc utiliser la fonction isset() ou array_key_exists().

INFORMATION : Si vous mettez checked="checked", la case sera cochée automatiquement ; enlevez-le pour que la case ne soit pas cochée par défaut.

Les listes

Cet élément du formulaire permet de créer une liste dans laquelle on choisira une seule et unique valeur.

Code HTML :

<select name="euh">
<option value="1">Oh</option>
<option value="2" selected="selected">Yeah</option>
<option value="3">!</option>
</select>

Quand vous validez un formulaire contenant cette liste, le PHP va créer une association dans $_POST dont la clé sera la valeur de l'attribut name (pour ne pas changer...) et dont la valeur sera la valeur de l'attribut value de l'option que vous aurez choisie.
Si je choisis l'option 'Oh', la valeur de l'association sera '1', si je choisis 'Yeah', ça sera '2', et si je choisis '!' ça sera 3.

INFORMATION : Rajouter l'attribut selected="selected" sélectionnera l'option par défaut.

Les boutons

Cet élément du formulaire vous permet de créer des boutons à cocher (ça ressemble un peu aux listes).

Code HTML :

<input type="radio" name="prout" value="1" checked="checked" />
<input type="radio" name="prout" value="2" />

Ces éléments de formulaire doivent toujours aller ensemble ; s'il n'y en a qu'un, ça revient à faire une case à cocher. Lorsque qu'on valide ce formulaire, le PHP va créer une association dans $_POST qui aura pour clé l'attribut name (qui est commun à plusieurs input) et comme valeur la valeur de l'attribut value du bouton qu'on aura coché.

INFORMATION : À nouveau, rajouter checked="checked" permet de cocher un bouton par défaut.

Si vous ne cochez aucun des boutons, aucune association ne sera créée.

Le champ caché

Cet élément permet de créer un champ caché aux yeux du visiteur.

Code HTML :

<input type="hidden" name="truc" value="Oui" />

Quand vous validerez le formulaire, le PHP créera une association dans $_POST qui aura comme clé la valeur de l'attribut name et comme valeur la valeur de l'attribut value.

Le bouton de validation

Cet élément vous permet de valider le formulaire en cliquant dessus.

Code HTML :

<input type="submit" name="valid" value="Valide-moi" />

En validant cela, le PHP créera une association qui aura pour clé la valeur de l'attribut name et comme valeur la valeur de l'attribut value.
En général, on ne met qu'un input de ce genre, mais il peut arriver qu'on ait besoin d'en mettre plusieurs pour laisser au visiteur le choix de faire telle ou telle action.

Un bouton plus coloré !

Il existe un autre bouton qui a le même rôle que le submit, à la différence près que c'est en cliquant sur une image et non sur un bouton qu'on valide le formulaire.

Code HTML :

<input type="image" src="lien_image.png" name="valid_image" />

Vous remarquez que je n'ai pas mis d'attribut value. En effet, quand on utilise cet input et qu'on valide le formulaire, le PHP ne créera pas l'association qui aura pour clé la valeur de l'attribut name. À la place, le PHP va créer deux associations : une qui aura comme clé le caractère 'x' et une autre qui aura comme clé le caractère 'y'.
Ces deux associations sont des coordonnées, ça indique à quel endroit l'utilisateur a cliqué sur l'image.

Aspiration !

Le tout dernier élément que je vais vous montrer nous servira bientôt : il permet d'uploader des fichiers (en clair, les envoyer de votre ordinateur vers le serveur). Son utilisation implique une légère modification de la balise <form></form>, mais on verra ça en temps voulu quand on fera un script pour permettre aux visiteurs d'uploader des images sur votre serveur !

Code HTML :

<input type="file" name="olala" />

N'essayez pas de chercher une association dans $_POST en utilisant cet input, vous ne trouverez rien. Cet élément est un peu différent des autres et l'association sera créée dans la superglobale $_FILES.

Et voilà : c'était vraiment lourd, cette partie (car très répétitive, il faut l'avouer), mais maintenant vous savez vous servir d'un formulaire en PHP !

Never Trust User Input

Maintenant que je viens de vous exposer comment laisser vos visiteurs interagir avec vos scripts, je dois vous avouer quelque chose : vous allez vous faire hacker votre site...

Désolé, je n'ai pas pas pu résister, mais soyez tranquilles, c'est faux, votre site ne va pas se faire hacker. Toutefois, ce que je vous ai montré est la porte ouverte à toutes sortes de risques de failles dans votre code. La plupart des failles de sécurité liées au PHP tirent leur origine de $_GET et $_POST (ainsi que de $_COOKIE, mais c'est pour plus tard).
Je ne peux pas encore vous expliquer en détail pourquoi ces formulaires sont dangereux, puisque c'est surtout dans la partie II de ce tutoriel qu'il y a vraiment des risques et qu'on peut se faire avoir.

Mais dans tous les cas, soyez rassurés. La sécurité en PHP tient en quelques mots : Never Trust User Input.
Littéralement et en français, ça veut dire « Ne jamais croire (faire confiance) aux entrées de l'utilisateur ». Quand vous mettez un formulaire à disposition sur votre site, vous le faites généralement pour faire un sondage, ou pour laisser la possibilité aux gens de s'exprimer. Mais beaucoup de dérives sont possibles, à plusieurs niveaux. Ce petit texte n'a pas pour vocation de vous enseigner toutes les ficelles de la sécurité, car c'est avant tout une histoire de comportement. La seule faille que je puisse vous montrer actuellement, c'est la faille XSS.

Reprenez votre page url.php et mettez-y ce code, puis validez le formulaire.

Code PHP :

<?php

if(isset($_POST['texte']))
{
echo $_POST['texte'];
}

?>
<form action="./url.php" method="post">
<p>
<textarea name="texte" rows="10" cols="50">
<script type="text/javascript">
alert('Ohoh, vous avez été piraté par `Haku !!');
</script>
</textarea>
<input type="submit" name="valid" value="go" />
</p>
</form>

Testez ce code et... Oh mon Dieu ! Je vous ai piraté. Non, rassurez-vous, je n'ai rien fait de méchant, votre PC ne va pas exploser, votre disque dur ne va pas danser la samba, les aliens ne vont pas débarquer ; j'ai juste mis un petit code JavaScript qui permet d'afficher une boîte de dialogue. Ce n'est pas plus méchant qu'une plume.

Vous voyez donc que si on laisse l'utilisateur mettre ce qu'il veut, il peut faire des choses qui ne sont pas prévues à la base et qui peuvent être ennuyeuses, voire même dangereuses.

Par exemple, faire une boucle infinie qui afficherait tout le temps des boîtes de dialogue comme celle que j'ai affichée, ça serait ennuyeux. Vous devriez tuer le processus de votre navigateur internet pour sortir de cette situation.
Mais en quoi est-ce dangereux ? C'est simple. En PHP, il existe une superglobale, $_COOKIE, qui permet de sauvegarder des informations sur l'ordinateur d'un visiteur. Ne criez pas au scandale, les cookies sont de simples fichiers texte, ils ne peuvent rien faire sur votre ordinateur, ce n'est pas Big Brother. Ce sont juste des fichiers texte qui permettent au script de sauver des informations propres au visiteur (par exemple, si vous allez sur un site qui propose plusieurs designs, il stockera une information dans un cookie qui permettra de ne pas avoir à vous redemander quel design vous voulez à chaque visite).

Mais on peut mettre des informations beaucoup plus sensibles dans les cookies, comme par exemple des mots de passe pour vous connecter à des espaces membres (les mots de passe ne sont pas là tels quels, ils sont « cachés » grâce à une fonction de hashage).
Et c'est là que la faille XSS arrive. Vous avez vu que je peux injecter du code JavaScript et le faire s'exécuter. Le problème, c'est que le JavaScript peut accéder aux cookies. Et donc, si je remplaçais le code qui affiche une boîte de dialogue par un code plus vicieux, qui vous redirigerait vers une page piégée, je pourrais obtenir votre mot de passe et me faire passer pour vous sur tous les sites où vous employez ce mot de passe (c'est d'ailleurs pourquoi il est conseillé de ne pas utiliser tout le temps le même mot de passe, il faut en avoir plusieurs, idéalement un par site ou application).

Maintenant, comment s'en protéger ?
La méthode est simple et a fait ses preuves : utilisez la fonction PHP htmlspecialchars().
Cette fonction transforme cinq caractères en leur équivalent HTML. Bon, et alors ? Eh bien c'est simple.
Si vous tapez ceci dans une page HTML :

Code HTML :

<script type="text/javascript">alert('hoho');</script>

... vous allez revoir une boîte de dialogue.
Maintenant, on va remplacer les chevrons (< et >) par leur équivalent HTML respectif : &lt; et &gt;.
Remettez ce code dans une page HTML et regardez ce qu'il se passe :

&lt;script type="text/javascript"&gt;alert('hoho');&lt;/script&gt;

Magie, plus de boîte de dialogue. La raison est simple : votre navigateur sait que s'il rencontre les balises <script></script>, il doit interpréter ce qu'il y a entre les balises comme du JavaScript. Mais comme on a remplacé les chevrons par leur équivalent HTML (c'est-à-dire une suite de caractères qui affiche la même chose mais qui n'a pas la même valeur), votre navigateur n'interprète pas ce qu'il y a entre les balises comme du JavaScript.

Et voilà comment se protéger de cette faille.
Reprenons le code du début en y adjoignant la fonction htmlspecialchars(), et admirons le résultat :

Code PHP :

<?php

if(isset($_POST['texte']))
{
echo htmlspecialchars($_POST['texte']);
}

?>
<form action="./url.php" method="post">
<p>
<textarea name="texte" rows="10" cols="50">
<script type="text/javascript">
alert('Ohoh, vous avez été piraté par `Haku !!');
</script>
</textarea>
<input type="submit" name="valid" value="go" />
</p>
</form>

Voici la liste des caractères remplacés par htmlspecialchars() :

  • & => &amp;
  • < => &lt;
  • > => &gt;
  • " => &quot;
  • ' => &#039;

INFORMATION : Certains caractères ne sont remplacés que si vous donnez un second argument à la fonction ; pour savoir comment ça fonctionne, allez voir dans la documentation, on a vu comment s'en servir !

L'enfer des guillemets magiques

Après un petit blabla fort intéressant sur la faille XSS, on va prendre un peu de temps pour discuter d'un autre problème plutôt ennuyeux (je voulais dire emmerdant, mais ce n'est pas très pédagogique !) : les guillemets magiques.

Ça me pose un problème d'en parler ici, puisque la cause de ces guillemets magiques (les magic_quotes) et ce qui a justifié leur création vous sont encore inconnus. Je vais donc en parler, mais très brièvement.

Testez ce code PHP  :

<?php

$text = 'lala des " et encore des " ' . " et des ' sans oublier les '";
echo $text;
echo addslashes($text);

?>

Vous voyez que les deux echo (echo qui est une structure, pas une fonction, je le rappelle) n'affichent pas la même chose. On aurait pu s'en douter, vu que l'un affiche directement $text, alors que l'autre affiche la valeur de retour d'une fonction : addslashes().
Le but de cette fonction est très simple : elle rajoute un backslash (\) devant ces quatre chaînes de caractères : ", ', \ et NULL.

Bon, vous allez me demander quel est l'intérêt de cette fonction ; je pourrais vous répondre, mais ça ne servirait à rien parce qu'on n'a pas encore abordé le sujet. Tout ce que je peux dire, c'est que pendant longtemps, cette fonction a été la défense de bien des codeurs face à une possible faille.

Mais quel rapport avec les formulaires ? Eh bien c'est simple. Dans le fichier de configuration du PHP (un truc obscur que l'on n'a jamais vu), il y a des directives, c'est-à-dire des ordres que le PHP doit suivre.
L'une de ces directives s'appelle magic_quote_gpc. Si cette directive est activée, le PHP va appliquer la fonction addslashes() à toutes les valeurs présentes dans les arrays GPC ($_GET, $_POST et $_COOKIE). Et donc, on risque de se retrouver avec une panoplie de backslashes en trop !

Idéalement, il faudrait que cette directive disparaisse : elle n'a été implémentée que pour pallier le manque de mesures de sécurité des codeurs PHP. Seulement, comme cette directive est désactivable, la configuration peut changer. Si vous faites votre script sur un serveur qui a désactivé la directive et qu'ensuite, vous décidez de changer de serveur et d'aller sur un autre qui a activé cette directive, vous aurez des backslashes dans tous les coins et vous devrez modifier votre script pour réparer les dégâts.
Heureusement, la version 6 du PHP fera disparaître cette directive. Malheureusement, il y a des tas de serveurs qui resteront avec le PHP version 5 pendant un bon moment, et même avec le PHP version 4.
Je vais vous donner un code qui va vous permettre de ne plus avoir à vous soucier des guillemets magiques et vous l'expliquer.

Code PHP :

<?php

if(get_magic_quotes_gpc())
{
$_POST = array_map('stripslashes', $_POST);
$_GET = array_map('stripslashes', $_GET);
$_COOKIE = array_map('stripslashes', $_COOKIE);
}

?>

Le fonctionnement est très simple : d'abord, on vérifie si les magic_quotes sont activés avec la fonction get_magic_quotes_gpc(). Si c'est le cas, on va utiliser la fonction inverse d'addslashes() : stripslashes().
Pour appliquer une fonction à l'ensemble des valeurs d'un array, on utilise la fonction array_map(). Le premier argument est le nom de la fonction qu'on veut appliquer (stripslashes() dans notre cas) ; le second argument est l'array sur lequel on va travailler.

Cette fonction est rudimentaire et peut être améliorée, mais pour le moment, ça suffira amplement.
Mais comme je l'ai dit, l'idéal est de les désactiver. Donc si vous avez accès au fichier de configuration du PHP (php.ini pour les intimes), suivez cette procédure pour désactiver les magic_quotes :

  • ouvrez le php.ini (chez moi, il est dans C:\Wamp\php\php.ini) ;
  • recherchez la chaîne 'magic_quotes_gpc' ;
  • mettez Off comme valeur pour les trois directives des magic_quotes pour obtenir ceci :
; Magic quotes
;

; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = Off

; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
magic_quotes_runtime = Off

; Use Sybase-style magic quotes (escape ' with '' instead of \').
magic_quotes_sybase = Off

Reste à redémarrer votre serveur pour que la modification soit effective.

Boum, plus de magic_quotes !
On reviendra là-dessus dans la partie II de ce tutoriel de toute façon, pour découvrir pourquoi cette directive existe.

Je suis perdu !

Je vais maintenant vous parler très brièvement de quelque chose qui n'a rien à voir avec les formulaires ou la transmission de variables : les constantes.
Si j'en parle ici, c'est que je n'avais pas de place ailleurs.

On a déjà entendu parler des constantes, mais jusqu'à maintenant, on ne parlait que de valeur constante (comme par exemple la valeur constante 5, ou la valeur constante 'lala'). Mais cette fois, je vais vous parler des vraies constantes, c'est-à-dire des sortes de variables, dont on définit le nom et la valeur une fois, et dont la valeur sera impossible à modifier tout au long du script.

Voici comment on déclare une constante :

<?php

define('NOM_CONSTANTE', 'VALEUR_CONSTANTE');
echo NOM_CONSTANTE;

?>

Pour déclarer une constante, on utilise la fonction define(). Le premier argument est le nom qu'aura la constante ; le second est la valeur qu'elle prendra (une expression quelconque).
Vous voyez que j'ai fait une instruction bizarre, nouvelle : echo NOM_CONSTANTE;.
À première vue, vous avez dû vous dire que j'ai voulu écrire une chaîne de caractères mais que j'ai oublié de la délimiter avec des apostrophes ou des guillemets. Il n'en est rien. En tapant cette instruction, je voulais afficher la valeur de la constante.
Pour utiliser la valeur d'une constante, il suffit de taper son nom sans l'encadrer de guillemets ou d'apostrophes. Une constante est une expression comme une autre, au même titre qu'une variable, qu'une fonction qui retourne une valeur, etc. Vous pouvez donc l'utiliser pour beaucoup de choses (concaténation, assignation, calcul...).

Quand vous avez une variable, vous pouvez redéfinir sa valeur, exemple :

<?php

$a = 5;
echo $a;
$a = 7;
echo $a;

?>

Ce code fonctionne à merveille, mais si on tente de faire ça avec des constantes...

<?php

define('A', 5);
echo A;
define('A', 7);
echo A;

?>

Pan ! Une belle erreur pointe le bout de son nez. Elle est là pour nous dire qu'on tente de redéfinir la valeur d'une constante (enfin, elle dit plutôt que la constante existe déjà).

Mais quel intérêt ?
Je dirais qu'il y a deux cas majeurs où les constantes sont intéressantes.

Le premier, c'est si vous voulez vous assurer qu'une valeur ne change jamais. Une valeur qui resterait constante du début à la fin du script. Par exemple, pour configurer un script (nombre de news affichées par page, si on veut afficher les signatures sur un forum ou non, etc.), c'est très utile, parce qu'on ne risque pas de changer cette valeur.

Le second cas, c'est ce que j'appelle les arguments muets. Quand vous créez une fonction, vous lui donnez souvent des arguments, mais il peut arriver que vous ayez besoin de donner des arguments que je qualifie de muets.
Voici la liste des arguments muets :

  • un entier ;
  • un nombre à virgule ;
  • un booléen.

Pourquoi sont-ils muets ?
Tout simplement parce qu'on ne sait pas quel est leur rôle, à quoi ils servent. Un exemple vaut mieux qu'un discours, et c'est cadeau :

<?php

echo fonction_affiche_news(NB_NEWS_PAGE);

?>

<?php

echo fonction_affiche_news(20);

?>

INFORMATION : La constante NB_NEWS_PAGE est définie comme telle : define('NB_NEWS_PAGE', 20);.

Imaginez que ce n'est pas votre script : vous tombez sur l'appel de cette fonction. Qui peut me dire à quoi sert le nombre 20 ? À afficher une catégorie particulière de news ? À limiter le nombre de news par page ?
On ne peut pas le deviner sans aller voir la déclaration de la fonction, et on perd du temps.
Tandis qu'avec une constante, on a un mot, un nom qui nous permet d'identifier l'utilité de ce paramètre. Quand les scripts sont petits et qu'on les a développés seuls, l'intérêt est limité, je l'avoue. Mais quand on a de gros scripts qu'on crée à plusieurs, ça devient vite le bordel et les constantes permettent d'améliorer un peu la lisibilité du code !

Que de choses à retenir... Si vous ne deviez en retenir qu'une et une seule, c'est le Never Trust User Input. Tant que l'utilisateur ne peut pas affecter votre script, il n'y a quasiment aucune chance que votre script pose un quelconque problème de sécurité ; mais dès que l'utilisateur peut interagir avec votre script, si vous ne prenez pas garde, c'est la porte ouverte à toutes sortes de failles de sécurité.

Retenez bien qu'il ne faut jamais, jamais, jamais faire confiance à l'utilisateur. Même si vous faites un script de membres (on en fera un) et qu'il y a des administrateurs (des gens de confiance, en théorie), il ne faut pas leur faire confiance. Quand vous faites un script, toute autre personne que vous est un danger potentiel. J'insiste beaucoup là-dessus. La sécurité, ce n'est pas une histoire de fonction, mais une histoire de comportement. Vous devez prévoir toutes les dérives possibles de votre script et les empêcher.

Mais ne paniquez pas, hein  : même si j'en ai envie, je ne vais pas vous laisser patauger dans cette affaire tout seuls, on verra très bientôt les grandes lignes des principales failles de sécurité et on essayera de s'en protéger !

 

Infos Plan Partenaires
À propos Webmasters
C.G.U Services Gratuits Annuaire de sites web
Bannières Forum Ionoa

 

Aipoweb est un site édité par ASMOH NetWork  ©

Créer un site gratuit avec e-monsite - Signaler un contenu illicite sur ce site