mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-24 08:52:09 +01:00
1745 lines
48 KiB
XML
1745 lines
48 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 74976cdb263ef841c5fc2c3f91ca7e284adce552 Maintainer: yannick Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<chapter xml:id="language.functions" xmlns="http://docbook.org/ns/docbook">
|
||
<title>Les fonctions</title>
|
||
|
||
<sect1 xml:id="functions.user-defined">
|
||
<title>Les fonctions définies par l'utilisateur</title>
|
||
|
||
<para>
|
||
Une fonction peut être définie en utilisant la syntaxe suivante :
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Pseudo code pour illustrer l'usage d'une fonction</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
|
||
{
|
||
echo "Exemple de fonction.\n";
|
||
return $retval;
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<simpara>
|
||
Tout code PHP, correct syntaxiquement, peut apparaître
|
||
dans une fonction et dans des définitions de
|
||
<link linkend="language.oop5.basic.class">classe</link>.
|
||
</simpara>
|
||
<para>
|
||
Les noms de fonctions suivent les mêmes règles que les autres labels en PHP.
|
||
Un nom de fonction valide commence par une lettre ou un souligné, suivi
|
||
par un nombre quelconque de lettres, de nombres ou de soulignés.
|
||
Ces règles peuvent être représentées par l'expression rationnelle suivante :
|
||
<code>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</code>
|
||
</para>
|
||
&tip.userlandnaming;
|
||
<simpara>
|
||
Les fonctions n'ont pas besoin d'être définies avant d'être utilisées,
|
||
<emphasis>SAUF</emphasis> lorsqu'une fonction est définie
|
||
conditionnellement, comme montré dans les deux exemples suivants.
|
||
</simpara>
|
||
<para>
|
||
Lorsqu'une fonction est définie de manière conditionnelle, comme dans
|
||
les exemples ci-dessous, leur définition doit <emphasis>précéder</emphasis>
|
||
leur utilisation.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Fonctions conditionnelles</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$makefoo = true;
|
||
|
||
/* Impossible d'appeler foo() ici,
|
||
car cette fonction n'existe pas.
|
||
Mais nous pouvons utiliser bar() */
|
||
|
||
bar();
|
||
|
||
if ($makefoo) {
|
||
function foo()
|
||
{
|
||
echo "Je n'existe pas tant que le programme n'est pas passé ici.\n";
|
||
}
|
||
}
|
||
|
||
/* Maintenant, nous pouvons appeler foo()
|
||
car $makefoo est évalué à vrai */
|
||
|
||
if ($makefoo) foo();
|
||
|
||
function bar()
|
||
{
|
||
echo "J'existe dès le début du programme.\n";
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Fonctions dans une autre fonction</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo()
|
||
{
|
||
function bar()
|
||
{
|
||
echo "Je n'existe pas tant que foo() n'est pas appelé.\n";
|
||
}
|
||
}
|
||
|
||
/* Impossible d'appeler bar() ici
|
||
car il n'existe pas. */
|
||
|
||
foo();
|
||
|
||
/* Maintenant, nous pouvons appeler bar(),
|
||
car l'utilisation de foo() l'a rendue
|
||
accessible. */
|
||
|
||
bar();
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Toutes les fonctions et classes en PHP ont une portée globale - elles
|
||
peuvent être appelées à l'extérieur d'une fonction si elles ont été définies
|
||
à l'intérieur et vice-versa.
|
||
</para>
|
||
<simpara>
|
||
PHP ne supporte pas la surcharge, la destruction et la redéfinition de
|
||
fonctions déjà déclarées.
|
||
</simpara>
|
||
<note>
|
||
<simpara>
|
||
Les noms de fonctions sont insensibles à la casse pour les caractères ASCII
|
||
<literal>A</literal> à <literal>Z</literal>,
|
||
et il est généralement admis que les fonctions doivent
|
||
être appelées avec le nom utilisé dans leur déclaration,
|
||
y compris la casse.
|
||
</simpara>
|
||
</note>
|
||
<simpara>
|
||
Les <link linkend="functions.variable-arg-list">
|
||
listes variables d'arguments de fonction</link> et les
|
||
<link linkend="functions.arguments.default">valeurs par défaut
|
||
d'arguments</link> sont supportés : voir
|
||
les fonctions de références que sont
|
||
<function>func_num_args</function>,
|
||
<function>func_get_arg</function>, et
|
||
<function>func_get_args</function> pour plus d'informations.
|
||
</simpara>
|
||
<para>
|
||
Il est possible d'appeler des fonctions récursives en PHP.
|
||
<example>
|
||
<title>Fonctions récursives</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function recursion($a)
|
||
{
|
||
if ($a < 20) {
|
||
echo "$a\n";
|
||
recursion($a + 1);
|
||
}
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<note>
|
||
<simpara>
|
||
Les appels de méthodes/fonctions récursives avec 100-200 degrés de
|
||
récursivité peuvent remplir la pile et ainsi, terminer le script courant.
|
||
À noter qu'une récursion infinie est considérée comme une erreur de
|
||
programmation.
|
||
</simpara>
|
||
</note>
|
||
</para>
|
||
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.arguments">
|
||
<title>Les arguments de fonction</title>
|
||
<simpara>
|
||
Des informations peuvent être passées à
|
||
une fonction en utilisant une liste d'arguments, dont chaque
|
||
expression est séparée par une virgule. Les arguments seront
|
||
évalués depuis la gauche vers la droite, avant que la fonction soit
|
||
actuellement appelée (évaluation <emphasis>immédiate</emphasis>).
|
||
</simpara>
|
||
<para>
|
||
PHP supporte le passage d'arguments par valeur (comportement par défaut), <link
|
||
linkend="functions.arguments.by-reference">le passage par référence</link>, et <link
|
||
linkend="functions.arguments.default">des valeurs d'arguments par défaut</link>.
|
||
Une <link linkend="functions.variable-arg-list">liste variable d'arguments</link>,
|
||
ainsi que les <link linkend="functions.named-arguments">Arguments Nommés</link>
|
||
sont également supportés.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Nombre variable d'arguments sous forme de tableau</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function takes_array($input)
|
||
{
|
||
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
À partir de PHP 8.0.0, la liste des arguments de fonction peut inclure une
|
||
virgule trainante, qui sera ignoré. Ceci est particulièrement pratique dans
|
||
les cas où la liste d'arguments est longue ou contient des noms de variables
|
||
longs, le rendant pratique pour lister les arguments verticalement.
|
||
</para>
|
||
<example>
|
||
<title>Function Argument List with trailing Comma</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function takes_many_args(
|
||
$first_arg,
|
||
$second_arg,
|
||
$a_very_long_argument_name,
|
||
$arg_with_default = 5,
|
||
$again = 'a default string', // Cette virgule trainant n'était pas permit avant 8.0.0.
|
||
)
|
||
{
|
||
// ...
|
||
}
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<sect2 xml:id="functions.arguments.by-reference">
|
||
<title>Passage d'arguments par référence</title>
|
||
|
||
<simpara>
|
||
Par défaut, les arguments sont passés
|
||
à la fonction par valeur (aussi, changer la valeur d'un argument dans la fonction ne
|
||
change pas sa valeur à l'extérieur de la fonction). Si vous voulez que vos fonctions
|
||
puissent changer la valeur des arguments, vous devez passer ces arguments par référence.
|
||
</simpara>
|
||
<para>
|
||
Si vous voulez qu'un argument soit toujours passé
|
||
par référence, vous pouvez ajouter un '<literal>&</literal>'
|
||
devant l'argument dans la déclaration de la fonction :
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Passage d'arguments par référence</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function add_some_extra(&$string)
|
||
{
|
||
$string .= ', et un peu plus.';
|
||
}
|
||
$str = 'Ceci est une chaîne';
|
||
add_some_extra($str);
|
||
echo $str; // Affiche : 'Ceci est une chaîne, et un peu plus.'
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
C'est une erreur de passer une valeur en tant qu'argument qui est supposé d'être passé par référence.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="functions.arguments.default">
|
||
<title>Valeur par défaut des arguments</title>
|
||
|
||
<para>
|
||
Une fonction peut définir des valeurs par défaut pour les arguments en utilisant une syntaxe similaire à l'affectation d'une variable.
|
||
La valeur par défaut n'est utilisée que lorsque le paramètre n'est pas spécifié ;
|
||
en particulier, notez que le passage de &null; n'assigne <emphasis>pas</emphasis> la valeur par défaut.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Valeur par défaut des arguments de fonctions</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function servir_cafe ($type = "cappuccino")
|
||
{
|
||
return "Servir un $type.\n";
|
||
}
|
||
echo servir_cafe();
|
||
echo servir_cafe(null);
|
||
echo servir_cafe("espresso");
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Servir un cappuccino.
|
||
Servir un .
|
||
Servir un espresso.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Les valeurs par défaut des paramètres peuvent être des valeurs scalaires,
|
||
des &array;s, le type spécial &null;, et à partir de PHP 8.1.0,
|
||
des objets utilisant la syntaxe <link linkend="language.oop5.basic.new">new ClassName()</link>.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Utilisation de type non-scalaire comme valeur par défaut</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function servir_cafe($types = array("cappuccino"), $coffeeMaker = NULL)
|
||
{
|
||
$device = is_null($coffeeMaker) ? "les mains" : $coffeeMaker;
|
||
return "Préparation d'une tasse de ".join(", ", $types)." avec $device.\n";
|
||
}
|
||
echo servir_cafe();
|
||
echo servir_cafe(array("cappuccino", "lavazza"), "une cafetière");
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Préparation d'une tasse de cappuccino avec les mains.
|
||
Préparation d'une tasse de cappuccino, lavazza avec une cafetière.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Utilisation d'objets comme valeurs par défaut (à partir de PHP 8.1.0)</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
class DefaultCoffeeMaker {
|
||
public function brew() {
|
||
return 'Faire du café.\n';
|
||
}
|
||
}
|
||
class FancyCoffeeMaker {
|
||
public function brew() {
|
||
return 'Créer un beau café rien que pour vous.\n';
|
||
}
|
||
}
|
||
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
|
||
{
|
||
return $coffeeMaker->brew();
|
||
}
|
||
echo makecoffee();
|
||
echo makecoffee(new FancyCoffeeMaker);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Faire du café.
|
||
Créer un beau café rien que pour vous.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
La valeur par défaut d'un argument doit
|
||
obligatoirement être une constante, et ne peut être
|
||
ni une variable, ni un membre de classe, ni un appel de fonction.
|
||
</simpara>
|
||
<para>
|
||
Il est à noter que tous les arguments facultatifs doivent être spécifiés après les arguments obligatoires,
|
||
sinon ils ne peuvent pas être omis dans les appels.
|
||
Considérons le code suivant :
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Les arguments sans valeur par défaut doivent être en premiers : erreur</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function faireunyaourt ($container = "bol", $flavour)
|
||
{
|
||
return "Préparer un $container de yaourt à la $flavour.\n";
|
||
}
|
||
|
||
echo faireunyaourt("framboise"); // "framboise" est $container, pas $flavour
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Fatal error: Uncaught ArgumentCountError: Too few arguments
|
||
to function faireunyaourt(), 1 passed in example.php on line 42
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Maintenant comparons l'exemple précédent avec l'exemple suivant :
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Les arguments sans valeur par défaut doivent être en premiers : valide</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function faireunyaourt ($flavour, $container = "bol")
|
||
{
|
||
return "Préparer un $container de yaourt à la $flavour.\n";
|
||
}
|
||
|
||
echo faireunyaourt ("framboise"); // "framboise" est $flavour
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Préparer un bol de yaourt à la framboise.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
À partir de PHP 8.0.0, les <link linkend="functions.named-arguments">arguments nommés</link>
|
||
peuvent être utilisées pour passer outre plusieurs paramètres optionnels.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Utilisation correcte des arguments de fonction par défaut</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function faireunyaourt($container = "bol", $flavour = "framboise", $style = "Grec")
|
||
{
|
||
return "Préparer un $container de yaourt $style à la $flavour.\n";
|
||
}
|
||
echo faireunyaourt(style: "naturel");
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Préparer un bol de yaourt naturel à la framboise.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
À partir de PHP 8.0.0, déclarer des arguments obligatoires après des arguments optionnels est <emphasis>obsolète</emphasis>.
|
||
Ce problème peut généralement être résolu en abandonnant la valeur par défaut, puisqu'elle ne sera jamais utilisée.
|
||
Une exception à cette règle concerne les arguments de la forme <code>Type $param = null</code>,
|
||
où le &null; par défaut rend le type implicitement nullable.
|
||
Cet usage reste autorisé, bien qu'il soit recommandé d'utiliser
|
||
un <link linkend="language.types.declarations.nullable">type nullable</link> explicite à la place.
|
||
<example>
|
||
<title>Déclarer des arguments facultatifs après les arguments obligatoires</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo($a = [], $b) {} // Par défaut, non utilisé ; obsolète à partir de PHP 8.0.0.
|
||
function foo($a, $b) {} // Fonctionnement équivalent, pas de notice d’obsolescence
|
||
function bar(A $a = null, $b) {} // Toujours autorisé ; $a est obligatoire mais nullable.
|
||
function bar(?A $a, $b) {} // Recommandé
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
À partir de PHP 7.1.0, l'omission d'un paramètre qui ne spécifie pas une valeur par défaut lance
|
||
un <classname>ArgumentCountError</classname> ;
|
||
dans les versions précédentes, cela levait un avertissement.
|
||
</simpara>
|
||
</note>
|
||
<note>
|
||
<simpara>
|
||
Les arguments passés par référence peuvent avoir
|
||
une valeur par défaut.
|
||
</simpara>
|
||
</note>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="functions.variable-arg-list">
|
||
<title>Liste d'argument à nombre variable</title>
|
||
|
||
<simpara>
|
||
PHP supporte les arguments à nombre variable dans les
|
||
fonctions défini par l'utilisateur en utilisant le token
|
||
<literal>...</literal>.
|
||
</simpara>
|
||
|
||
<para>
|
||
La liste des arguments peut inclure le
|
||
token <literal>...</literal> pour indiquer que cette fonction accepte
|
||
un nombre variable d'arguments. Les arguments seront passés dans la variable
|
||
fournie sous forme d'un &array;:
|
||
|
||
<example>
|
||
<title>Utilisation de <literal>...</literal> pour accéder aux arguments variables</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function sum(...$numbers) {
|
||
$acc = 0;
|
||
foreach ($numbers as $n) {
|
||
$acc += $n;
|
||
}
|
||
return $acc;
|
||
}
|
||
|
||
echo sum(1, 2, 3, 4);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
10
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
<literal>...</literal> peut aussi être utilisé lors des appels de
|
||
fonctions pour extraire le &array; ou la variable
|
||
<classname>Traversable</classname> ou le littéral dans la liste d'arguments :
|
||
|
||
<example>
|
||
<title>Utilisation de <literal>...</literal> pour fournir des arguments</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function add($a, $b) {
|
||
return $a + $b;
|
||
}
|
||
|
||
echo add(...[1, 2])."\n";
|
||
|
||
$a = [1, 2];
|
||
echo add(...$a);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
3
|
||
3
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
Vous pouvez spécifier des arguments classiques avant le mot clé
|
||
<literal>...</literal>. Dans ce cas, seuls les arguments finaux
|
||
qui ne correspondent pas à un argument classique seront ajoutés
|
||
au tableau généré par <literal>...</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
Il est également possible d'ajouter une
|
||
<link linkend="language.types.declarations">déclaration de type</link>
|
||
avant le jeton <literal>...</literal>. Si ceci est présent,
|
||
alors tous les arguments capturés par <literal>...</literal>
|
||
doivent correspondre au type de paramètre.
|
||
|
||
<example>
|
||
<title>Transtypage d'arguments variables</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function total_intervals($unit, DateInterval ...$intervals) {
|
||
$time = 0;
|
||
foreach ($intervals as $interval) {
|
||
$time += $interval->$unit;
|
||
}
|
||
return $time;
|
||
}
|
||
|
||
$a = new DateInterval('P1D');
|
||
$b = new DateInterval('P2D');
|
||
echo total_intervals('d', $a, $b).' jours';
|
||
|
||
// Ceci échouera, car null n'est pas un objet DateInterval.
|
||
echo total_intervals('d', null);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
3 jours
|
||
Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
Pour finir, vous pouvez passer des arguments variables
|
||
<link linkend="functions.arguments.by-reference">par référence</link>
|
||
en préfixant le mot clé <literal>...</literal> d'un ET commercial
|
||
(<literal>&</literal>).
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="functions.named-arguments">
|
||
<title>Arguments Nommés</title>
|
||
|
||
<para>
|
||
PHP 8.0.0 introduit les arguments nommés comme extension aux paramètres
|
||
positionnels existant. Les arguments nommés permettent de passer les
|
||
arguments à une fonction en s'appuyant sur le nom du paramètre, au lieu de
|
||
la position du paramètre. Ceci documente automatiquement la signification
|
||
de l'argument, rend l'ordre des arguments indépendant et permet d'ignorer
|
||
les valeurs par défaut arbitrairement.
|
||
</para>
|
||
|
||
<para>
|
||
Les arguments nommés sont passés en préfixant la valeur avec le nom du
|
||
paramètre suivit d'un deux-points. Utiliser des mots-clés réservés comme
|
||
nom de paramètre est autorisé. Le nom du paramètre doit être un identifiant,
|
||
le spécifiant de façon dynamique n'est pas permis.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Syntaxe des arguments nommés</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
myFunction(paramName: $value);
|
||
array_foobar(array: $value);
|
||
|
||
// NON supporté.
|
||
function_name($variableStoringParamName: $value);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<example>
|
||
<title>Arguments positionnels comparés aux arguments nommés</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// Utilisant les arguments positionnels :
|
||
array_fill(0, 100, 50);
|
||
|
||
// Utilisant les arguments nommés :
|
||
array_fill(start_index: 0, count: 100, value: 50);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
L'ordre dans lequel les arguments nommés sont passés n'importe pas.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Même exemple que ci-dessus, mais avec un ordre de paramètre différent</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
array_fill(value: 50, count: 100, start_index: 0);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Les arguments nommés peuvent être combinés avec les arguments positionnels.
|
||
Auquel cas, les arguments nommés doivent venir après les arguments positionnels.
|
||
Il est aussi possible de spécifier seulement certains des arguments optionnels
|
||
d'une fonction, peu importe leur ordre.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Combiner les arguments nommés avec les arguments positionnels</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
htmlspecialchars($string, double_encode: false);
|
||
// Same as
|
||
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Passer le même paramètre plusieurs fois résulte en une Error exception.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Error émise quand un même paramètre est passé plusieurs fois</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo($param) { ... }
|
||
|
||
foo(param: 1, param: 2);
|
||
// Error: Named parameter $param overwrites previous argument
|
||
foo(1, param: 2);
|
||
// Error: Named parameter $param overwrites previous argument
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
À partir de PHP 8.1.0, il est possible d'utiliser des arguments nommés après avoir décompressé les arguments.
|
||
Un argument nommé <emphasis>ne doit pas</emphasis> écraser un argument déjà déballé.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Utiliser les arguments nommés après le déballage</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo($a, $b, $c = 3, $d = 4) {
|
||
return $a + $b + $c + $d;
|
||
}
|
||
var_dump(foo(...[1, 2], d: 40)); // 46
|
||
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46
|
||
var_dump(foo(...[1, 2], b: 20)); // Erreur fatale. Le paramètre nommé $b écrase l'argument précédent.
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.returning-values">
|
||
<title>Les valeurs de retour</title>
|
||
|
||
<para>
|
||
Les valeurs sont renvoyées en utilisant une
|
||
instruction de retour optionnelle. Tous les types de variables
|
||
peuvent être renvoyés, tableaux et objets compris. Cela fait
|
||
que la fonction finit son exécution immédiatement et passe
|
||
le contrôle à la ligne appelante. Voir
|
||
<function>return</function>
|
||
pour plus d'informations.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Si <function>return</function>
|
||
est omis, la valeur &null; sera retournée.
|
||
</para>
|
||
</note>
|
||
|
||
<sect2>
|
||
<title>Utilisation de return</title>
|
||
<para>
|
||
<example>
|
||
<title>Utilisation de <function>return</function></title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function carre($num)
|
||
{
|
||
return $num * $num;
|
||
}
|
||
echo carre(4); // Affiche '16'
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
Une fonction ne peut pas renvoyer plusieurs valeurs en même temps, mais
|
||
vous pouvez obtenir le même résultat en renvoyant un tableau.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Retourner un tableau d'une fonction</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function petit_nombre()
|
||
{
|
||
return [0, 1, 2];
|
||
}
|
||
// La déconstruction d'un tableau collectera chaque membre du tableau individuellement
|
||
[$zero, $one, $two] = petit_nombre();
|
||
|
||
// Antérieur à PHP 7.1, la seule alternative équivalente est en utilisant la structure de langage list()
|
||
list ($zero, $un, $deux) = petit_nombre();
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Pour retourner une référence d'une fonction, utilisez
|
||
l'opérateur & aussi bien dans la déclaration de la fonction que dans
|
||
l'assignation de la valeur de retour.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Retourner une référence d'une fonction</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function &retourne_reference()
|
||
{
|
||
return $uneref;
|
||
}
|
||
|
||
$newref =& retourne_reference();
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
Pour plus d'informations sur les références, référez-vous à <link
|
||
linkend="language.references">l'explication sur les références</link>.
|
||
</simpara>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.variable-functions">
|
||
<title>Fonctions variables</title>
|
||
|
||
<para>
|
||
PHP supporte le concept de fonctions variables.
|
||
Cela signifie que si le nom d'une variable est suivi de parenthèses,
|
||
PHP recherchera une fonction de même nom et essaiera de l'exécuter.
|
||
Cela peut servir, entre autres, pour faire des fonctions de rappel, des tables de fonctions...
|
||
</para>
|
||
<para>
|
||
Les fonctions variables ne peuvent pas fonctionner avec les
|
||
éléments de langage comme les
|
||
<function>echo</function>, <function>print</function>,
|
||
<function>unset</function>, <function>isset</function>,
|
||
<function>empty</function>, <function>include</function>,
|
||
<function>require</function> etc. Vous devez utiliser votre
|
||
propre gestion de fonctions pour utiliser un de ces éléments
|
||
de langage comme fonctions variables.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Exemple de fonction variable</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
function foo() {
|
||
echo "dans foo()<br />\n";
|
||
}
|
||
|
||
function bar($arg = '')
|
||
{
|
||
echo "Dans bar(); l'argument était '$arg'.<br />\n";
|
||
}
|
||
|
||
// Ceci est une fonction détournée de echo
|
||
function echoit($string)
|
||
{
|
||
echo $string;
|
||
}
|
||
|
||
$func = 'foo';
|
||
$func(); // Appel foo()
|
||
|
||
$func = 'bar';
|
||
$func('test'); // Appel bar()
|
||
|
||
$func = 'echoit';
|
||
$func('test'); // Appel echoit()
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Vous pouvez aussi appeler les méthodes d'un objet en utilisant le système des
|
||
fonctions variables.
|
||
<example>
|
||
<title>Exemple de méthode variable</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
class Foo
|
||
{
|
||
function Variable()
|
||
{
|
||
$name = 'Bar';
|
||
$this->$name(); // Appelle la méthode Bar()
|
||
}
|
||
|
||
function Bar()
|
||
{
|
||
echo "C'est Bar";
|
||
}
|
||
}
|
||
|
||
$foo = new Foo();
|
||
$funcname = "Variable";
|
||
$foo->$funcname(); // Appelle $foo->Variable()
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
Lors de l'appel à des méthodes statiques, l'appel de fonction est meilleur que
|
||
l'opérateur de propriété statique :
|
||
<example>
|
||
<title>Exemple de méthode variable avec des propriétés statiques</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
class Foo
|
||
{
|
||
static $variable = 'static property';
|
||
static function Variable()
|
||
{
|
||
echo 'Method Variable called';
|
||
}
|
||
}
|
||
|
||
echo Foo::$variable; // Ceci affiche 'static property'. Il est nécessaire d'avoir une $variable dans le contexte.
|
||
$variable = "Variable";
|
||
Foo::$variable(); // Ceci appelle $foo->Variable(), lisant ainsi la $variable depuis le contexte.
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>callables complexe</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
class Foo
|
||
{
|
||
static function bar()
|
||
{
|
||
echo "bar\n";
|
||
}
|
||
function baz()
|
||
{
|
||
echo "baz\n";
|
||
}
|
||
}
|
||
|
||
$func = array("Foo", "bar");
|
||
$func(); // Affiche "bar"
|
||
$func = array(new Foo, "baz");
|
||
$func(); // Affiche "baz"
|
||
$func = "Foo::bar";
|
||
$func(); // Affiche "bar"
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<sect2 role="seealso">
|
||
&reftitle.seealso;
|
||
<para>
|
||
<simplelist>
|
||
<member><function>is_callable</function></member>
|
||
<member><function>call_user_func</function></member>
|
||
<member><function>function_exists</function></member>
|
||
<member><link linkend="language.variables.variable">Les variables variable</link></member>
|
||
</simplelist>
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.internal">
|
||
<title>Fonctions internes</title>
|
||
|
||
<para>
|
||
PHP dispose de nombreuses fonctions et structures standards. Il y a aussi
|
||
des fonctions qui requièrent des extensions spécifiques de PHP, sans
|
||
lesquelles vous obtiendrez l'erreur fatale
|
||
<literal>undefined function</literal>. Par exemple, pour utiliser les
|
||
fonctions <link linkend="ref.image">d'images</link>,
|
||
telles que <function>imagecreatetruecolor</function>, vous aurez besoin du
|
||
support de <productname>GD</productname> dans PHP. Ou bien, pour utiliser
|
||
<function>mysqli_connect</function>, vous aurez besoin de l'extension
|
||
<link linkend="book.mysqli">MySQLi</link>. Il y a des fonctions de base qui
|
||
sont incluses dans toutes les versions de PHP, telles que les fonctions de
|
||
<link linkend="ref.strings">chaînes de caractères</link> et les fonctions
|
||
de <link linkend="ref.var">variables</link>. Utilisez
|
||
<function>phpinfo</function> ou
|
||
<function>get_loaded_extensions</function> pour savoir quelles sont les
|
||
extensions qui sont compilées avec votre PHP. Notez aussi que de
|
||
nombreuses extensions sont activées par défaut, et que le manuel PHP est
|
||
compartimenté par extension. Voyez les chapitres de
|
||
<link linkend="configuration">configuration</link>,
|
||
<link linkend="install">installation</link> ainsi que les
|
||
détails particuliers à chaque extension, pour savoir comment les mettre en place.
|
||
</para>
|
||
<para>
|
||
Lire et comprendre le prototype d'une fonction est décrit dans l'annexe
|
||
<link linkend="about.prototypes">Comment lire la définition d'une
|
||
fonction (prototype)</link>.
|
||
Il est important de comprendre ce qu'une fonction retourne, ou si une
|
||
fonction travaille directement sur la valeur des paramètres fournis. Par
|
||
exemple, <function>str_replace</function> va retourner une chaîne modifiée,
|
||
tandis que <function>usort</function> travaille directement sur la variable
|
||
passée en paramètre. Chaque page du manuel a des informations spécifiques
|
||
sur chaque fonction, comme le nombre de paramètres, les évolutions de
|
||
spécifications, les valeurs retournées en cas de succès ou d'échec, et la
|
||
disponibilité en fonction des versions. Bien connaître ces différences,
|
||
parfois subtiles, est crucial pour bien programmer en PHP.
|
||
</para>
|
||
<note>
|
||
<simpara>
|
||
Si les paramètres donnés à une fonction ne sont pas corrects, comme le fait
|
||
de passer un &array; alors qu'une &string; est attendue, la valeur retournée
|
||
de la fonction est indéfinie. Dans ce cas, la fonction retournera la plupart
|
||
du temps une valeur &null; mais ce n'est juste qu'une convention et
|
||
ne peut être considéré comme une certitude.
|
||
À partir de PHP 8.0.0, une exception <classname>TypeError</classname>
|
||
est normalement lancée dans ce cas.
|
||
</simpara>
|
||
</note>
|
||
<note>
|
||
<para>
|
||
En mode coercitif, les types scalaires des fonctions internes sont nullables par défaut.
|
||
À partir PHP 8.1.0, passer &null; à un paramètre de fonction interne qui n'est pas déclaré
|
||
nullable est déconseillé et émet une notice de dépréciation en mode coercitif pour s'aligner
|
||
sur le comportement des fonctions définies par l'utilisateur, où les types scalaires doivent
|
||
être marqués comme nullables explicitement.
|
||
</para>
|
||
<para>
|
||
Par exemple, la fonction <function>strlen</function> attend du paramètre <literal>$string</literal>
|
||
soit de type &string; et non &null;.
|
||
Pour des raisons historiques, PHP autorise le passage de &null; pour ce paramètre en mode coercitif.
|
||
Le paramètre est alors implicitement converti en <type>string</type>, résultant en une valeur <literal>""</literal>.
|
||
Noter qu'une <classname>TypeError</classname> est émise en mode strict.
|
||
</para>
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
var_dump(strlen(null));
|
||
// "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" as of PHP 8.1.0
|
||
// int(0)
|
||
|
||
var_dump(str_contains("foobar", null));
|
||
// "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" as of PHP 8.1.0
|
||
// bool(true)
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</note>
|
||
<sect2 role="seealso">
|
||
&reftitle.seealso;
|
||
<para>
|
||
<simplelist>
|
||
<member><function>function_exists</function></member>
|
||
<member><link linkend="funcref">l'index des fonctions</link></member>
|
||
<member><function>get_extension_funcs</function></member>
|
||
<member><function>dl</function></member>
|
||
</simplelist>
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.anonymous">
|
||
<title>Fonctions anonymes</title>
|
||
<simpara>
|
||
Les fonctions anonymes, aussi appelées fermetures ou <literal>closures</literal>
|
||
permettent la création de fonctions sans préciser leur nom.
|
||
Elles sont particulièrement utiles comme fonctions de rappel <type>callable</type>,
|
||
mais leur utilisation n'est pas limitée à ce seul usage.
|
||
</simpara>
|
||
<simpara>
|
||
Les fonctions anonymes sont implémentées en utilisant la classe
|
||
<link linkend="class.closure"><classname>Closure</classname></link>.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Exemples avec des fonctions anonymes</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
echo preg_replace_callback('~-([a-z])~', function ($match) {
|
||
return strtoupper($match[1]);
|
||
}, 'bonjour-le-monde');
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<simpara>
|
||
Les fonctions anonymes peuvent aussi être utilisées comme valeurs de
|
||
variables. PHP va automatiquement convertir ces expressions
|
||
en objets <classname>Closure</classname>. Assigner une fermeture
|
||
à une variable est la même chose qu'une affectation classique,
|
||
y compris pour le point-virgule final.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Assignation de fonction anonyme à une variable</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$greet = function($name) {
|
||
printf("Bonjour %s\r\n", $name);
|
||
};
|
||
|
||
$greet('World');
|
||
$greet('PHP');
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<simpara>
|
||
Les fonctions anonymes peuvent hériter des variables du contexte de leur
|
||
parent. Ces variables doivent alors être passées dans la construction
|
||
de langage <literal>use</literal>.
|
||
À partir de PHP 7.1, ces variables ne doivent pas inclure de &link.superglobals;,
|
||
<varname>$this</varname>, ou des variables ayant le même nom qu'un paramètre.
|
||
Une déclaration de type de retour pour la fonction doit être placé
|
||
<emphasis>après</emphasis> la clause <literal>use</literal>.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Héritage de variable depuis le contexte parent</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$message = 'hello';
|
||
|
||
// Pas de "use"
|
||
$example = function () {
|
||
var_dump($message);
|
||
};
|
||
$example();
|
||
|
||
// Hérite $message
|
||
$example = function () use ($message) {
|
||
var_dump($message);
|
||
};
|
||
$example();
|
||
|
||
// La valeur de la variable héritée est définie lorsque la fonction est
|
||
// définie non quand elle est appelée
|
||
$message = 'world';
|
||
$example();
|
||
|
||
// Réinitialisation de la variable message
|
||
$message = 'hello';
|
||
|
||
// Héritage par référence
|
||
$example = function () use (&$message) {
|
||
var_dump($message);
|
||
};
|
||
$example();
|
||
|
||
// Le changement de valeur dans le contexte parent est reflété lors de
|
||
// l'appel de la fonction.
|
||
$message = 'world';
|
||
$example();
|
||
|
||
// Les fonctions anonymes acceptent également des arguments classiques
|
||
$example = function ($arg) use ($message) {
|
||
var_dump($arg . ' ' . $message);
|
||
};
|
||
$example("hello");
|
||
|
||
// Return type declaration comes after the use clause
|
||
$example = function () use ($message): string {
|
||
return "hello $message";
|
||
};
|
||
var_dump($example());
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs.similar;
|
||
<screen>
|
||
<![CDATA[
|
||
Notice: Undefined variable: message in /example.php on line 6
|
||
NULL
|
||
string(5) "hello"
|
||
string(5) "hello"
|
||
string(5) "hello"
|
||
string(5) "world"
|
||
string(11) "hello world"
|
||
string(11) "hello world"
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
À partir de PHP 8.0.0, la liste des variables hérité du contexte peut
|
||
inclure une virgule trainante, qui sera ignoré.
|
||
</para>
|
||
<simpara>
|
||
L'héritage du contexte parent
|
||
<emphasis>n'est pas</emphasis> la même chose que les variables
|
||
de l'environnement global. Les variables globales existent dans le
|
||
contexte global, qui est le même, quelle que soit la fonction qui
|
||
s'exécute. Le contexte parent d'une fonction anonyme est la fonction
|
||
dans laquelle la fonction a été déclarée (pas nécessairement celle
|
||
qui appelle). Voyez l'exemple ci-dessous :
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Fonctions anonymes et contexte</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
// Un panier d'achat simple, qui contient une liste de produits
|
||
// choisis et la quantité désirée de chaque produit. Il inclut
|
||
// une méthode qui calcule le prix total des éléments dans le panier
|
||
// en utilisant une fonction de rappel anonyme.
|
||
class Panier
|
||
{
|
||
const PRICE_BEURRE = 1.00;
|
||
const PRICE_LAIT = 3.00;
|
||
const PRICE_OEUF = 6.95;
|
||
|
||
protected $products = array();
|
||
|
||
public function add($product, $quantity)
|
||
{
|
||
$this->products[$product] = $quantity;
|
||
}
|
||
|
||
public function getQuantity($product)
|
||
{
|
||
return isset($this->products[$product]) ? $this->products[$product] :
|
||
FALSE;
|
||
}
|
||
|
||
public function getTotal($tax)
|
||
{
|
||
$total = 0.00;
|
||
|
||
$callback =
|
||
function ($quantity, $product) use ($tax, &$total)
|
||
{
|
||
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
|
||
strtoupper($product));
|
||
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
|
||
};
|
||
|
||
array_walk($this->products, $callback);
|
||
return round($total, 2);
|
||
}
|
||
}
|
||
|
||
$mon_panier = new Panier;
|
||
|
||
// Ajout d'élément au panier
|
||
$mon_panier->add('beurre', 1);
|
||
$mon_panier->add('lait', 3);
|
||
$mon_panier->add('oeuf', 6);
|
||
|
||
// Affichage du prix avec 5.5% de TVA
|
||
print $mon_panier->getTotal(0.055) . "\n";
|
||
// Le résultat sera 54.29
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<example>
|
||
<title>Liage automatique de <literal>$this</literal></title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class Test
|
||
{
|
||
public function testing()
|
||
{
|
||
return function() {
|
||
var_dump($this);
|
||
};
|
||
}
|
||
}
|
||
|
||
$object = new Test;
|
||
$function = $object->testing();
|
||
$function();
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
object(Test)#1 (0) {
|
||
}
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
Lorsque déclarée dans le contexte d'une classe, la classe
|
||
courante est automatiquement liée, la rendant <literal>$this</literal>
|
||
disponible dans le contexte de la fonction. Si ce liage automatique de
|
||
la classe courante n'est pas souhaité, alors les
|
||
<link linkend="functions.anonymous-functions.static">fonctions anonymes
|
||
statiques</link> peuvent être utilisées à la place.
|
||
</para>
|
||
|
||
<sect2 xml:id="functions.anonymous-functions.static">
|
||
<title>Les fonctions anonymes statiques</title>
|
||
<para>
|
||
Les fonctions anonymes peuvent être déclarées statiquement.
|
||
Ceci permet de ne pas lier automatiquement la classe courante à la fonction.
|
||
Les objets peuvent aussi ne pas être liés lors de l'exécution.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Tentative d'usage de <literal>$this</literal> dans une fonction anonyme statique</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class Foo
|
||
{
|
||
function __construct()
|
||
{
|
||
$func = static function() {
|
||
var_dump($this);
|
||
};
|
||
$func();
|
||
}
|
||
};
|
||
new Foo();
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Notice: Undefined variable: this in %s on line %d
|
||
NULL
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
|
||
<para>
|
||
<example>
|
||
<title>Tentative de liage d'un objet à une fonction anonyme statique</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$func = static function() {
|
||
// function body
|
||
};
|
||
$func = $func->bindTo(new stdClass);
|
||
$func();
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
</sect2>
|
||
|
||
|
||
<sect2 role="changelog">
|
||
&reftitle.changelog;
|
||
<para>
|
||
<informaltable>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>&Version;</entry>
|
||
<entry>&Description;</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>7.1.0</entry>
|
||
<entry>
|
||
Les fonctions anonymes peuvent ne pas se fermer sur les &link.superglobals;,
|
||
<varname>$this</varname>, ou toute variable avec le même nom qu'un
|
||
paramètre.
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 role="notes">
|
||
&reftitle.notes;
|
||
<note>
|
||
<simpara>
|
||
Il est possible d'utiliser les fonctions <function>func_num_args</function>,
|
||
<function>func_get_arg</function> et <function>func_get_args</function>
|
||
dans une fonction anonyme.
|
||
</simpara>
|
||
</note>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.arrow">
|
||
<title>Fonction Fléchée</title>
|
||
|
||
<simpara>
|
||
Les fonctions fléchées ont été introduites en PHP 7.4 en tant que syntaxe
|
||
plus concise pour les
|
||
<link linkend="functions.anonymous">fonctions anonymes</link>.
|
||
</simpara>
|
||
<simpara>
|
||
Les fonctions anonymes comme les fonctions fléchées sont implémentées en
|
||
utilisant la classe
|
||
<link linkend="class.closure"><classname>Closure</classname></link>.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Les fonctions fléchées ont la forme basique
|
||
<code>fn (argument_list) => expr</code>.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Les fonctions fléchées supportent les mêmes fonctionnalités que les
|
||
<link linkend="functions.anonymous">fonctions anonymes</link>,
|
||
à l'exception que l'utilisation des variables de la portée parente est
|
||
automatique.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Quand une variable utilisée dans l'expression est définie dans la portée
|
||
parente, elle sera implicitement capturée par valeur.
|
||
Dans l'exemple suivant, les fonctions <varname>$fn1</varname> et
|
||
<varname>$fn2</varname> se comportent de façon identique.
|
||
</simpara>
|
||
|
||
<para>
|
||
<example>
|
||
<title>Les fonctions fléchées capturent les variables par valeur automatiquement</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$y = 1;
|
||
|
||
$fn1 = fn($x) => $x + $y;
|
||
// equivalent to using $y by value:
|
||
$fn2 = function ($x) use ($y) {
|
||
return $x + $y;
|
||
};
|
||
|
||
var_export($fn1(3));
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
4
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
Ceci fonctionne aussi si les fonctions fléchées sont imbriquées :
|
||
</simpara>
|
||
<para>
|
||
<example>
|
||
<title>Les fonctions fléchées capturent les variables par valeur automatiquement, même imbriquées</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$z = 1;
|
||
$fn = fn($x) => fn($y) => $x * $y + $z;
|
||
// Outputs 51
|
||
var_export($fn(5)(10));
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
Similairement aux fonctions anonymes,
|
||
la syntaxe des fonctions fléchées permet les signatures de fonction arbitraire,
|
||
ceci inclus les types de paramètres et de retour, valeur par défaut, variable,
|
||
aussi bien que le passage et retour par référence.
|
||
Tous les exemples suivants sont des fonctions fléchées valides :
|
||
</simpara>
|
||
<para>
|
||
<example>
|
||
<title>Exemples de fonctions fléchées</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
fn(array $x) => $x;
|
||
static fn($x): int => $x;
|
||
fn($x = 42) => $x;
|
||
fn(&$x) => $x;
|
||
fn&($x) => $x;
|
||
fn($x, ...$rest) => $rest;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
<simpara>
|
||
Les fonctions fléchées lie les variables par valeur.
|
||
Ceci est à peu près équivalent à effectuer un <code>use($x)</code> pour
|
||
chaque variable <varname>$x</varname> utilisée à l'intérieur de la fonction
|
||
fléchée.
|
||
Un liage par valeur signifie qu'il n'est pas possible de modifier une
|
||
valeur de la portée extérieure.
|
||
<link linkend="functions.anonymous">Les fonctions anonymes</link>
|
||
peuvent être utilisées à la place pour des liaisons par référence.
|
||
</simpara>
|
||
<para>
|
||
<example>
|
||
<title>
|
||
Valeurs de la portée extérieure ne peuvent pas être modifiées par les fonctions fléchées
|
||
</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$x = 1;
|
||
$fn = fn() => $x++; // Has no effect
|
||
$fn();
|
||
var_export($x); // Outputs 1
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<sect2 role="changelog">
|
||
&reftitle.changelog;
|
||
<para>
|
||
<informaltable>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>&Version;</entry>
|
||
<entry>&Description;</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>7.4.0</entry>
|
||
<entry>
|
||
Les fonctions fléchées sont désormais disponibles.
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 role="notes">
|
||
&reftitle.notes;
|
||
<note>
|
||
<simpara>
|
||
Il est possible d'utiliser <function>func_num_args</function>,
|
||
<function>func_get_arg</function>, et <function>func_get_args</function>
|
||
depuis l'intérieur d'une fonction fléchée.
|
||
</simpara>
|
||
</note>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="functions.first_class_callable_syntax">
|
||
<title>Syntaxe callable de première classe</title>
|
||
|
||
<para>
|
||
La syntaxe de callable de première classe est introduite à partir de PHP 8.1.0,
|
||
comme une manière de créer des <link linkend="functions.anonymous">fonctions anonymes</link>
|
||
depuis des <link linkend="language.types.callable">callable</link>.
|
||
Elle remplace la syntaxe des callables existante utilisant les chaînes et tableaux.
|
||
L'avantage de cette syntaxe est qu'elle est accessible à l'analyse statique
|
||
et utilise la portée du point où le callable est acquis.
|
||
</para>
|
||
|
||
<para>
|
||
La syntaxe <code>CallableExpr(...)</code> est utilisée pour créer un objet
|
||
<classname>Closure</classname> depuis le callable.
|
||
<code>CallableExpr</code> accepte toute expression qui peut être directement
|
||
appelée dans la grammaire de PHP :
|
||
<example>
|
||
<title>Syntaxe callable de première classe basique</title>
|
||
<programlisting role="php">
|
||
<;
|
||
$f9 = [Foo::class, 'staticmethod'](...);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Les <code>...</code> font partie de la syntaxe et ne sont pas une omission.
|
||
</para>
|
||
</note>
|
||
|
||
<para>
|
||
<code>CallableExpr(...)</code> a les mêmes sémantiques que <methodname>Closure::fromCallable</methodname>.
|
||
C'est-à-dire, contrairement aux callables utilisant les chaînes et tableaux,
|
||
<code>CallableExpr(...)</code> respecte la portée du point où il est créé :
|
||
<example>
|
||
<title>Comparaison de portée de <code>CallableExpr(...)</code> et des callables traditionnels</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
class Foo {
|
||
public function getPrivateMethod() {
|
||
return [$this, 'privateMethod'];
|
||
}
|
||
private function privateMethod() {
|
||
echo __METHOD__, "\n";
|
||
}
|
||
}
|
||
$foo = new Foo;
|
||
$privateMethod = $foo->getPrivateMethod();
|
||
$privateMethod();
|
||
// Fatal error: Call to private method Foo::privateMethod() from global scope
|
||
// This is because call is performed outside from Foo and visibility will be checked from this point.
|
||
class Foo1 {
|
||
public function getPrivateMethod() {
|
||
// Uses the scope where the callable is acquired.
|
||
return $this->privateMethod(...); // identical to Closure::fromCallable([$this, 'privateMethod']);
|
||
}
|
||
private function privateMethod() {
|
||
echo __METHOD__, "\n";
|
||
}
|
||
}
|
||
$foo1 = new Foo1;
|
||
$privateMethod = $foo1->getPrivateMethod();
|
||
$privateMethod(); // Foo1::privateMethod
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
La création d'objets avec cette syntaxe (e.g <code>new Foo(...)</code>) n'est pas supportée,
|
||
car la syntaxe <code>new Foo()</code> n'est pas considérée comme un appel.
|
||
</para>
|
||
</note>
|
||
|
||
<note>
|
||
<para>
|
||
La syntaxe de callable de première classe ne peut pas être combinée avec
|
||
l'<link linkend="language.oop5.basic.nullsafe">opérateur nullsafe</link>.
|
||
Les deux cas suivants entraînent une erreur de compilation :
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
$obj?->method(...);
|
||
$obj?->prop->method(...);
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
</note>
|
||
</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
|
||
-->
|