mirror of
https://github.com/php/doc-fr.git
synced 2026-03-23 22:52:18 +01:00
640 lines
18 KiB
XML
640 lines
18 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- $Revision$ -->
|
||
<!-- EN-Revision: 9463e5b660c4883b91a30f07ff68731bbcc48346 Maintainer: jpauli Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<!-- CREDITS: DAnnebicque -->
|
||
|
||
<chapter xml:id="language.references" xmlns="http://docbook.org/ns/docbook">
|
||
<title>Les références</title>
|
||
<sect1 xml:id="language.references.whatare">
|
||
<title>Qu'est-ce qu'une référence ?</title>
|
||
<simpara>
|
||
En PHP, les références sont un moyen d'accéder au contenu d'une même
|
||
variable en utilisant plusieurs noms. Les références ne sont pas comme des
|
||
pointeurs en C : il n'est pas possible d'effectuer d'opération arithmétique de pointeurs
|
||
sur celles-ci, ce ne sont pas des adresses mémoires, etc.
|
||
Consulter
|
||
<xref linkend="language.references.arent" /> pour plus d'informations.
|
||
En fait, les références sont des alias dans la
|
||
<link linkend="features.gc.refcounting-basics">table des symboles</link>.
|
||
Il est à noter qu'en PHP, le nom d'une variable et son contenu sont deux
|
||
notions distinctes, ce qui fait que l'on peut donner
|
||
plusieurs noms au même contenu.
|
||
On peut faire l'analogie avec les fichiers sous Unix, et leurs noms :
|
||
les noms des variables sont les entrées dans un répertoire, tandis
|
||
que le contenu de la variable est le fichier en lui-même.
|
||
Les références en PHP peuvent alors être considérées comme semblables
|
||
aux liens sous Unix.
|
||
</simpara>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="language.references.whatdo">
|
||
<title>Que font les références ?</title>
|
||
<para>
|
||
Il existe trois principales utilisations des références :
|
||
l'<link linkend="language.references.whatdo.assign">assignation par
|
||
référence</link>, le <link linkend="language.references.whatdo.pass">passage
|
||
par référence</link>
|
||
et le <link linkend="language.references.whatdo.return">retour par
|
||
référence</link>. Cette section va introduire ces opérations, avec des liens
|
||
vers plus de précisions.
|
||
</para>
|
||
<sect2 xml:id="language.references.whatdo.assign">
|
||
<title>Assignation par référence</title>
|
||
<para>
|
||
Dans ce premier cas, les références PHP permettent de faire en
|
||
sorte que deux variables référencent le même contenu.
|
||
Par exemple :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$a =& $b;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Cette écriture indique que <varname>$a</varname> et <varname>$b</varname>
|
||
pointent sur le même contenu.
|
||
<note>
|
||
<para>
|
||
<varname>$a</varname> et <varname>$b</varname> sont complètement
|
||
égales ici : ce n'est pas <varname>$a</varname> qui pointe sur
|
||
<varname>$b</varname>, ou vice-versa. Ce sont bien <varname>$a</varname>
|
||
et <varname>$b</varname> qui pointent sur le même contenu.
|
||
</para>
|
||
</note>
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Si l'on assigne, passe, ou retourne, une variable indéfinie par référence,
|
||
elle sera créée automatiquement.
|
||
<example>
|
||
<title>Utilisation des références avec des variables indéfinies</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function foo(&$var) {}
|
||
|
||
foo($a); // $a est "créée" et assignée à NULL
|
||
|
||
$b = array();
|
||
foo($b['b']);
|
||
var_dump(array_key_exists('b', $b)); // bool(true)
|
||
|
||
$c = new stdClass();
|
||
foo($c->d);
|
||
var_dump(property_exists($c, 'd')); // bool(true)
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
</note>
|
||
<para>
|
||
La même syntaxe peut être utilisée avec les fonctions qui
|
||
retournent des références :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$foo =& find_var($bar);
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<para>
|
||
Utiliser la même syntaxe avec une fonction qui <emphasis>ne</emphasis>
|
||
retourne pas par référence génèrera une erreur, comme l'utiliser avec le
|
||
résultat de l'opérateur <link linkend="language.oop5.basic.new">new</link>.
|
||
Bien que les objets soient passés comme des pointeurs, ceci n'est pas
|
||
identique aux références comme expliqué dans la section les
|
||
<link linkend="language.oop5.references">Objets et références</link>.
|
||
</para>
|
||
<warning>
|
||
<para>
|
||
Si une référence est assignée à une variable déclarée comme <literal>global</literal>
|
||
dans une fonction, la référence ne sera visible qu'au sein de la fonction.
|
||
Il est possible d'éviter cela en utilisant le tableau <varname>$GLOBALS</varname>.
|
||
<example>
|
||
<title>Référencer des variables globales depuis des fonctions</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$var1 = "Variable Exemple";
|
||
$var2 = "";
|
||
|
||
function global_references($use_globals)
|
||
{
|
||
global $var1, $var2;
|
||
|
||
if (!$use_globals) {
|
||
$var2 =& $var1; // visible uniquement dans la fonction
|
||
} else {
|
||
$GLOBALS["var2"] =& $var1; // visible également dans le contexte global
|
||
}
|
||
}
|
||
|
||
global_references(false);
|
||
echo "var2 est défini à '$var2'\n"; // var2 est défini à ''
|
||
|
||
global_references(true);
|
||
echo "var2 est défini à '$var2'\n"; // var2 est défini à 'Variable Exemple'
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
Considérer <literal>global $var;</literal> comme un raccourci pour <literal>$var
|
||
=& $GLOBALS['var'];</literal>. De ce fait, assigner une autre référence à
|
||
<literal>$var</literal> modifie uniquement la référence locale de la variable.
|
||
</para>
|
||
</warning>
|
||
<note>
|
||
<para>
|
||
Si une valeur est assignée à une variable qui a des références dans une structure
|
||
&foreach;, les références seront également modifiées.
|
||
<example>
|
||
<title>Références et structure foreach</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$ref = 0;
|
||
$row =& $ref;
|
||
|
||
foreach (array(1, 2, 3) as $row) {
|
||
// faites quelque chose
|
||
}
|
||
|
||
echo $ref; // 3 - le dernier élément du tableau itéré
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
</note>
|
||
<para>
|
||
Même si ce n'est pas strictement une assignation par référence, les expressions
|
||
créées avec la structure de langage
|
||
<link linkend="function.array"><literal>array()</literal></link> peuvent aussi
|
||
se comporter comme telles, en préfixant par <literal>&</literal> l'élément du tableau.
|
||
Voici un exemple :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$a = 1;
|
||
$b = array(2, 3);
|
||
$arr = array(&$a, &$b[0], &$b[1]);
|
||
$arr[0]++;
|
||
$arr[1]++;
|
||
$arr[2]++;
|
||
/* $a == 2, $b == array(3, 4); */
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<para>
|
||
Il est à noter par contre que les références à l'intérieur des tableaux peuvent s'avérer
|
||
dangereuses. Utiliser une assignation normale (pas par référence) avec une
|
||
référence à droite de l'opérateur ne transforme pas la partie gauche de l'assignation
|
||
en référence, mais les références à l'intérieur des tableaux sont préservées. Ceci
|
||
s'applique également aux appels de fonctions avec un tableau passé par valeur.
|
||
Exemple :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
/* Assignation de variables scalaires */
|
||
$a = 1;
|
||
$b =& $a;
|
||
$c = $b;
|
||
$c = 7; // $c n'est pas une référence ; pas de changement à $a ou $b
|
||
|
||
/* Assignation de variables de type tableau */
|
||
$arr = array(1);
|
||
$a =& $arr[0]; // $a et $arr[0] sont des références vers la même valeur
|
||
$arr2 = $arr; // PAS une assignation par référence!
|
||
$arr2[0]++;
|
||
/* $a == 2, $arr == array(2) */
|
||
/* Les contenus de $arr sont changés même si ce n'était pas une référence ! */
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Autrement dit, d'un point de vue des références, le comportement des tableaux
|
||
est défini élément par élément ; le comportement de chaque élément
|
||
est indépendant du statut de référence du tableau qui les contient.
|
||
</para>
|
||
</sect2>
|
||
<sect2 xml:id="language.references.whatdo.pass">
|
||
<title>Passage par référence</title>
|
||
<para>
|
||
Le deuxième intérêt des références est de
|
||
permettre de passer des variables par référence. On réalise ceci en faisant
|
||
référencer le même contenu par une variable locale à une fonction et par une
|
||
variable du contexte appelant.
|
||
Par exemple :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function foo(&$var) {
|
||
$var++;
|
||
}
|
||
$a=5;
|
||
foo($a);
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Après l'exécution de cette portion de code, <varname>$a</varname> vaut 6.
|
||
Cela provient du fait que, dans la fonction <varname>foo</varname>, la
|
||
variable <varname>$var</varname> pointe sur le même contenu que
|
||
<varname>$a</varname>.
|
||
Pour plus d'informations à ce sujet, consulter la section
|
||
<link linkend="language.references.pass">passage par référence</link>.
|
||
</para>
|
||
</sect2>
|
||
<sect2 xml:id="language.references.whatdo.return">
|
||
<title>Retour par référence</title>
|
||
<para>
|
||
Le troisième intérêt des références est de permettre le
|
||
<link linkend="language.references.return">retour de valeurs par
|
||
référence</link>.
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="language.references.arent">
|
||
<title>Ce que les références ne sont pas</title>
|
||
<para>
|
||
Comme nous l'avons vu précédemment, les références ne
|
||
sont pas des pointeurs. Cela signifie que le script suivant ne fera pas
|
||
ce à quoi on peut s'attendre :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function foo(&$var) {
|
||
$var =& $GLOBALS["baz"];
|
||
}
|
||
|
||
foo($bar);
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<simpara>
|
||
Ici, la variable <varname>$var</varname> dans la fonction <varname>foo</varname> sera liée
|
||
à <varname>$bar</varname> dans l'appelant, mais elle sera ensuite reliée à
|
||
<varname>$GLOBALS["baz"]</varname>.
|
||
Il n'est pas possible de lier <varname>$bar</varname> à quelque chose d'autre en utilisant
|
||
le mécanisme de références, car <varname>$bar</varname> n'est pas accessible dans la
|
||
fonction <varname>foo</varname> (certes, elle est représentée par <varname>$var</varname>,
|
||
mais <varname>$var</varname> ne fait référence qu'à la valeur, et n'a pas de liaison dans
|
||
la <link linkend="features.gc.refcounting-basics">table de symboles</link> de l'appelant).
|
||
Il est possible d'utiliser le <link linkend="language.references.return">retour par
|
||
référence</link> pour référencer des variables sélectionnées par la fonction.
|
||
</simpara>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="language.references.pass">
|
||
<title>Passage par référence</title>
|
||
<para>
|
||
Il est possible de passer une variable par référence à une fonction, de
|
||
manière à ce que celle-ci puisse la modifier.
|
||
La syntaxe est la suivante :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function foo(&$var) {
|
||
$var++;
|
||
}
|
||
$a=5;
|
||
|
||
foo ($a);
|
||
// $a vaut 6 maintenant
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<note>
|
||
<simpara>
|
||
Il n'y a pas de signe de référence dans l'appel de la
|
||
fonction, uniquement sur sa définition. La définition de la
|
||
fonction en elle-même est suffisante pour passer correctement
|
||
des arguments par référence.
|
||
</simpara>
|
||
</note>
|
||
</para>
|
||
<para>
|
||
Les données suivantes peuvent être passées par référence :
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Une variable, comme dans <literal>foo($a)</literal>
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Une référence retournée par une fonction :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function foo(&$var)
|
||
{
|
||
$var++;
|
||
}
|
||
|
||
function &bar()
|
||
{
|
||
$a = 5;
|
||
return $a;
|
||
}
|
||
|
||
foo(bar());
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Pour plus d'informations, voir les détails dans
|
||
<link linkend="language.references.return">retour par
|
||
référence</link>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Toutes les autres expressions ne doivent pas être passées par
|
||
référence, car le résultat sera indéfini. Par exemple,
|
||
les passages par référence suivants sont invalides :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function foo(&$var)
|
||
{
|
||
$var++;
|
||
}
|
||
|
||
function bar() // Notez l'absence de &
|
||
{
|
||
$a = 5;
|
||
return $a;
|
||
}
|
||
|
||
foo(bar()); // Produit une notice
|
||
|
||
foo($a = 5); // Expression, pas une variable
|
||
foo(5); // Produit une erreur fatale
|
||
|
||
class Foobar{}
|
||
|
||
foo(new Foobar()) // Produit une notice depuis PHP 7.0.7
|
||
// Notice: Seules les variables devraient être passées par référence.
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="language.references.return">
|
||
<title>Retourner des références</title>
|
||
<para>
|
||
Retourner des références est utile lorsque l'on
|
||
souhaite utiliser une fonction pour déterminer à quelle variable
|
||
une référence devrait être liée.
|
||
Il ne faut <emphasis>pas</emphasis> utiliser
|
||
le retour par référence pour améliorer les performances,
|
||
le moteur est suffisamment robuste pour optimiser cela
|
||
en interne. Il convient de ne retourner des références que
|
||
lorsqu'il y a de bonnes raisons techniques
|
||
de le faire. Pour retourner des références, utiliser cette syntaxe :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class Foo
|
||
{
|
||
public $value = 42;
|
||
|
||
public function &getValue()
|
||
{
|
||
return $this->value;
|
||
}
|
||
}
|
||
|
||
$obj = new Foo();
|
||
$myValue = &$obj->getValue(); // $myValue est une référence de $obj->value, qui vaut 42.
|
||
$obj->value = 2;
|
||
echo $myValue; // affiche la nouvelle valeur de $obj->value, i.e. 2.
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Dans cet exemple, on affecte une valeur à la propriété de l'objet
|
||
retourné par la fonction <varname>getValue</varname>, et non à sa copie,
|
||
comme ce serait le cas si nous n'avions pas utilisé la syntaxe de référence.
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
Contrairement au passage de paramètre, ici, il faut utiliser
|
||
<literal>&</literal> aux deux endroits, à la fois pour
|
||
indiquer le retour par référence (pas par copie), et
|
||
pour indiquer l'assignation aussi par référence (pas par copie
|
||
non plus) pour la variable <varname>$myValue</varname>.
|
||
</simpara>
|
||
</note>
|
||
<note>
|
||
<simpara>
|
||
Tenter de retourner une référence depuis une fonction
|
||
avec la syntaxe : <literal>return ($this->value);</literal>,
|
||
ne fonctionnera <emphasis>pas</emphasis> comme
|
||
attendu, et retournera le résultat de l'<emphasis>expression</emphasis>,
|
||
et pas de la variable, par référence. Seules
|
||
des variables peuvent être retournées par référence depuis une fonction - et rien d'autre.
|
||
</simpara>
|
||
</note>
|
||
<para>
|
||
Pour utiliser la référence retournée, il faut utiliser l'affectation
|
||
par référence :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function &collector()
|
||
{
|
||
static $collection = array();
|
||
return $collection;
|
||
}
|
||
|
||
$collection = &collector();
|
||
// Désormais, la variable $collection est une variable par référence qui référence le tableau static à l’intérieur de la fonction
|
||
|
||
$collection[] = 'foo';
|
||
|
||
print_r(collector());
|
||
// Array
|
||
// (
|
||
// [0] => foo
|
||
// )
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<note>
|
||
<simpara>
|
||
Si l'affectation est faite sans le symbole <literal>&</literal>,
|
||
par exemple <code>$collection = collector();</code>,
|
||
la variable <varname>$collection</varname> recevra une copie de la valeur,
|
||
et non la référence retournée par la fonction.
|
||
</simpara>
|
||
</note>
|
||
Pour passer la référence retournée à une autre fonction attendant une référence,
|
||
il est possible d'utiliser la syntaxe suivante :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
function &collector()
|
||
{
|
||
static $collection = array();
|
||
return $collection;
|
||
}
|
||
|
||
array_push(collector(), 'foo');
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
Il est à noter que <literal>array_push(&collector(), 'foo');</literal>
|
||
<emphasis>ne fonctionnera pas</emphasis>, et résultera en une erreur
|
||
fatale.
|
||
</simpara>
|
||
</note>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="language.references.unset">
|
||
<title>Détruire une référence</title>
|
||
<para>
|
||
Lorsqu'une référence est détruite, cela ne
|
||
fait que casser le lien entre le nom de la variable et son contenu.
|
||
Cela ne signifie pas que le contenu de la variable est détruit.
|
||
Par exemple :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$a = 1;
|
||
$b =& $a;
|
||
unset($a);
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Cet exemple ne détruira pas <varname>$b</varname>, mais juste
|
||
<varname>$a</varname>.
|
||
</para>
|
||
<simpara>
|
||
Encore une fois, on peut comparer cette action avec l'appel
|
||
<command>unlink</command> d'Unix.
|
||
</simpara>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="language.references.spot">
|
||
<title>Repérer une référence</title>
|
||
<simpara>
|
||
De nombreuses syntaxes de PHP sont implémentées via le
|
||
mécanisme de référence, et tout ce qui a
|
||
été vu concernant les liaisons entre variables
|
||
s'applique à ces syntaxes. Certaines constructions, comme le passage
|
||
d'arguments et le retour par référence, ont été mentionnées plus haut.
|
||
D'autres constructions qui utilisent les références sont les suivantes :
|
||
</simpara>
|
||
|
||
<sect2 xml:id="references.global">
|
||
<title>Références globales</title>
|
||
<para>
|
||
Lorsqu'une variable est déclarée en tant que <command>global $var</command>,
|
||
cela crée en fait une référence sur une variable
|
||
globale. Autrement dit, cela revient au même que :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$var =& $GLOBALS["var"];
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<simpara>
|
||
Cela signifie aussi que détruire la variable <varname>$var</varname> n'entraînera
|
||
pas la destruction de la variable globale.
|
||
</simpara>
|
||
</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:
|
||
-->
|