mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-26 01:42:09 +01:00
574 lines
17 KiB
XML
574 lines
17 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: fe18943c11c6fe9be88688574153013ff249452d 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 : vous ne pouvez pas effectuer d'opération arithmétique de pointeurs
|
|
sur celles-ci, ce ne sont pas des adresses mémoires, etc.
|
|
Vous pouvez consulter
|
|
<xref linkend="language.references.arent" /> pour plus d'informations.
|
|
En fait, les références sont des alias dans la table des symboles.
|
|
Notez 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 leur 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 vous assignez, passez, ou retournez, 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 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>.
|
|
Tant bien que les objets sont passés comme des pointeurs, ceci n'est pas
|
|
identique au références comm expliqué dans la section les
|
|
<link linkend="language.oop5.references">Objets et références</link>.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
Si vous assignez une référence à 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.
|
|
Vous pouvez é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>
|
|
Voyez <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 vous assignez une valeur à 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>
|
|
Notez 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 à un 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, vous pouvez 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 table de symboles de l'appelant).
|
|
Vous pouvez 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>
|
|
Vous pouvez 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 un 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 vous
|
|
voulez utiliser une fonction pour déterminer à quelle variable
|
|
une référence devrait être liée.
|
|
N'utilisez <emphasis>pas</emphasis>
|
|
le retour par référence pour améliorer les performances,
|
|
le moteur est suffisamment robuste pour optimiser cela
|
|
en interne. Retournez des références uniquement
|
|
lorsque vous avez de bonnes raisons techniques
|
|
de le faire ! Pour retourner des références, utilisez 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, vous devez utiliser
|
|
<literal>&</literal> aux deux endroits, à la fois pour
|
|
indiquer que vous retournez par référence (pas par copie), et
|
|
pour indiquer que vous assignez aussi par référence (pas par copie
|
|
non plus) pour la variable <varname>$myValue</varname>.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<simpara>
|
|
Si vous tentez de retourner une référence depuis une fonction
|
|
avec la syntaxe : <literal>return ($this->value);</literal>,
|
|
cela ne fonctionnera <emphasis>pas</emphasis> comme
|
|
vous l'attendez, et retournera le résultat de l'<emphasis>expression</emphasis>,
|
|
et pas de la variable, par référence. Vous ne pouvez retourner que
|
|
des variables par référence depuis une fonction - et rien d'autre.
|
|
</simpara>
|
|
</note>
|
|
<para>
|
|
Pour utiliser la référence retournée, vous devez utiliser l'affectation
|
|
par référence :
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function &collector() {
|
|
static $collection = array();
|
|
return $collection;
|
|
}
|
|
$collection = &collector();
|
|
$collection[] = 'foo';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Pour passer la référence retournée à une autre fonction attendant une référence,
|
|
vous pouvez 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>
|
|
Notez 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>
|
|
Lorsque vous détruisez une référence, vous ne
|
|
faites 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>
|
|
Lorsque vous déclarez une variable en tant que <command>global $var</command>,
|
|
vous créez 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'entrainera
|
|
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:
|
|
-->
|