Files
doc-fr/language/variables.xml
2022-05-06 14:40:21 +01:00

1156 lines
34 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 61cfd00858115c6fe029df05829b04c1ec5bc9c2 Maintainer: yannick Status: ready -->
<!-- Reviewed: yes -->
<chapter xml:id="language.variables" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Les variables</title>
<sect1 xml:id="language.variables.basics">
<title>Essentiel</title>
<simpara>
En PHP, les variables sont représentées par un signe
dollar "$" suivi du nom de la variable. Le nom est sensible à
la casse.
</simpara>
<para>
Les noms de variables suivent les mêmes règles de nommage que
les autres entités PHP. Un nom de variable valide doit commencer par
une lettre ou un souligné (_), suivi de lettres, chiffres ou
soulignés. Exprimé sous la forme d'une expression
régulière, cela donne :
<code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>
</para>
<note>
<simpara>
Dans nos propos, une lettre peut être a-z, A-Z, et les octets
de 128 à 255 (<literal>0x80-0xff</literal>).
</simpara>
</note>
<note>
<simpara>
<literal>$this</literal> est une variable spéciale,
qui ne peut pas être assignée.
Avant PHP 7.1.0, l'affectation indirecte (i.e. en utilisant
<link linkend="language.variables.variable">les variables variables</link>)
était impossible.
</simpara>
</note>
&tip.userlandnaming;
<para>
Pour obtenir des informations sur une variable, voyez les fonctions
dédiées aux <link linkend="ref.var">variables</link>.
</para>
<para>
<example>
<title>Validité des noms de variables</title>
<programlisting role="php">
<![CDATA[
<?php
$var = 'Jean';
$Var = 'Paul';
echo "$var, $Var"; // affiche "Jean, Paul"
$4site = 'pas encore'; // invalide : commence par un nombre
$_4site = 'pas encore'; // valide : commence par un souligné
$täyte = 'mansikka'; // valide : 'ä' est ASCII (étendu) 228.
?>
]]>
</programlisting>
</example>
</para>
<para>
Les variables sont toujours assignées par valeur.
C'est-à-dire, lorsque vous assignez une expression à
une variable, la valeur de l'expression est recopiée dans
la variable. Cela signifie, par exemple, qu'après avoir
assigné la valeur d'une variable à une autre,
modifier l'une des variables n'aura pas d'effet sur l'autre. Pour plus
de détails sur ce genre d'assignation, reportez-vous aux
<link linkend="language.expressions">expressions</link>.
</para>
<para>
PHP permet aussi d'assigner les valeurs aux variables
<link linkend="language.references">par référence</link>. Cela
signifie que la nouvelle variable ne fait que référencer
(en d'autres termes, "devient un alias de", ou encore "pointe sur") la
variable originale. Les modifications de la nouvelle variable
affecteront l'ancienne et vice versa.
</para>
<para>
Pour assigner par référence, ajoutez simplement
un &amp; (ET commercial) au début de la variable qui
est assignée (la variable source). Dans l'exemple suivant,
<literal>Mon nom est Pierre</literal> s'affichera deux
fois :
<example>
<title>Assignation de référence</title>
<programlisting role="php">
<![CDATA[
<?php
$foo = 'Pierre'; // Assigne la valeur 'Pierre' à $foo
$bar = &$foo; // Référence $foo avec $bar.
$bar = "Mon nom est $bar"; // Modifie $bar...
echo $foo; // $foo est aussi modifiée
echo $bar;
?>
]]>
</programlisting>
</example>
</para>
<para>
Une chose importante à noter est que seules les variables
nommées peuvent être assignées par référence.
<example>
<title>Assignation de référence et variables anonymes</title>
<programlisting role="php">
<![CDATA[
<?php
$foo = 25;
$bar = &$foo; // assignation valide
$bar = &(24 * 7); // assignation invalide : référence une expression sans nom
function test() {
return 25;
}
$bar = &test(); // assignation invalide.
?>
]]>
</programlisting>
</example>
</para>
<para>
Il n'est pas nécessaire d'initialiser les variables en PHP, cependant, cela reste
une excellente pratique. Les variables non initialisées ont une valeur par défaut
selon leur type - &false; pour les booléens, zéro pour les entiers et les réels, chaîne vide
pour les chaînes de caractères (comme utilisée avec
<function>echo</function>) ou un tableau vide
pour les tableaux.
</para>
<para>
<example>
<title>Valeurs par défaut des variables non initialisées</title>
<programlisting role="php">
<![CDATA[
<?php
// Une variable non initialisée et non référencée (pas de contexte d'utilisation); retourne NULL
var_dump($unset_var);
// L'utilisation d'un booléen; retourne 'false' (Voir l'opérateur ternaire pour comprendre cette syntaxe)
echo($unset_bool ? "true\n" : "false\n");
// Utilisation d'une chaîne de caractères; retourne 'string(3) "abc"'
$unset_str .= 'abc';
var_dump($unset_str);
// Utilisation d'un entier; retourne 'int(25)'
$unset_int += 25; // 0 + 25 => 25
var_dump($unset_int);
// Utilisation d'un entier/double; retourne 'float(1.25)'
$unset_float += 1.25;
var_dump($unset_float);
// Utilisation d'un tableau : retourne array(1) { [3]=> string(3) "def" }
$unset_arr[3] = "def"; // array() + array(3 => "def") => array(3 => "def")
var_dump($unset_arr);
// Utilisation d'un objet; crée un nouvel objet stdClass (voir http://www.php.net/manual/fr/reserved.classes.php)
// Retourne : object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
$unset_obj->foo = 'bar';
var_dump($unset_obj);
?>
]]>
</programlisting>
</example>
</para>
<para>
Utiliser la valeur par défaut d'une variable non initialisée est problématique
lorsque vous incluez un fichier dans un autre qui utilise le même nom de variable.
Une erreur de niveau <link linkend="errorfunc.constants.errorlevels.e-notice">E_NOTICE</link> sera émise
lorsque vous travaillerez avec des variables non initialisées, cependant, aucune
erreur ne sera lancée lorsque vous tenterez d'insérer un élément dans un tableau
non initialisé. La structure de langage <function>isset</function>
peut être utilisée pour détecter si une variable a déjà été initialisée.
</para>
</sect1>
<sect1 xml:id="language.variables.predefined">
<title>Variables pré-définies</title>
<para>
PHP fournit un grand nombre de variables pré-définies.
Cependant, beaucoup de ces variables ne peuvent pas être
présentées ici, car elles dépendent du serveur
sur lequel elles tournent, de la version et de la
configuration du serveur ou encore d'autres facteurs. Certaines
de ces variables ne seront pas accessibles lorsque PHP fonctionne
en <link linkend="features.commandline">ligne de commande</link>.
Pour plus de détails voir la
<link linkend="reserved.variables">liste des variables pré-définies</link>.
</para>
<para>
PHP fournit aussi un jeu de tableaux pré-définis contenant les variables
du serveur (si possible), les variables d'environnement et celles d'entrées.
Ces tableaux sont un peu particuliers, car ils sont automatiquement globaux,
c.à.d qu'ils sont automatiquement disponibles dans toutes les portées d'exécution.
Pour cette raison, ils sont dits 'superglobaux'. (il n'y a pas de mécanisme en
PHP pour créer de telles variables.) Pour plus de détails voir la
<link linkend="language.variables.superglobals">liste des superglobales</link>.
</para>
<note>
<title>Variables variables</title>
<para>
Les superglobales ne peuvent pas être utilisées comme
<link linkend="language.variables.variable">variables dynamiques</link>
dans les fonctions ou les méthodes des classes.
</para>
</note>
<para>
Si certaines variables de
<link linkend="ini.variables-order"><option>variables_order</option></link>
ne sont pas définies, leur tableau pré-défini PHP correspondant est laissé vide.
</para>
</sect1>
<sect1 xml:id="language.variables.scope">
<title>Portée des variables</title>
<simpara>
La portée d'une variable dépend du contexte
dans lequel la variable est définie. Pour la majorité des
variables, la portée concerne la totalité d'un script
PHP. Mais, lorsque vous définissez une fonction, la
portée d'une variable définie dans cette fonction
est locale à la fonction. Par exemple :
</simpara>
<example>
<title>Les variables sont locales à la fonction</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
include 'b.inc';
?>
]]>
</programlisting>
</example>
<simpara>
Ici, la variable <varname>$a</varname> sera accessible dans le script inclus
<filename>b.inc</filename>. Cependant, dans les fonctions
définies par l'utilisateur, une nouvelle définition
de cette variable sera donnée, limitée à la
fonction. Toute variable utilisée dans une fonction est,
par définition, locale. Par exemple :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 1; /* portée globale */
function test()
{
echo $a; /* portée locale */
}
test();
?>
]]>
</programlisting>
</informalexample>
<simpara>
Le script n'affichera rien à l'écran car
l'instruction <function>echo</function> utilise la variable locale <varname>$a</varname>,
et celle-ci n'a pas été assignée
préalablement dans la fonction. Vous pouvez noter que
ce concept diffère un petit peu du langage C dans
lequel une variable globale est automatiquement accessible dans
les fonctions, à moins d'être redéfinie
localement dans la fonction. Cela peut poser des problèmes
si vous redéfinissez des variables globales localement.
En PHP, une variable globale doit être
déclarée à l'intérieur de chaque
fonction afin de pouvoir être utilisée dans cette
fonction.
</simpara>
<sect2 xml:id="language.variables.scope.global">
<title>Le mot clé <literal>global</literal></title>
<simpara>
Commençons par un exemple avec <literal>global</literal> :
</simpara>
<para>
<example>
<title>Exemple avec <literal>global</literal></title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;
function somme() {
global $a, $b;
$b = $a + $b;
}
somme();
echo $b;
]]>
</programlisting>
</example>
</para>
<simpara>
Le script ci-dessus va afficher la valeur <literal>3</literal>.
En déclarant globales les variables <varname>$a</varname> et
<varname>$b</varname> locales
de la fonction somme(), toutes les références à
ces variables concerneront les variables globales. Il n'y a
aucune limite au nombre de variables globales qui peuvent
être manipulées par une fonction.
</simpara>
<simpara>
Une deuxième méthode pour accéder aux
variables globales est d'utiliser le tableau associatif
pré-défini <varname>$GLOBALS</varname>. Le précédent
exemple peut être réécrit de la
manière suivante :
</simpara>
<para>
<example>
<title>Les variables globales et <varname>$GLOBALS</varname></title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;
function somme() {
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
somme();
echo $b;
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Le tableau <varname>$GLOBALS</varname> est un tableau associatif avec le nom
des variables globales comme clé et les valeurs des éléments
du tableau comme valeur des variables. Notez que <varname>$GLOBALS</varname>
existe dans tous les contextes, car <varname>$GLOBALS</varname> est un
<link linkend="language.variables.superglobals">superglobal</link>.
Voici un exemple des super globaux :
</simpara>
<para>
<example>
<title>Exemple montrant les superglobales et la portée</title>
<programlisting role="php">
<![CDATA[
<?php
function test_superglobal()
{
echo $_POST['name'];
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
L'utilisation du mot clé <literal>global</literal> à l'extérieur
d'une fonction n'est pas une erreur. Il peut être utilisé si le fichier
est inclus depuis l'intérieur d'une fonction.
</para>
</note>
</sect2>
<sect2 xml:id="language.variables.scope.static">
<title>Utilisation des variables <literal>static</literal></title>
<simpara>
Une autre caractéristique importante de la portée des variables est
la notion de variable <emphasis>static</emphasis>. Une variable statique a
une portée locale uniquement, mais elle ne perd pas sa valeur lorsque le
script appelle la fonction. Prenons l'exemple suivant :
</simpara>
<para>
<example>
<title>Les variables statiques</title>
<programlisting role="php">
<![CDATA[
<?php
function test()
{
$a = 0;
echo $a;
$a++;
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Cette fonction est un peu inutile car à chaque fois
qu'elle est appelée, elle initialise <varname>$a</varname> à <literal>0</literal> et
affiche "<literal>0</literal>". L'incrémentation de la variable (<varname>$a</varname>++)
ne sert pas à grand chose, car dès que la
fonction est terminée, la variable <varname>$a</varname> disparaît.
Pour faire une fonction de comptage utile, c'est-à-dire qui
ne perdra pas la trace du compteur, la variable <varname>$a</varname> est
déclarée comme une variable statique :
</simpara>
<para>
<example>
<title>Les variables statiques (2)</title>
<programlisting role="php">
<![CDATA[
<?php
function test()
{
static $a = 0;
echo $a;
$a++;
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Maintenant, la variable <varname>$a</varname> est initialisée uniquement
lors du premier appel à la fonction et, à chaque fois que la fonction
<literal>test()</literal> est appelée, elle affichera une valeur de
<varname>$a</varname> incrémentée de 1.
</simpara>
<simpara>
Les variables statiques sont essentielles lorsque vous faites des
appels récursifs à une fonction. Une fonction
récursive est une fonction qui s'appelle elle-même.
Il faut faire attention lorsque vous écrivez une fonction
récursive car il est facile de faire une boucle infinie.
Vous devez vérifier que vous avez bien une condition qui
permet de terminer votre récursivité. La fonction
suivante compte récursivement jusqu'à 10, en utilisant la variable
<varname>$count</varname> pour savoir quand il faut s'arrêter :
</simpara>
<para>
<example>
<title>Les variables statiques et la récursivité</title>
<programlisting role="php">
<![CDATA[
<?php
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Les variables statiques peuvent être assignées des valeurs qui sont issue
d'expression constante, mais les expressions dynamique, tel que les appels
de fonctions, résulteront en une erreur d'analyse.
</para>
<para>
<example>
<title>Déclaration de variables statiques</title>
<programlisting role="php">
<![CDATA[
<?php
function foo(){
static $int = 0; // correct
static $int = 1+2; // correct
static $int = sqrt(121); // faux (car c'est une fonction)
$int++;
echo $int;
}
?>
]]>
</programlisting>
</example>
</para>
<para>
À partir de PHP 8.1.0, lorsqu'une méthode utilisant des variables statiques
est héritée (mais pas surchargée), la méthode héritée partage désormais les
variables statiques avec la méthode parente.
Cela signifie que les variables statiques dans les méthodes se comportent
désormais de la même manière que les propriétés statiques.
</para>
<example>
<title>Utilisation de variables statiques dans les méthodes héritées</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo {
public static function counter() {
static $counter = 0;
$counter++;
return $counter;
}
}
class Bar extends Foo {}
var_dump(Foo::counter()); // int(1)
var_dump(Foo::counter()); // int(2)
var_dump(Bar::counter()); // int(3), Avant PHP 8.1.0 int(1)
var_dump(Bar::counter()); // int(4), Avant PHP 8.1.0 int(2)
]]>
</programlisting>
</example>
<note>
<para>
Les déclarations statiques sont résolues au moment de la
compilation.
</para>
</note>
</sect2>
<sect2 xml:id="language.variables.scope.references">
<title>
Les références avec les variables <literal>global</literal> et <literal>static</literal>
</title>
<simpara>
PHP implémente les modificateurs de variables
<link linkend="language.variables.scope.static">static</link>
et <link linkend="language.variables.scope.global">global</link>,
en terme de <link linkend="language.references">référence</link>.
Par exemple, une vraie variable globale est importée dans un
contexte de fonction avec <literal>global</literal>.
Cette commande crée en fait une référence sur la variable globale. Cela
peut vous mener à des comportements inattendus, par exemple :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function test_global_ref() {
global $obj;
$new = new stdclass;
$obj = &$new;
}
function test_global_noref() {
global $obj;
$new = new stdclass;
$obj = $new;
}
test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>
]]>
</programlisting>
</informalexample>
&example.outputs;
<screen>
<![CDATA[
NULL
object(stdClass)#1 (0) {
}
]]>
</screen>
<simpara>
Un comportement similaire s'applique à la commande <literal>static</literal>.
Les références ne sont pas stockées dynamiquement :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
function &get_instance_ref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
$new = new stdclass;
// Assign a reference to the static variable
$obj = &$new;
}
if (!isset($obj->property)) {
$obj->property = 1;
} else {
$obj->property++;
}
return $obj;
}
function &get_instance_noref() {
static $obj;
echo 'Static object: ';
var_dump($obj);
if (!isset($obj)) {
$new = new stdclass;
// Assign the object to the static variable
$obj = $new;
}
if (!isset($obj->property)) {
$obj->property = 1;
} else {
$obj->property++;
}
return $obj;
}
$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>
]]>
</programlisting>
</informalexample>
&example.outputs;
<screen>
<![CDATA[
Static object: NULL
Static object: NULL
Static object: NULL
Static object: object(stdClass)#3 (1) {
["property"]=>
int(1)
}
]]>
</screen>
<simpara>
Ces exemples illustrent les problèmes rencontrés lors de l'assignation
de référence à des variables statiques, qui sont
<emphasis>oubliées</emphasis> lorsque vous appelez
<literal>&amp;get_instance_ref()</literal> une seconde fois.
</simpara>
</sect2>
</sect1>
<sect1 xml:id="language.variables.variable">
<title>Les variables dynamiques</title>
<simpara>
Il est pratique d'avoir parfois des noms de variables qui sont variables.
C'est-à-dire un nom de variable qui est affecté et utilisé
dynamiquement. Une variable classique est affectée avec
l'instruction suivante :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = 'bonjour';
?>
]]>
</programlisting>
</informalexample>
<simpara>
Une variable dynamique prend la valeur d'une variable et l'utilise
comme nom d'une autre variable. Dans l'exemple ci-dessous,
<emphasis>bonjour</emphasis> peut être utilisé comme le nom d'une
variable en utilisant le "$$" précédent la variable.
C'est-à-dire :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$$a = 'monde';
?>
]]>
</programlisting>
</informalexample>
<simpara>
À ce niveau, deux variables ont été définies et
stockées dans l'arbre des symboles PHP : <varname>$a</varname> avec comme valeur
"bonjour" et <varname>$bonjour</varname> avec comme valeur "monde". Alors, l'instruction :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo "$a ${$a}";
?>
]]>
</programlisting>
</informalexample>
<simpara>
produira le même affichage que :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo "$a $bonjour";
?>
]]>
</programlisting>
</informalexample>
<simpara>
c'est-à-dire : <computeroutput>bonjour monde</computeroutput>.
</simpara>
<simpara>
Afin de pouvoir utiliser les variables dynamiques avec les tableaux,
vous avez à résoudre un problème ambigu. Si vous
écrivez <varname>$$a[1]</varname>, l'analyseur a besoin de savoir si vous
parler de la variable qui a pour nom <varname>$a[1]</varname> ou bien si vous
voulez l'index [1] de la variable <varname>$$a</varname>. La syntaxe pour résoudre
cette ambiguïté est la suivante : <varname>${$a[1]}</varname> pour le premier
cas et <varname>${$a}[1]</varname> pour le deuxième.
</simpara>
<simpara>
On peut également accéder aux propriétés d'une classe
en utilisant les noms des variables. Le nom de la variable
sera résolu en utilisant la portée depuis laquelle l'appel
s'effectue. Par exemple, si vous avez une expression de la forme
<varname>$foo->$bar</varname>, alors la portée locale sera
examinée pour <varname>$bar</varname> et sa valeur sera utilisée
comme nom pour la propriété de <varname>$foo</varname>.
Ce comportement reste valide si <varname>$bar</varname>
est un tableau.
</simpara>
<simpara>
Les accolades peuvent aussi être utilisées, pour clairement délimiter
le nom de la propriété. Ceci est utile lors de l'accès à des valeurs
d'une propriété qui contient un tableau, lorsque le nom de la propriété
est composé de plusieurs parties, ou lorsque le nom de la propriété
contient des caractères non valides (i.e. depuis la fonction
<function>json_decode</function> ou <link linkend="book.simplexml">SimpleXML</link>).
</simpara>
<para>
<example>
<title>Exemple de propriété variable</title>
<programlisting role="php">
<![CDATA[
<?php
class foo {
var $bar = 'I am bar.';
var $arr = array('I am A.', 'I am B.', 'I am C.');
var $r = 'I am r.';
}
$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo $foo->$bar . "\n";
echo $foo->{$baz[1]} . "\n";
$start = 'b';
$end = 'ar';
echo $foo->{$start . $end} . "\n";
$arr = 'arr';
echo $foo->{$arr[1]} . "\n";
?>
]]>
</programlisting>
&example.outputs;
<screen>
I am bar.
I am bar.
I am bar.
I am r.
</screen>
</example>
</para>
<warning>
<simpara>
Notez que les variables dynamiques ne peuvent pas être utilisées
avec les
<link linkend="language.variables.superglobals">tableaux Superglobaux</link> dans
une fonction ou une classe. La variable <literal>$this</literal> est aussi
une variable spéciale qui ne peut être référencée dynamiquement.
</simpara>
</warning>
</sect1>
<sect1 xml:id="language.variables.external">
<title>Variables externes à PHP</title>
<sect2 xml:id="language.variables.external.form">
<title>Formulaires HTML (GET et POST)</title>
<simpara>
Lorsqu'un formulaire est envoyé à un script PHP,
toutes les variables du formulaire seront automatiquement disponibles
dans le script. Il y a peu de façon pour récupérer ces informations,
par exemple :
</simpara>
<para>
<example>
<title>Exemple avec un formulaire simple</title>
<programlisting role="html">
<![CDATA[
<form action="foo.php" method="post">
Nom : <input type="text" name="username" /><br />
Email: <input type="text" name="email" /><br />
<input type="submit" name="submit" value="Envoie!" />
</form>
]]>
</programlisting>
</example>
</para>
<para>
Il y a que deux façons d'accéder aux données provenant d'un formulaire HTML.
Les méthodes disponible actuellement sont décrites ci-dessous :
</para>
<para>
<example>
<title>Accéder simplement à des variables de formulaires POST</title>
<programlisting role="php">
<![CDATA[
<?php
echo $_POST['username'];
echo $_REQUEST['username'];
?>
]]>
</programlisting>
</example>
</para>
<para>
Utiliser un formulaire de type GET est similaire, hormis le fait que
vous deviez utiliser les variables pré-définies de GET à la place.
GET s'applique aussi à la <literal>QUERY_STRING</literal>
(les informations disponibles après le '?' dans une URL).
De ce fait, par exemple,
<literal>http://www.example.com/test.php?id=3</literal>
contient les données de GET, qui sont accessibles via <varname>$_GET['id']</varname>.
Voyez aussi <varname>$_REQUEST</varname>.
</para>
<note>
<para>
Les points et les espaces dans les noms de variables
sont convertis en underscores. Par exemple,
<literal>&lt;input name="a.b" /&gt;</literal> deviendra
<literal>$_REQUEST["a_b"]</literal>.
</para>
</note>
<simpara>
PHP comprend aussi les tableaux dans le contexte des formulaires.
(voir aussi <link linkend="faq.html">la FAQ</link>). Vous pouvez,
par exemple, grouper des variables ensemble ou bien utiliser cette
fonctionnalité pour lire des valeurs multiples d'un menu déroulant.
Par exemple, voici un formulaire qui se poste lui-même des données,
et les affiche :
</simpara>
<para>
<example>
<title>Variables de formulaires complexes</title>
<programlisting role="php">
<![CDATA[
<?php
if ($_POST) {
echo '<pre>';
echo htmlspecialchars(print_r($_POST, true));
echo '</pre>';
}
?>
<form action="" method="post">
Name: <input type="text" name="personal[name]" /><br />
Email: <input type="text" name="personal[email]" /><br />
Beer: <br />
<select multiple name="beer[]">
<option value="warthog">Warthog</option>
<option value="guinness">Guinness</option>
<option value="stuttgarter">Stuttgarter Schwabenbräu</option>
</select><br />
<input type="submit" value="Validez moi !" />
</form>
]]>
</programlisting>
</example>
</para>
<note>
<simpara>
Si le nom d'une variable externe commence par une syntaxe valide pour un tableau, les caractères qui suivent
sont silencieusement ignorés. Par example : <literal>&lt;input name="foo[bar]baz"&gt;</literal>
deviens <literal>$_REQUEST['foo']['bar']</literal>.
</simpara>
</note>
<sect3 xml:id="language.variables.external.form.submit">
<title>Nom de variables IMAGE de type SUBMIT</title>
<simpara>
Lors de la soumission d'un formulaire, il est possible d'utiliser
une image au lieu d'un bouton standard, comme ceci :
</simpara>
<informalexample>
<programlisting role="html">
<![CDATA[
<input type="image" src="image.gif" name="sub" />
]]>
</programlisting>
</informalexample>
<simpara>
Lorsque l'utilisateur clique sur cette image, le formulaire
associé est envoyé au serveur, avec deux données supplémentaires,
<varname>sub_x</varname> et <varname>sub_y</varname>. Elles contiennent
les coordonnées du clic de l'utilisateur dans l'image. Vous noterez
que ces variables sont envoyées par le navigateur avec un point dans leur
nom, mais PHP convertit ces points en soulignés.
</simpara>
</sect3>
</sect2>
<sect2 xml:id="language.variables.external.cookies">
<title>Cookies HTTP</title>
<simpara>
PHP supporte les cookies HTTP de manière totalement
transparente, comme défini dans la
<link xlink:href="&url.rfc;6265">RFC 6265</link>. Les cookies
sont un mécanisme permettant de stocker des données
sur la machine cliente à des fins d'identification de
l'utilisateur. Vous pouvez établir un cookie grâce à
la fonction <function>setcookie</function>. Les cookies
font partie intégrante des en-têtes HTTP et donc
la fonction <function>setcookie</function> doit être
appelée avant que le moindre affichage ne soit envoyé
au navigateur. C'est la même restriction que pour la fonction
<function>header</function>. Les données contenus dans les cookies
sont alors disponibles dans les tableaux de cookies appropriés, comme
<varname>$_COOKIE</varname> mais aussi <varname>$_REQUEST</varname>.
Lisez la page de la documentation sur la fonction
<function>setcookie</function> pour plus de détails ainsi que des exemples.
</simpara>
<note>
<simpara>
Depuis PHP 7.2.34, 7.3.23 et 7.4.11, respectivement, les
<emphasis>noms</emphasis> des cookies entrantes ne sont plus
url-décodés, et ce, pour des raisons de sécurité.
</simpara>
</note>
<simpara>
Si vous souhaitez assigner plusieurs valeurs à un seul
cookie, vous devez l'assigner sous forme de tableau.
Par exemple :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
setcookie("MyCookie[foo]", 'Test 1', time()+3600);
setcookie("MyCookie[bar]", 'Test 2', time()+3600);
?>
]]>
</programlisting>
</informalexample>
<simpara>
Cela va créer deux cookies distincts bien que <varname>MyCookie</varname>
est maintenant un simple tableau dans votre script. Si vous voulez définir
seulement un cookie avec plusieurs valeurs, utilisez la fonction
<function>serialize</function> ou <function>explode</function>
sur la première valeur.
</simpara>
<simpara>
Il est à noter qu'un cookie remplace le cookie
précédent par un cookie de même nom tant que
le chemin ou le domaine sont identiques.
Donc, pour une application de panier, vous devez implémenter
un compteur et l'incrémenter au fur et à mesure. C'est-à-dire :
</simpara>
<example>
<title>Exemple avec <function>setcookie</function></title>
<programlisting role="php">
<![CDATA[
<?php
if (isset($_COOKIE['compte'])) {
$compte = $_COOKIE['compte'] + 1;
} else {
$compte = 1;
}
setcookie('compte', $compte, time()+3600);
setcookie("Panier[$compte]", $item, time()+3600);
?>
]]>
</programlisting>
</example>
</sect2>
<sect2 xml:id="language.variables.external.dot-in-names">
<title>Cas des points dans les noms de variables</title>
<para>
Typiquement, PHP ne modifie pas les noms des variables lorsqu'elles
sont passées à un script. Cependant, il faut noter que
les points (.) ne sont pas autorisés dans les noms de variables
PHP. Pour cette raison, jetez un oeil sur :
<programlisting role="php">
<![CDATA[
<?php
$varname.ext; /* nom de variable invalide */
?>
]]>
</programlisting>
Dans ce cas, l'analyseur croit voir la variable nommée
<varname>$varname</varname>, suivie par l'opérateur de concaténation,
et suivie encore par la chaîne sans guillemets
(une chaîne sans guillemets et qui n'a pas de signification
particulière). Visiblement, ce n'est pas ce qu'on attendait...
</para>
<para>
Pour cette raison, il est important de noter que PHP remplacera
automatiquement les points des noms de variables entrantes par
des soulignés.
</para>
</sect2>
<sect2 xml:id="language.variables.determining-type-of">
<title>Détermination du type des variables</title>
<para>
Parce que PHP détermine le type des variables et
les convertit (généralement) comme il faut,
ce n'est pas toujours le type de variable que vous souhaitez.
PHP inclut des fonctions permettant de déterminer le
type d'une variable :
<function>gettype</function>,
<function>is_array</function>,
<function>is_float</function>,
<function>is_int</function>,
<function>is_object</function> et
<function>is_string</function>.
Lisez également le chapitre sur les
<link linkend="language.types">types</link>.
</para>
<para>
HTTP étant un protocole texte, la plupart, sinon tous, le contenu qui vient
dans les <link linkend="language.variables.superglobals">tableaux Superglobaux</link>,
comme <varname>$_POST</varname> et <varname>$_GET</varname> restera en tant
que chaînes. PHP n'essaiera pas de convertir des valeurs en un type spécifique.
Dans l'exemple ci-dessous, <varname>$_GET["var1"]</varname> contiendra la
chaîne "null" et <varname>$_GET["var2"]</varname>, la chaîne "123".
<programlisting>
<![CDATA[
/index.php?var1=null&var2=123
]]>
</programlisting>
</para>
</sect2>
<sect2 xml:id="language.variables.external.changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>7.2.34, 7.3.23, 7.4.11</entry>
<entry>
Les <emphasis>noms</emphasis> des cookies entrantes ne sont plus
url-décodés, et ce, pour des raisons de sécurité.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->