Files
doc-fr/language/variables.xml
2024-10-12 16:12:56 +01:00

1181 lines
34 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: b7dbf6357d4c2d68ffb52158076f692ed532b546 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>
Un nom de variable valide commence par une lettre
(<literal>A-Z</literal>, <literal>a-z</literal>, ou les octets de 128 à 255)
ou par un tiret bas, suivi 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>
PHP ne prend pas en charge les noms de variables Unicode, cependant, certains
encodages de caractères (comme UTF-8) encodent les caractères de manière
à ce que tous les octets d'un caractère multi-octet soient dans la plage
autorisée, ce qui en fait ainsi un nom de variable valide.
</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 (c.à.d. en utilisant
<link linkend="language.variables.variable">les variables variables</link>)
était impossible.
</simpara>
</note>
&tip.userlandnaming;
<example>
<title>Noms de variables valides et invalides</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>
<simpara>
PHP accepte une séquence de n'importe quels octets comme nom de variable.
Les noms de variables qui ne respectent pas les règles de nommage mentionnées ci-dessus
ne peuvent être accédés que dynamiquement à l'exécution. Voir
<link linkend="language.variables.variable">variables variables</link>
pour plus d'informations sur la façon d'y accéder.
</simpara>
<example>
<title>Accéder à des noms de variables inhabituels</title>
<programlisting role="php">
<![CDATA[
<?php
${'nom-invalide'} = 'bar';
$nom = 'nom-invalide';
echo ${'nom-invalide'}, " ", $$nom;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
bar bar
]]>
</screen>
</example>
<para>
Les variables sont toujours assignées par valeur.
C'est-à-dire, lorsqu'une expression est affectée à 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
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(); // invalide car test() ne retourne pas une variable par référence.
.
?>
]]>
</programlisting>
</example>
</para>
<para>
Il n'est pas nécessaire de déclarer des variables en PHP, cependant, c'est une très
bonne pratique. Accéder à une variable non définie entraînera un
<constant>E_WARNING</constant> (avant PHP 8.0.0, <constant>E_NOTICE</constant>).
Une variable non définie a une valeur par défaut de &null;.
Le langage <function>isset</function> peut être utilisé
pour détecter si une variable a déjà été initialisée.
</para>
<para>
<example>
<title>Valeur par défaut d'une variable non initialisée</title>
<programlisting role="php">
<![CDATA[
<?php
// Une variable non initialisée et non référencée (pas de contexte d'utilisation).
var_dump($unset_var);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Warning: Undefined variable $unset_var in ...
NULL
]]>
</screen>
</example>
</para>
<simpara>
PHP permet l'autovivification de tableaux (création automatique de nouveaux tableaux)
à partir d'une variable non définie.
Ajouter un élément à une variable non définie créera un nouveau tableau et
ne générera pas d'avertissement.
</simpara>
<example>
<title>Autovivification d'un tableau à partir d'une variable non définie</title>
<programlisting role="php">
<![CDATA[
<?php
$unset_array[] = 'valeur'; // Ne génère pas d'avertissement.
?>
]]>
</programlisting>
</example>
<warning>
<simpara>
Compter sur la valeur par défaut d'une variable non initialisée est problématique
lorsqu'un fichier inclus dans un autre utilise le même
nom de variable.
</simpara>
</warning>
<simpara>
Pour plus d'informations sur les fonctions liées aux variables, consultez la
<link linkend="ref.var">Référence des fonctions sur les variables</link>.
</simpara>
</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 est le contexte dans lequel elle est définie.
Pour la plupart, toutes les variables PHP n'ont qu'une seule portée.
Cette portée unique englobe les fichiers inclus avec les fonctions
<function>include</function> et <function>require</function>. 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>
Ce génèrera un diagnostic <constant>E_WARNING</constant>
(ou <constant>E_NOTICE</constant> antérieur à PHP 8.0.0) de variable non définit.
Cependant, si le paramètre INI
<link linkend="ini.display-errors">display_errors</link>
est défini pour cacher ces diagnostics alors rien du tout sera affiché.
La raison pour cela est que
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. Notez 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 de l'écriture une fonction
récursive, car il est facile de faire une boucle infinie.
Il faut vérifier qu'il y a une condition qui
permet de terminer la 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>
Avant PHP 8.3.0, une variable statique ne pouvait être initialisée qu'en utilisant
une expression constante. Depuis PHP 8.3.0, les expressions dynamiques
(par exemple, les appels de fonction) sont également autorisées :
</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); // correct à partir de PHP 8.3.0
$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
dorénavant 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>
</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
<literal>&amp;get_instance_ref()</literal> est appelé 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 d'utiliser des variables variables avec des tableaux,
un problème d'ambiguïté doit être résolu. En effet, si l'analyseur rencontre
<varname>$$a[1]</varname>, il doit déterminer si
<varname>$a[1]</varname> devait être utilisé comme une variable, ou si
<varname>$$a</varname> était attendu comme la variable, suivi de l'indice <literal>[1]</literal>
de cette variable. 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 il y a 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
les variables prédéfinies de GET peuvent être utilisées à 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>.
Voir 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>).
Par exemple, des variables peuvent être groupés ensemble ou cette
fonctionnalité peut être utilisée 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 exemple : <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. Il est possible d'é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 contenues 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 entrants ne sont plus
url-décodés, et ce, pour des raisons de sécurité.
</simpara>
</note>
<simpara>
Si plusieurs valeurs peuvent être assignées à un seul
cookie, ils peuvent être assignées 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 le script. Si seulement un cookie
doit être défini 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,
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 œil 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 entrants 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
-->