1
0
mirror of https://github.com/php/doc-fr.git synced 2026-03-23 22:52:18 +01:00
Files
archived-doc-fr/language/types/string.xml
2026-03-02 13:40:31 +01:00

1363 lines
42 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 2832df2e1bd7daa1ec29ffb167dce1c9feb8cc6b Maintainer: yannick Status: ready -->
<!-- Reviewed: no Maintainer: girgias -->
<sect1 xml:id="language.types.string">
<title>Chaînes</title>
<para>
Une <type>chaîne</type> est une série de caractères, où un caractère est
le même qu'un octet. Cela signifie que PHP ne prend en charge qu'un ensemble
de 256 caractères, et n'offre donc pas de prise en charge native de l'Unicode. Voir
<link linkend="language.types.string.details">les détails du type chaîne</link>.
</para>
<note>
<simpara>
Sur les versions 32 bits, une <type>chaîne</type> peut être aussi grande que 2 Go
(2147483647 octets maximum)
</simpara>
</note>
<sect2 xml:id="language.types.string.syntax">
<title>Syntaxe</title>
<para>
Une <type>chaîne</type> littérale peut être spécifiée de quatre manières différentes :
</para>
<itemizedlist>
<listitem>
<simpara>
<link linkend="language.types.string.syntax.single">entre guillemets simples</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.types.string.syntax.double">entre guillemets doubles</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.types.string.syntax.heredoc">syntaxe heredoc</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.types.string.syntax.nowdoc">syntaxe nowdoc</link>
</simpara>
</listitem>
</itemizedlist>
<sect3 xml:id="language.types.string.syntax.single">
<title>Entre guillemets simples</title>
<para>
La manière la plus simple de spécifier une <type>chaîne</type> est de l'encadrer de guillemets
simples (le caractère <literal>'</literal>).
</para>
<para>
Pour spécifier un guillemet simple littéral, échappez-le avec un antislash
(<literal>\</literal>). Pour spécifier un antislash littéral, doublez-le
(<literal>\\</literal>). Toutes les autres occurrences de l'antislash seront traitées
comme un antislash littéral : cela signifie que les autres séquences d'échappement que l'on
pourrait connaître, telles que <literal>\r</literal> ou <literal>\n</literal>,
seront sorties littéralement comme spécifié plutôt que d'avoir une signification spéciale.
</para>
<note>
<simpara>
Contrairement aux <link linkend="language.types.string.syntax.double">guillemets doubles</link>
et <link linkend="language.types.string.syntax.heredoc">syntaxes heredoc</link>,
les <link linkend="language.variables">variables</link> et les séquences d'échappement
pour les caractères spéciaux <emphasis>ne</emphasis> seront <emphasis>pas</emphasis> étendues
lorsqu'elles se trouvent dans des <type>chaînes</type> entre guillemets simples.
</simpara>
</note>
<example>
<title>Variantes de syntaxe</title>
<programlisting role="php">
<![CDATA[
<?php
echo 'ceci est une chaîne simple', PHP_EOL;
echo 'Vous pouvez également avoir des nouvelles intégrées dans
les chaînes de cette manière, car c'est
acceptable de le faire.', PHP_EOL;
// Affiche : Arnold a dit un jour : "Je reviendrai"
echo 'Arnold a dit un jour : "Je reviendrai"', PHP_EOL;
// Affiche : Vous avez supprimé C:\*.* ?
echo 'Vous avez supprimé C:\\*.* ?', PHP_EOL;
// Affiche : Vous avez supprimé C:\*.* ?
echo 'Vous avez supprimé C:\*.* ?', PHP_EOL;
// Affiche : Cela ne s'étendra pas : \n une nouvelle ligne
echo 'Cela ne s\'étendra pas : \n une nouvelle ligne', PHP_EOL;
// Affiche : Les variables ne $s\'étendent pas $non plus
echo 'Les variables ne $s\'étendent pas $non plus', PHP_EOL;
?>
]]>
</programlisting>
</example>
</sect3>
<sect3 xml:id="language.types.string.syntax.double">
<title>Entre guillemets doubles</title>
<para>
Si la <type>chaîne</type> est encadrée de guillemets doubles (<literal>"</literal>), PHP interprétera
les séquences d'échappement suivantes pour les caractères spéciaux :
</para>
<table>
<title>Caractères échappés</title>
<tgroup cols="2">
<thead>
<row>
<entry>Séquence</entry>
<entry>Signification</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>\n</literal></entry>
<entry>retour à la ligne (LF ou 0x0A (10) en ASCII)</entry>
</row>
<row>
<entry><literal>\r</literal></entry>
<entry>retour chariot (CR ou 0x0D (13) en ASCII)</entry>
</row>
<row>
<entry><literal>\t</literal></entry>
<entry>tabulation horizontale (HT ou 0x09 (9) en ASCII)</entry>
</row>
<row>
<entry><literal>\v</literal></entry>
<entry>tabulation verticale (VT ou 0x0B (11) en ASCII)</entry>
</row>
<row>
<entry><literal>\e</literal></entry>
<entry>échapper (ESC ou 0x1B (27) en ASCII)</entry>
</row>
<row>
<entry><literal>\f</literal></entry>
<entry>avance de formulaire (FF ou 0x0C (12) en ASCII)</entry>
</row>
<row>
<entry><literal>\\</literal></entry>
<entry>antislash</entry>
</row>
<row>
<entry><literal>\$</literal></entry>
<entry>signe dollar</entry>
</row>
<row>
<entry><literal>\"</literal></entry>
<entry>guillemet double</entry>
</row>
<row>
<entry><literal>\[0-7]{1,3}</literal></entry>
<entry>
Octal : la séquence de caractères correspondant à l'expression régulière <literal>[0-7]{1,3}</literal>
est un caractère en notation octale (par exemple, <literal>"\101" === "A"</literal>),
qui déborde silencieusement pour s'adapter à un octet (par exemple, <literal>"\400" === "\000"</literal>)
</entry>
</row>
<row>
<entry><literal>\x[0-9A-Fa-f]{1,2}</literal></entry>
<entry>
Hexadécimal : la séquence de caractères correspondant à l'expression régulière
<literal>[0-9A-Fa-f]{1,2}</literal> est un caractère en notation hexadécimale
(par exemple, <literal>"\x41" === "A"</literal>)
</entry>
</row>
<row>
<entry><literal>\u{[0-9A-Fa-f]+}</literal></entry>
<entry>
Unicode : la séquence de caractères correspondant à l'expression régulière <literal>[0-9A-Fa-f]+</literal>
est un point de code Unicode, qui sera sorti dans la chaîne sous la représentation UTF-8 de ce point de code.
Les accolades sont requises dans la séquence. Par exemple, <literal>"\u{41}" === "A"</literal>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Comme pour les <type>chaînes</type> entre guillemets simples, échapper tout autre caractère
entraînera également l'impression de l'antislash.
</para>
<para>
La caractéristique la plus importante des <type>chaînes</type> entre guillemets doubles est le fait
que les noms de variables seront étendus. Voir
<link linkend="language.types.string.parsing">l'interpolation de chaînes</link> pour
plus de détails.
</para>
</sect3>
<sect3 xml:id="language.types.string.syntax.heredoc">
<title>Heredoc</title>
<simpara>
Une troisième manière de délimiter les <type>chaînes</type> est la syntaxe heredoc :
<literal>&lt;&lt;&lt;</literal>. Après cet opérateur, un identifiant est
fourni, puis une nouvelle ligne. La <type>chaîne</type> elle-même suit, puis
le même identifiant à nouveau pour fermer la citation.
</simpara>
<simpara>
L'identifiant de fermeture peut être indenté par des espaces ou des tabulations, auquel cas
l'indentation sera supprimée de toutes les lignes dans la chaîne doc.
Avant PHP 7.3.0, l'identifiant de fermeture <emphasis>doit</emphasis>
commencer dans la première colonne de la ligne.
</simpara>
<simpara>
De plus, l'identifiant de fermeture doit suivre les mêmes règles de nommage que tout
autre label en PHP : il doit contenir uniquement des caractères alphanumériques et
des soulignés, et doit commencer par un caractère non numérique ou un souligné.
</simpara>
<example>
<title>Exemple de base de Heredoc à partir de PHP 7.3.0</title>
<programlisting role="php">
<![CDATA[
<?php
// pas d'indentation
echo <<<END
a
b
c
\n
END;
// 4 espaces d'indentation
echo <<<END
a
b
c
END;
]]>
</programlisting>
&example.outputs.73;
<screen>
<![CDATA[
a
b
c
a
b
c
]]>
</screen>
</example>
<simpara>
Si l'identifiant de fermeture est indenté plus que n'importe quelle ligne du corps, alors une <classname>ParseError</classname> sera levée :
</simpara>
<example>
<title>L'identifiant de fermeture ne doit pas être indenté plus que n'importe quelle ligne du corps</title>
<programlisting role="php">
<![CDATA[
<?php
echo <<<END
a
b
c
END;
]]>
</programlisting>
&example.outputs.73;
<screen>
<![CDATA[
Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4
]]>
</screen>
</example>
<simpara>
Si l'identifiant de fermeture est indenté, des tabulations peuvent également être utilisées, cependant,
les tabulations et les espaces <emphasis>ne doivent pas</emphasis> être mélangés concernant
l'indentation de l'identifiant de fermeture et l'indentation du corps
(jusqu'à l'identifiant de fermeture). Dans l'un de ces cas, une <classname>ParseError</classname> sera levée.
Ces contraintes d'espace ont été incluses car le mélange d'espaces et de tabulations pour l'indentation nuit à la lisibilité.
</simpara>
<example>
<title>Indentation différente pour le corps (espaces) identifiant de fermeture</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
// Tout le code suivant ne fonctionne pas.
// indentation différente pour le corps (espaces) marqueur de fin (tabulations)
{
echo <<<END
a
END;
}
// mélange d'espaces et de tabulations dans le corps
{
echo <<<END
a
END;
}
// mélange d'espaces et de tabulations dans le marqueur de fin
{
echo <<<END
a
END;
}
]]>
</programlisting>
&example.outputs.73;
<screen>
<![CDATA[
Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8
]]>
</screen>
</example>
<simpara>
L'identifiant de fermeture pour la chaîne du corps n'est pas requis pour être
suivi d'un point-virgule ou d'un saut de ligne. Par exemple, le code suivant
est autorisé à partir de PHP 7.3.0 :
</simpara>
<example>
<title>Continuation d'une expression après un identifiant de fermeture</title>
<programlisting role="php">
<![CDATA[
<?php
$values = [<<<END
a
b
c
END, 'd e f'];
var_dump($values);
]]>
</programlisting>
&example.outputs.73;
<screen>
<![CDATA[
array(2) {
[0] =>
string(11) "a
b
c"
[1] =>
string(5) "d e f"
}
]]>
</screen>
</example>
<warning>
<simpara>
Si l'identifiant de fermeture a été trouvé au début d'une ligne, alors
peu importe s'il faisait partie d'un autre mot, il peut être considéré
comme l'identifiant de fermeture et provoquer une <classname>ParseError</classname>.
</simpara>
<example>
<title>L'identifiant de fermeture dans le corps de la chaîne tend à provoquer une ParseError</title>
<programlisting role="php">
<![CDATA[
<?php
$values = [<<<END
a
b
END ING
END, 'd e f'];
]]>
</programlisting>
&example.outputs.73;
<screen>
<![CDATA[
Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 5
]]>
</screen>
</example>
<simpara>
Pour éviter ce problème, il est sûr de suivre la règle simple :
<emphasis>ne pas choisir un mot qui apparaît dans le corps du texte
en tant qu'identifiant de fermeture</emphasis>.
</simpara>
</warning>
<warning>
<simpara>
Avant PHP 7.3.0, il est très important de noter que la ligne contenant l'
identifiant de fermeture ne doit contenir aucun autre caractère, sauf un point-virgule
(<literal>;</literal>).
Cela signifie surtout que l'identifiant
<emphasis>ne peut pas être indenté</emphasis>, et il ne doit pas y avoir d'espaces
ou d'onglets avant ou après le point-virgule. Il est également important de réaliser que
le premier caractère avant l'identifiant de fermeture doit être un saut de ligne tel
que défini par le système d'exploitation local. C'est <literal>\n</literal> sur
les systèmes UNIX, y compris macOS. Le délimiteur de fermeture doit également être
suivi d'un saut de ligne.
</simpara>
<simpara>
Si cette règle est enfreinte et que l'identifiant de fermeture n'est pas "propre", il ne sera
pas considéré comme un identifiant de fermeture, et PHP continuera à en chercher un. Si un
identifiant de fermeture approprié n'est pas trouvé avant la fin du fichier
courant, une erreur d'analyse se produira à la dernière ligne.
</simpara>
<example>
<title>Exemple invalide, avant PHP 7.3.0</title>
<programlisting role="php">
<!-- Ceci est un exemple INVALIDE -->
<![CDATA[
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
// L'identifiant ne doit pas être indenté
?>
]]>
</programlisting>
</example>
<example>
<title>Exemple valide, même avant PHP 7.3.0</title>
<programlisting role="php">
<!-- Ceci est un exemple VALIDE -->
<![CDATA[
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
]]>
</programlisting>
</example>
<para>
Les heredocs contenant des variables ne peuvent pas être utilisés pour initialiser des propriétés de classe.
</para>
</warning>
<para>
Le texte heredoc se comporte exactement comme une <type>string</type> entre guillemets doubles, sans les guillemets. Cela signifie que les guillemets dans un heredoc n'ont pas besoin d'être échappés, mais les codes d'échappement mentionnés ci-dessus peuvent toujours être utilisés. Les variables sont développées, mais il faut prendre le même soin lors de l'expression de variables complexes à l'intérieur d'un heredoc que pour les <type>string</type>s.
</para>
<example>
<title>Exemple de citation de chaîne heredoc</title>
<programlisting role="php">
<![CDATA[
<?php
$str = <<<EOD
Exemple de chaîne
s'étendant sur plusieurs lignes
utilisant la syntaxe heredoc.
EOD;
/* Exemple plus complexe, avec des variables. */
class foo
{
var $foo;
var $bar;
function __construct()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<EOT
Mon nom est "$name". Je suis en train d'imprimer $foo->foo.
Maintenant, j'imprime {$foo->bar[1]}.
Cela devrait imprimer un 'A' majuscule : \x41
EOT;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Mon nom est "MyName". Je suis en train d'imprimer Foo.
Maintenant, j'imprime Bar2.
Cela devrait imprimer un 'A' majuscule : A]]>
</screen>
</example>
<para>
Il est également possible d'utiliser la syntaxe heredoc pour passer des données aux arguments de fonction :
</para>
<example>
<title>Heredoc dans les exemples d'arguments</title>
<programlisting role="php">
<![CDATA[
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
]]>
</programlisting>
</example>
<para>
Il est possible d'initialiser des variables statiques et des propriétés/constants de classe en utilisant la syntaxe heredoc :
</para>
<example>
<title>Utilisation d'Heredoc pour initialiser des valeurs statiques</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
// Variables statiques
function foo()
{
static $bar = <<<LABEL
Rien ici...
LABEL;
}
// Propriétés/constants de classe
class foo
{
const BAR = <<<FOOBAR
Exemple de constante
FOOBAR;
public $baz = <<<FOOBAR
Exemple de propriété
FOOBAR;
}
?>
]]>
</programlisting>
</example>
<para>
L'identifiant d'ouverture du Heredoc peut éventuellement être
encadré de guillemets doubles :
</para>
<example>
<title>Utilisation de guillemets doubles dans le Heredoc</title>
<programlisting role="php">
<![CDATA[
<?php
echo <<<"FOOBAR"
Bonjour le monde !
FOOBAR;
?>
]]>
</programlisting>
</example>
</sect3>
<sect3 xml:id="language.types.string.syntax.nowdoc">
<title>Nowdoc</title>
<para>
Les nowdocs sont aux chaînes entre guillemets simples ce que les heredocs sont aux chaînes entre guillemets doubles. Un nowdoc est spécifié de manière similaire à un heredoc, mais <emphasis>aucune interpolation de chaîne n'est effectuée</emphasis> à l'intérieur d'un nowdoc. La construction est idéale pour intégrer du code PHP ou d'autres blocs de texte volumineux sans avoir besoin d'échapper. Il partage certaines caractéristiques avec la construction SGML
<literal>&lt;![CDATA[ ]]&gt;</literal>, en ce sens qu'elle déclare un
bloc de texte qui n'est pas destiné à être analysé.
</para>
<para>
Un nowdoc est identifié par la même séquence <literal>&lt;&lt;&lt;</literal>
utilisée pour les heredocs, mais l'identifiant qui suit est encadré de guillemets simples, par exemple <literal>&lt;&lt;&lt;'EOT'</literal>. Toutes les règles pour les identifiants heredoc s'appliquent également aux identifiants nowdoc, en particulier celles concernant l'apparence de l'identifiant de fermeture.
</para>
<example>
<title>Exemple de citation de chaîne nowdoc</title>
<programlisting role="php">
<![CDATA[
<?php
echo <<<'EOD'
Exemple de chaîne s'étendant sur plusieurs lignes
utilisant la syntaxe nowdoc. Les barres obliques inverses sont toujours traitées littéralement,
c'est-à-dire \\ et \'.
EOD;
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Exemple de chaîne s'étendant sur plusieurs lignes
utilisant la syntaxe nowdoc. Les barres obliques inverses sont toujours traitées littéralement,
c'est-à-dire \\ et \'.
]]>
</screen>
</example>
<example>
<title>Exemple de citation de chaîne nowdoc avec des variables</title>
<programlisting role="php">
<![CDATA[
<?php
class foo
{
public $foo;
public $bar;
function __construct()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<'EOT'
Mon nom est "$name". Je suis en train d'imprimer $foo->foo.
Maintenant, j'imprime {$foo->bar[1]}.
Cela ne devrait pas imprimer un 'A' majuscule : \x41
EOT;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Mon nom est "$name". Je suis en train d'imprimer $foo->foo.
Maintenant, j'imprime {$foo->bar[1]}.
Cela ne devrait pas imprimer un 'A' majuscule : \x41]]>
</screen>
</example>
<example>
<title>Exemple de données statiques</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
]]>
</programlisting>
</example>
</sect3>
<sect3 xml:id="language.types.string.parsing">
<title>Interpolation de chaînes</title>
<simpara>
Lorsqu'une <type>chaîne</type> est spécifiée entre guillemets doubles ou avec heredoc,
des <link linkend="language.variables">variables</link> peuvent être substituées à l'intérieur.
</simpara>
<simpara>
Il existe deux types de syntaxe : une
<link linkend="language.types.string.parsing.basic">de base</link> et une
<link linkend="language.types.string.parsing.advanced">avancée</link>.
La syntaxe de base est la plus courante et la plus pratique. Elle offre un moyen d'incorporer une variable, une valeur <type>tableau</type> ou une propriété <type>objet</type> dans une <type>chaîne</type> avec un minimum d'effort.
</simpara>
<sect4 xml:id="language.types.string.parsing.basic">
<title>Syntaxe de base</title>
<simpara>
Si un signe dollar (<literal>$</literal>) est rencontré, les caractères qui le suivent et qui peuvent être utilisés dans un nom de variable seront interprétés comme tels et substitués.
</simpara>
<example>
<title>Interpolation de chaînes</title>
<programlisting role="php">
<![CDATA[
<?php
$juice = "pomme";
echo "Il a bu un peu de $juice jus." . PHP_EOL;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Il a bu un peu de pomme jus.
]]>
</screen>
</example>
<simpara>
Formellement, la structure pour la syntaxe de substitution de variable de base est la suivante :
</simpara>
<informalexample>
<programlisting>
<![CDATA[
string-variable::
variable-name (offset-or-property)?
| ${ expression }
offset-or-property::
offset-in-string
| property-in-string
offset-in-string::
[ name ]
| [ variable-name ]
| [ integer-literal ]
property-in-string::
-> name
variable-name::
$ name
name::
[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
]]>
</programlisting>
</informalexample>
<warning>
<para>
La syntaxe <literal>${ expression }</literal> est dépréciée depuis
PHP 8.2.0, car elle peut être interprétée comme
<link linkend="language.variables.variable">des variables de variables</link> :
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
const foo = 'bar';
$foo = 'foo';
$bar = 'bar';
var_dump("${foo}");
var_dump("${(foo)}");
?>
]]>
</programlisting>
&example.outputs.82;
<screen>
<![CDATA[
Déprécié : Utiliser ${var} dans des chaînes est déprécié, utilisez {$var} à la place dans le fichier à la ligne 6
Déprécié : Utiliser ${expr} (variables de variables) dans des chaînes est déprécié, utilisez {${expr}} à la place dans le fichier à la ligne 9
string(3) "foo"
string(3) "bar"
]]>
</screen>
&example.outputs;
<screen>
<![CDATA[
string(3) "foo"
string(3) "bar"
]]>
</screen>
</informalexample>
La syntaxe d'interpolation de chaîne <link linkend="language.types.string.parsing.advanced">avancée</link> devrait être utilisée à la place.
</para>
</warning>
<note>
<simpara>
S'il n'est pas possible de former un nom valide, le signe dollar reste
tel quel dans la chaîne :
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo "Aucune interpolation $ n'a eu lieu\n";
echo "Aucune interpolation $\n n'a eu lieu\n";
echo "Aucune interpolation $2 n'a eu lieu\n";
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Aucune interpolation $ n'a eu lieu
Aucune interpolation $
n'a eu lieu
Aucune interpolation $2 n'a eu lieu
]]>
</screen>
</informalexample>
</note>
<example>
<title>Interpolation de la valeur de la première dimension d'un tableau ou d'une propriété</title>
<programlisting role="php">
<![CDATA[
<?php
$juices = array("pomme", "orange", "string_key" => "violet");
echo "Il a bu un peu de $juices[0] jus.";
echo PHP_EOL;
echo "Il a bu un peu de $juices[1] jus.";
echo PHP_EOL;
echo "Il a bu un peu de $juices[string_key] jus.";
echo PHP_EOL;
class A {
public $s = "chaîne";
}
$o = new A();
echo "Valeur de l'objet : $o->s.";
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Il a bu un peu de pomme jus.
Il a bu un peu de orange jus.
Il a bu un peu de violet jus.
Valeur de l'objet : chaîne.
]]>
</screen>
</example>
<note>
<simpara>
La clé du tableau doit être non citée, et il n'est donc pas possible de
référencer une constante comme clé avec la syntaxe de base. Utiliser la
syntaxe <link linkend="language.types.string.parsing.advanced">avancée</link>
à la place.
</simpara>
</note>
<simpara>
À partir de PHP 7.1.0, les indices numériques <emphasis>négatifs</emphasis> sont également
supportés.
</simpara>
<example><title>Indices numériques négatifs</title>
<programlisting role="php">
<![CDATA[
<?php
$string = 'chaîne';
echo "Le caractère à l'indice -2 est $string[-2].", PHP_EOL;
$string[-3] = 'o';
echo "Changer le caractère à l'indice -3 en o donne $string.", PHP_EOL;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Le caractère à l'indice -2 est n.
Changer le caractère à l'indice -3 en o donne strong.
]]>
</screen>
</example>
<simpara>
Pour tout ce qui est plus complexe, la
<link linkend="language.types.string.parsing.advanced">syntaxe avancée</link>
doit être utilisée.
</simpara>
</sect4>
<sect4 xml:id="language.types.string.parsing.advanced">
<title>Syntaxe avancée (syntaxe des accolades)</title>
<simpara>
La syntaxe avancée permet l'interpolation de
<emphasis>variables</emphasis> avec des accesseurs arbitraires.
</simpara>
<simpara>
Toute variable scalaire, élément de tableau ou propriété d'objet
(<modifier>statique</modifier> ou non) avec une représentation
<type>chaîne</type> peut être incluse via cette syntaxe.
L'expression est écrite de la même manière que celle qui apparaîtrait en dehors de la
<type>chaîne</type>, puis entourée de <literal>{</literal> et
<literal>}</literal>. Étant donné que <literal>{</literal> ne peut pas être échappé, cette
syntaxe ne sera reconnue que lorsque le <literal>$</literal> suit immédiatement le
<literal>{</literal>. Utiliser <literal>{\$</literal> pour obtenir un
<literal>{$</literal>. Voici quelques exemples pour clarifier :
</simpara>
<example>
<title>Syntaxe avec des accolades</title>
<programlisting role="php">
<![CDATA[
<?php
const DATA_KEY = 'const-key';
$great = 'fantastique';
$arr = [
'1',
'2',
'3',
[41, 42, 43],
'key' => 'Valeur indexée',
'const-key' => 'Clé avec un signe moins',
'foo' => ['foo1', 'foo2', 'foo3']
];
// Ne fonctionnera pas, affiche : This is { fantastic}
echo "Ceci est { $great}";
// Fonctionne, affiche : This is fantastic
echo "Ceci est {$great}";
class Square {
public $width;
public function __construct(int $width) { $this->width = $width; }
}
$square = new Square(5);
// Fonctionne
echo "Ce carré mesure {$square->width}00 centimètres de large.";
// Fonctionne, les clés entre guillemets ne fonctionnent qu'avec la syntaxe des accolades
echo "Cela fonctionne : {$arr['key']}";
// Fonctionne
echo "Cela fonctionne : {$arr[3][2]}";
echo "Cela fonctionne : {$arr[DATA_KEY]}";
// Lors de l'utilisation de tableaux multidimensionnels, utilisez toujours des accolades autour des tableaux
// lorsqu'ils sont à l'intérieur de chaînes
echo "Cela fonctionne : {$arr['foo'][2]}";
echo "Cela fonctionne : {$obj->values[3]->name}";
echo "Cela fonctionne : {$obj->$staticProp}";
// Ne fonctionnera pas, affiche : C:\directory\{fantastic}.txt
echo "C:\directory\{$great}.txt";
// Fonctionne, affiche : C:\directory\fantastic.txt
echo "C:\\directory\\{$great}.txt";
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Comme cette syntaxe permet des expressions arbitraires, il est possible d'utiliser
<link linkend="language.variables.variable">des variables variables</link>
dans la syntaxe avancée.
</simpara>
</note>
</sect4>
</sect3>
<sect3 xml:id="language.types.string.substr">
<title>Accès et modification de chaîne par caractère</title>
<para>
Les caractères dans les <type>chaînes</type> peuvent être accédés et modifiés en
spécifiant l'offset basé sur zéro du caractère souhaité après la
<type>chaîne</type> à l'aide de crochets <type>array</type>, comme dans
<varname>$str[42]</varname>. Pensez à une <type>chaîne</type> comme à un
<type>tableau</type> de caractères à cette fin. Les fonctions
<function>substr</function> et <function>substr_replace</function>
peuvent être utilisées pour extraire ou remplacer plus d'un caractère.
</para>
<note>
<simpara>
À partir de PHP 7.1.0, les offsets de chaîne négatifs sont également supportés. Ceux-ci spécifient
l'offset à partir de la fin de la chaîne.
Auparavant, les offsets négatifs émettaient <constant>E_NOTICE</constant> pour la lecture
(produisant une chaîne vide) et <constant>E_WARNING</constant> pour l'écriture
(laissant la chaîne intacte).
</simpara>
</note>
<note>
<simpara>
Avant PHP 8.0.0, les <type>chaînes</type> pouvaient également être accédées en utilisant des accolades, comme dans
<varname>$str{42}</varname>, pour le même objectif.
Cette syntaxe des accolades a été dépréciée à partir de PHP 7.4.0 et n'est plus prise en charge à partir de PHP 8.0.0.
</simpara>
</note>
<warning>
<simpara>
Écrire à un offset hors de portée remplit la chaîne d'espaces.
Les types non entiers sont convertis en entier.
Un type d'offset illégal émet <constant>E_WARNING</constant>.
Seul le premier caractère d'une chaîne assignée est utilisé.
À partir de PHP 7.1.0, assigner une chaîne vide génère une erreur fatale. Auparavant,
cela assignait un octet NULL.
</simpara>
</warning>
<warning>
<simpara>
En interne, les chaînes PHP sont des tableaux d'octets. En conséquence, accéder ou
modifier une chaîne à l'aide de crochets de tableau n'est pas sûr pour les multi-octets, et
ne devrait être fait qu'avec des chaînes en encodage à un seul octet tel que ISO-8859-1.
</simpara>
</warning>
<note>
<simpara>
À partir de PHP 7.1.0, appliquer l'opérateur d'index vide sur une chaîne vide génère une erreur fatale.
Auparavant, la chaîne vide était silencieusement convertie en tableau.
</simpara>
</note>
<example>
<title>Quelques exemples de chaînes</title>
<programlisting role="php">
<![CDATA[
<?php
// Obtenez le premier caractère d'une chaîne
$str = 'Ceci est un test.';
$first = $str[0];
var_dump($first);
// Obtenez le troisième caractère d'une chaîne
$third = $str[2];
var_dump($third);
// Obtenez le dernier caractère d'une chaîne.
$str = 'Ceci est toujours un test.';
$last = $str[strlen($str)-1];
var_dump($last);
// Modifiez le dernier caractère d'une chaîne
$str = 'Regardez la mer';
$str[strlen($str)-1] = 'e';
var_dump($str);
?>
]]>
</programlisting>
</example>
<para>
Les offsets de chaîne doivent être des entiers ou des chaînes ressemblant à des entiers,
sinon un avertissement sera émis.
</para>
<example>
<title>Exemple d'offsets de chaîne illégaux</title>
<programlisting role="php">
<![CDATA[
<?php
$str = 'abc';
$keys = [ '1', '1.0', 'x', '1x' ];
foreach ($keys as $keyToTry) {
var_dump(isset($str[$keyToTry]));
try {
var_dump($str[$keyToTry]);
} catch (TypeError $e) {
echo $e->getMessage(), PHP_EOL;
}
echo PHP_EOL;
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
bool(true)
string(1) "b"
bool(false)
Cannot access offset of type string on string
bool(false)
Cannot access offset of type string on string
bool(false)
Warning: Illegal string offset "1x" in Standard input code on line 10
string(1) "b"
]]>
</screen>
</example>
<note>
<para>
Accéder à des variables d'autres types (à l'exception des tableaux ou objets
implémentant les interfaces appropriées) en utilisant <literal>[]</literal> ou
<literal>{}</literal> renvoie silencieusement &null;.
</para>
</note>
<note>
<para>
Les caractères dans les littéraux de chaîne peuvent être accédés
en utilisant <literal>[]</literal> ou <literal>{}</literal>.
</para>
</note>
<note>
<para>
Accéder à des caractères dans des littéraux de chaîne en utilisant la
syntaxe <literal>{}</literal> a été déprécié dans PHP 7.4.
Cela a été supprimé dans PHP 8.0.
</para>
</note>
</sect3>
</sect2><!-- fin de la syntaxe -->
<sect2 xml:id="language.types.string.useful-funcs">
<title>Fonctions et opérateurs utiles</title>
<para>
Les <type>chaînes</type> peuvent être concaténées à l'aide de l'opérateur '.' (point). Notez
que l'opérateur '+' (addition) ne fonctionnera <emphasis>pas</emphasis> pour cela.
Consulter <link linkend="language.operators.string">les opérateurs de chaîne</link> pour
plus d'informations.
</para>
<para>
Il existe plusieurs fonctions utiles pour la manipulation des <type>chaînes</type>.
</para>
<simpara>
Consulter la <link linkend="ref.strings">section des fonctions de chaîne</link> pour
les fonctions générales, et la <link linkend="ref.pcre">section des fonctions d'expressions régulières compatibles Perl</link> pour
des fonctionnalités avancées de recherche et de remplacement.
</simpara>
<simpara>
Il existe également des <link linkend="ref.url">fonctions pour les chaînes d'URL</link>, et
des fonctions pour chiffrer/déchiffrer des chaînes
(<link linkend="ref.sodium">Sodium</link> et
<link linkend="ref.hash">Hash</link>).
</simpara>
<simpara>
Enfin, consulter également les <link linkend="ref.ctype">fonctions de type caractère</link>.
</simpara>
</sect2>
<sect2 xml:id="language.types.string.casting">
<title>Conversion en chaîne</title>
<para>
Une valeur peut être convertie en <type>chaîne</type> à l'aide du
cast <literal>(string)</literal> ou de la fonction <function>strval</function>.
La conversion en <type>chaîne</type> est effectuée automatiquement dans le contexte d'une
expression où une <type>chaîne</type> est nécessaire. Cela se produit lors de l'utilisation des
fonctions <function>echo</function> ou <function>print</function>, ou lorsque
une variable est comparée à une <type>chaîne</type>. Les sections sur
<link linkend="language.types">Types</link> et
<link linkend="language.types.type-juggling">Type Juggling</link> clarifieront
ce qui suit. Voir également la fonction <function>settype</function>.
</para>
<para>
Une valeur <type>bool</type> &true; est convertie en la <type>chaîne</type>
<literal>"1"</literal>. La <type>bool</type> &false; est convertie en
<literal>""</literal> (la chaîne vide). Cela permet une conversion aller-retour entre
les valeurs <type>bool</type> et <type>chaîne</type>.
</para>
<para>
Un <type>int</type> ou <type>float</type> est converti en une
<type>chaîne</type> représentant le nombre textuellement (y compris la
partie exponentielle pour les <type>float</type>). Les nombres à virgule flottante peuvent être
convertis à l'aide de la notation exponentielle (<literal>4.1E+6</literal>).
</para>
<note>
<para>
À partir de PHP 8.0.0, le caractère de la virgule décimale est toujours
un point ("<literal>.</literal>"). Avant PHP 8.0.0,
le caractère de la virgule décimale est défini dans la locale du script (catégorie
LC_NUMERIC). Consulter la fonction <function>setlocale</function>.
</para>
</note>
<para>
Les <type>tableaux</type> sont toujours convertis en la <type>chaîne</type>
<literal>"Array"</literal>; de ce fait, <function>echo</function> et
<function>print</function> ne peuvent pas à eux seuls afficher le contenu d'un
<type>tableau</type>. Pour afficher un seul élément, utiliser une construction telle que
<literal>echo $arr['foo']</literal>. Consulter ci-dessous les conseils sur la visualisation de tout le contenu.
</para>
<para>
Afin de convertir des <type>objets</type> en <type>chaînes</type>, la méthode magique
<link linkend="language.oop5.magic">__toString</link> doit être utilisée.
</para>
<para>
Les <type>ressources</type> sont toujours converties en <type>chaînes</type> avec la
structure <literal>"Resource id #1"</literal>, où <literal>1</literal>
est le numéro de ressource attribué au <type>resource</type> par PHP à
l'exécution. Bien que la structure exacte de cette chaîne ne doive pas être considérée comme
fiable et soit sujette à changement, elle sera toujours unique pour une ressource donnée
pendant la durée d'exécution d'un script (c'est-à-dire une requête Web ou un processus CLI)
et ne sera pas réutilisée. Pour obtenir le type d'une <type>resource</type>, utiliser
la fonction <function>get_resource_type</function>.
</para>
<para>
&null; est toujours converti en une chaîne vide.
</para>
<para>
Comme indiqué ci-dessus, convertir directement un <type>tableau</type>,
un <type>objet</type> ou une <type>resource</type> en <type>chaîne</type> ne fournit
pas d'informations utiles sur la valeur au-delà de son type. Consulter les fonctions
<function>print_r</function> et <function>var_dump</function> pour
des moyens plus efficaces d'inspecter le contenu de ces types.
</para>
<para>
La plupart des valeurs PHP peuvent également être converties en <type>chaînes</type> pour un stockage permanent.
Cette méthode est appelée sérialisation et est effectuée par la fonction
<function>serialize</function>.
</para>
</sect2>
<sect2 xml:id="language.types.string.details">
<title>Détails du type chaîne</title>
<para>
La <type>chaîne</type> en PHP est implémentée comme un tableau d'octets et un
entier indiquant la longueur du tampon. Elle n'a aucune information sur la façon
dont ces octets se traduisent en caractères, laissant cette tâche au programmeur.
Il n'y a pas de limitations sur les valeurs que la chaîne peut être composée ; en
particulier, les octets de valeur <literal>0</literal> (« octets NUL ») sont autorisés
partout dans la chaîne (cependant, quelques fonctions, dites dans ce manuel de ne
pas être « sûres pour les binaires », peuvent transmettre les chaînes à des bibliothèques
qui ignorent les données après un octet NUL.)
</para>
<para>
Cette nature du type chaîne explique pourquoi il n'y a pas de type « octet » distinct
en PHP les chaînes prennent ce rôle. Les fonctions qui ne renvoient pas de données
textuelles par exemple, des données arbitraires lues à partir d'une socket réseau
renverront tout de même des chaînes.
</para>
<para>
Étant donné que PHP ne dicte pas un encodage spécifique pour les chaînes, on pourrait
se demander comment les littéraux de chaînes sont encodés. Par exemple, la chaîne
<literal>"á"</literal> est-elle équivalente à <literal>"\xE1"</literal> (ISO-8859-1),
<literal>"\xC3\xA1"</literal> (UTF-8, forme C),
<literal>"\x61\xCC\x81"</literal> (UTF-8, forme D) ou toute autre représentation
possible ? La réponse est que la chaîne sera encodée de la manière dont elle est
encodée dans le fichier script. Ainsi, si le script est écrit en ISO-8859-1, la
chaîne sera encodée en ISO-8859-1 et vice versa. Cependant, cela ne s'applique pas
si Zend Multibyte est activé ; dans ce cas, le script peut être écrit dans un
encodage arbitraire (qui est explicitement déclaré ou détecté) et ensuite converti
dans un certain encodage interne, qui sera ensuite l'encodage utilisé pour les
littéraux de chaînes.
Notez qu'il y a certaines contraintes sur l'encodage du script (ou sur l'encodage
interne, si Zend Multibyte est activé) cela signifie presque toujours que cet
encodage doit être un superset compatible de l'ASCII, tel que UTF-8 ou ISO-8859-1.
Notez cependant que les encodages dépendants de l'état où les mêmes valeurs d'octets
peuvent être utilisées dans des états de décalage initiaux et non initiaux peuvent
poser problème.
</para>
<para>
Bien sûr, afin d'être utiles, les fonctions qui opèrent sur du texte peuvent devoir
faire certaines hypothèses sur la façon dont la chaîne est encodée. Malheureusement,
il y a beaucoup de variations à ce sujet dans les fonctions de PHP :
</para>
<itemizedlist>
<listitem>
<simpara>
Certaines fonctions supposent que la chaîne est encodée dans un (tout) encodage
à un octet, mais elles n'ont pas besoin d'interpréter ces octets comme des
caractères spécifiques. C'est le cas, par exemple, de <function>substr</function>,
<function>strpos</function>, <function>strlen</function> ou
<function>strcmp</function>. Une autre façon de penser à ces fonctions est qu'elles
opèrent sur des tampons mémoire, c'est-à-dire qu'elles fonctionnent avec des octets
et des décalages d'octets.
</simpara>
</listitem>
<listitem>
<simpara>
D'autres fonctions reçoivent l'encodage de la chaîne, supposant éventuellement un
défaut si aucune information de ce type n'est donnée. C'est le cas de
<function>htmlentities</function> et de la majorité des fonctions dans
l'<link linkend="book.mbstring">extension mbstring</link>.
</simpara>
</listitem>
<listitem>
<simpara>
D'autres utilisent la locale actuelle (voir <function>setlocale</function>),
mais fonctionnent octet par octet.
</simpara>
</listitem>
<listitem>
<simpara>
Enfin, elles peuvent simplement supposer que la chaîne utilise un encodage
spécifique, généralement UTF-8. C'est le cas de la plupart des fonctions dans
l'<link linkend="book.intl">extension intl</link> et dans
l'<link linkend="book.pcre">extension PCRE</link>
(dans ce dernier cas, seulement lorsque le modificateur <literal>u</literal> est
utilisé).
</simpara>
</listitem>
</itemizedlist>
<para>
En fin de compte, cela signifie que l'écriture de programmes corrects utilisant
Unicode dépend d'éviter soigneusement les fonctions qui ne fonctionneront pas et
qui corrompront très probablement les données, et d'utiliser à la place les
fonctions qui se comportent correctement, généralement provenant des extensions
<link linkend="book.intl">intl</link> et <link linkend="book.mbstring">mbstring</link>.
Cependant, utiliser des fonctions capables de gérer les encodages Unicode n'est que
le début. Peu importe les fonctions que le langage fournit, il est essentiel de
connaître la spécification Unicode. Par exemple, un programme qui suppose qu'il
n'y a que des majuscules et des minuscules fait une hypothèse erronée.
</para>
</sect2>
</sect1><!-- end string -->
<!-- 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
-->