mirror of
https://github.com/macintoshplus/doc-fr.git
synced 2026-03-25 17:32:07 +01:00
Applied commits: - php/doc-en@2e8ef0a1bd (empty) - php/doc-en@de9c65c91f - php/doc-en@b890f28c0c - php/doc-en@0da76b0197 - php/doc-en@8782bc7340 (empty)
575 lines
16 KiB
XML
575 lines
16 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 2e8ef0a1bd98243cb2c6c5c627a195bb53a7a440 Maintainer: yannick Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
|
|
<chapter xml:id="language.exceptions" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Les exceptions</title>
|
|
|
|
<sect1 xml:id="language.exceptions.extending">
|
|
<title>Exceptions étendues</title>
|
|
<para>
|
|
Une classe d'exception écrite par l'utilisateur peut être définie en étendant
|
|
la classe Exception interne. Les membres et les propriétés suivants
|
|
montrent ce qui est accessible dans la classe enfant qui est dérivée de la
|
|
classe Exception interne.
|
|
</para>
|
|
<example>
|
|
<title>La classe Exception interne</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Exception implements Throwable
|
|
{
|
|
protected $message = 'Exception inconnue'; // message de l'exception
|
|
private $string; // __toString cache
|
|
protected $code = 0; // code de l'exception défini par l'utilisateur
|
|
protected $file; // nom du fichier source de l'exception
|
|
protected $line; // ligne de la source de l'exception
|
|
private $trace; // backtrace
|
|
private $previous; // exception précédente (depuis PHP 5.3)
|
|
|
|
public function __construct($message = '', $code = 0, Throwable $previous = null);
|
|
|
|
final private function __clone(); // Inhibe le clonage des exceptions.
|
|
|
|
final public function getMessage(); // message de l'exception
|
|
final public function getCode(); // code de l'exception
|
|
final public function getFile(); // nom du fichier source
|
|
final public function getLine(); // ligne du fichier source
|
|
final public function getTrace(); // un tableau de backtrace()
|
|
final public function getPrevious(); // exception précédente (depuis PHP 5.3)
|
|
final public function getTraceAsString(); // chaîne formatée de trace
|
|
|
|
// Remplaçable
|
|
public function __toString(); // chaîne formatée pour l'affichage
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Si une classe étend la classe Exception interne et redéfinit le <link
|
|
linkend="language.oop5.decon">constructeur</link>, il est vivement
|
|
recommandé qu'elle appelle aussi
|
|
<link linkend="language.oop5.paamayim-nekudotayim">
|
|
<literal>parent::__construct()</literal></link>
|
|
pour s'assurer que toutes les données disponibles ont été proprement
|
|
assignées. La méthode
|
|
<link linkend="language.oop5.magic">__toString()</link> peut être réécrite
|
|
pour fournir un affichage personnalisé lorsque l'objet est présenté comme
|
|
une chaîne.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Les exceptions ne peuvent pas être clonées. Si vous tentez
|
|
de <link linkend="language.oop5.cloning">cloner</link> une
|
|
exception, une erreur fatale (<constant>E_ERROR</constant>)
|
|
sera émise.
|
|
</para>
|
|
</note>
|
|
<example>
|
|
<title>Étendre la classe Exception</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
/**
|
|
* Définition d'une classe d'exception personnalisée
|
|
*/
|
|
class MyException extends Exception
|
|
{
|
|
// Redéfinissez l'exception ainsi le message n'est pas facultatif
|
|
public function __construct($message, $code = 0, Throwable $previous = null) {
|
|
|
|
// traitement personnalisé que vous voulez réaliser ...
|
|
|
|
// assurez-vous que tout a été assigné proprement
|
|
parent::__construct($message, $code, $previous);
|
|
}
|
|
|
|
// chaîne personnalisée représentant l'objet
|
|
public function __toString() {
|
|
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
|
|
}
|
|
|
|
public function customFunction() {
|
|
echo "Une fonction personnalisée pour ce type d'exception\n";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Création d'une classe pour tester l'exception
|
|
*/
|
|
class TestException
|
|
{
|
|
public $var;
|
|
|
|
const THROW_NONE = 0;
|
|
const THROW_CUSTOM = 1;
|
|
const THROW_DEFAULT = 2;
|
|
|
|
function __construct($avalue = self::THROW_NONE) {
|
|
|
|
switch ($avalue) {
|
|
case self::THROW_CUSTOM:
|
|
// lance une exception personnalisée
|
|
throw new MyException('1 est un paramètre invalide', 5);
|
|
break;
|
|
|
|
case self::THROW_DEFAULT:
|
|
// lance l'exception par défaut.
|
|
throw new Exception('2 n\'est pas autorisé en tant que paramètre', 6);
|
|
|
|
break;
|
|
|
|
default:
|
|
// Aucune exception, l'objet sera créé.
|
|
$this->var = $avalue;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Exemple 1
|
|
try {
|
|
$o = new TestException(TestException::THROW_CUSTOM);
|
|
} catch (MyException $e) { // Devrait être attrapée
|
|
echo "Capture mon exception\n", $e;
|
|
$e->customFunction();
|
|
} catch (Exception $e) { // Sauté
|
|
echo "Capture l'exception par défaut\n", $e;
|
|
}
|
|
|
|
// Continue l'exécution
|
|
var_dump($o); // Null
|
|
echo "\n\n";
|
|
|
|
|
|
//Exemple 2
|
|
try {
|
|
$o = new TestException(TestException::THROW_DEFAULT);
|
|
} catch (MyException $e) { // Ne correspond pas à ce type
|
|
echo "Capture mon exception\n", $e;
|
|
$e->customFunction();
|
|
} catch (Exception $e) { // Devrait être attrapée
|
|
echo "Capture l'exception par défaut\n", $e;
|
|
}
|
|
|
|
// Continue l'exécution
|
|
var_dump($o); // Null
|
|
echo "\n\n";
|
|
|
|
|
|
// Exemple 3
|
|
try {
|
|
$o = new TestException(TestException::THROW_CUSTOM);
|
|
} catch (Exception $e) { // Devrait être attrapée
|
|
echo "Capture l'exception par défaut\n", $e;
|
|
}
|
|
|
|
// Continue l'exécution
|
|
var_dump($o); // Null
|
|
echo "\n\n";
|
|
|
|
|
|
// Exemple 4
|
|
try {
|
|
$o = new TestException();
|
|
} catch (Exception $e) { // sauté, aucune exception
|
|
echo "Capture l'exception par défaut\n", $e;
|
|
}
|
|
|
|
// Continue l'exécution
|
|
var_dump($o); // TestException
|
|
echo "\n\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</sect1>
|
|
|
|
<simplesect xml:id="language.exceptions.introduction">
|
|
<para>
|
|
PHP a une gestion des exceptions similaire à ce qu'offrent les autres
|
|
langages de programmation.
|
|
Une exception peut être lancée ("&throw;") et attrapée
|
|
("&catch;") dans PHP. Le code devra être entouré
|
|
d'un bloc &try; pour faciliter la saisie d'une exception
|
|
potentielle. Chaque &try; doit avoir au moins
|
|
un bloc &catch; ou &finally; correspondant.
|
|
</para>
|
|
|
|
<para>
|
|
Si une exception est lancée et que la portée courante de la fonction n'a pas
|
|
de block &catch;, l'exception "remontera" la pile d'appel de la fonction appelante
|
|
jusqu'à trouver un bloc &catch; correspondant. Tous les blocs &finally; rencontrés
|
|
seront exécutés. Si la pile d'appel est déroulée jusqu'à la portée globale sans
|
|
rencontrer de bloc &catch; correspondant, le programme sera terminé avec
|
|
une erreur fatale sauf si un gestionnaire global d'exception a été défini.
|
|
</para>
|
|
<para>
|
|
L'objet lancé doit être une instance de la classe
|
|
<classname>Exception</classname> ou d'une sous-classe de la classe
|
|
<classname>Exception</classname>. Tenter de lancer un objet qui ne
|
|
correspond pas à cela résultera en une erreur fatale émise par PHP.
|
|
</para>
|
|
<para>
|
|
À partir de PHP 8.0.0, le mot clé &throw; est une expression et peut être
|
|
utilisé dans n'importe quel contexte d'expressions. Dans les versions
|
|
antérieures c'était une déclaration qui devait être sur sa propre ligne.
|
|
</para>
|
|
</simplesect>
|
|
|
|
<simplesect xml:id="language.exceptions.catch">
|
|
<title><literal>catch</literal></title>
|
|
<para>
|
|
Un bloc &catch; définit comment réagir à une exception qui a été lancée.
|
|
Un bloc &catch; définit un ou plusieurs types d'exceptions ou erreurs qu'il peut
|
|
gérer, et optionnellement une variable dans laquelle assigner l'exception.
|
|
(Cette variable était requise dans les versions antérieures à PHP 8.0.0)
|
|
Le premier bloc &catch; qu'une exception ou erreur lancée rencontre et qui correspond au
|
|
type de l'objet lancé gérera l'objet.
|
|
</para>
|
|
<para>
|
|
Plusieurs blocs &catch; peuvent être utilisés pour attraper différentes
|
|
classes d'exceptions. L'exécution normale (lorsqu'aucune exception n'est lancée
|
|
dans le bloc &try;) continue après le dernier
|
|
bloc &catch; défini dans la séquence. Les exceptions
|
|
peuvent être lancées (&throw;) ou relancées dans un bloc &catch;. Sinon,
|
|
l'exécution continuera après le bloc &catch; qui a été déclenché.
|
|
</para>
|
|
<para>
|
|
Lorsqu'une exception est lancée, le code suivant le traitement ne sera pas
|
|
exécuté et PHP tentera de trouver le premier bloc &catch; correspondant.
|
|
Si une exception n'est pas attrapée, une erreur fatale issue de PHP sera
|
|
envoyée avec un message "<literal>Uncaught Exception ...</literal>"
|
|
indiquant que l'exception n'a pu être attrapée à moins qu'un gestionnaire
|
|
d'exceptions ne soit défini avec la fonction
|
|
<function>set_exception_handler</function>.
|
|
</para>
|
|
<para>
|
|
À partir de PHP 7.1, un block &catch; peut spécifier plusieurs exceptions à
|
|
l'aide du caratère pipe (<literal>|</literal>). Ceci est utile lorsque
|
|
différentes exceptions de hiérarchies de classes différentes sont traitées
|
|
de la même manière.
|
|
</para>
|
|
<para>
|
|
À partir de PHP 8.0.0, le nom de variable pour l'exception attrapée est
|
|
optionnel. Si non spécifié, le bloc &catch; sera toujours exécuté mais
|
|
n'aura pas accès à l'objet lancé.
|
|
</para>
|
|
</simplesect>
|
|
|
|
<simplesect xml:id="language.exceptions.finally">
|
|
<title><literal>finally</literal></title>
|
|
<para>
|
|
Un bloc &finally; peut aussi être
|
|
spécifié après des blocs &catch;. Le code à l'intérieur
|
|
du bloc &finally; sera toujours exécuté après les blocs
|
|
&try; et &catch;, indépendamment du fait qu'une
|
|
exception a été lancée, avant de continuer l'exécution normale.
|
|
</para>
|
|
<para>
|
|
Une interaction notable est entre un bloc &finally; et une déclaration
|
|
&return;.
|
|
Si une déclaration &return; est rencontrée à l'intérieur des blocs &try;
|
|
ou &catch;, le bloc &finally; sera quand même exécuté. De plus,
|
|
la déclaration &return; est évaluée quand elle est rencontrée, mais le
|
|
résultat sera retourné après que le bloc &finally; soit exécuté.
|
|
Additionnellement, si le bloc &finally; contient aussi une déclaration
|
|
&return; la valeur du bloc &finally; est retournée.
|
|
</para>
|
|
</simplesect>
|
|
|
|
<simplesect xml:id="language.exceptions.exception-handler">
|
|
<title><literal>Global exception handler</literal></title>
|
|
<para>
|
|
Si une exception est autorisée à remonter jusqu'à la portée globale, elle peut
|
|
être attrapée par un gestionnaire d'exceptions global si il a été défini. La fonction
|
|
<function>set_exception_handler</function> peut définir une fonction qui sera
|
|
appelée à la place d'un block &catch; si aucun autre block n'est invoqué.
|
|
L'effet est essentiellement identique à entourer le programme entier dans un
|
|
block &try;-&catch; avec cette fonction en tant que &catch;.
|
|
</para>
|
|
</simplesect>
|
|
|
|
|
|
<simplesect xml:id="language.exceptions.notes">
|
|
&reftitle.notes;
|
|
|
|
<note>
|
|
<para>
|
|
Les fonctions internes de PHP utilisent principalement l'
|
|
<link linkend="ini.error-reporting">Error reporting</link>, seules les extensions
|
|
<link linkend="language.oop5">orientées objet</link>
|
|
utilisent les exceptions. Quoiqu'il en soit, des erreurs peuvent facilement être traduites en
|
|
exceptions avec <link linkend="class.errorexception">ErrorException</link>.
|
|
Cependant, cette technique ne fonctionne que pour les erreurs non fatales.
|
|
</para>
|
|
<example>
|
|
<title>Convertir l'error reporting en exceptions</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function exceptions_error_handler($severity, $message, $filename, $lineno) {
|
|
throw new ErrorException($message, 0, $severity, $filename, $lineno);
|
|
}
|
|
|
|
set_error_handler('exceptions_error_handler');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</note>
|
|
<tip>
|
|
<para>
|
|
La <link linkend="intro.spl">bibliothèque standard PHP (SPL)</link> fournit
|
|
un bon nombre <link linkend="spl.exceptions">d'exceptions additionnelles</link>.
|
|
</para>
|
|
</tip>
|
|
</simplesect>
|
|
|
|
<simplesect xml:id="language.exceptions.examples">
|
|
&reftitle.examples;
|
|
|
|
<example>
|
|
<title>Lancer une exception</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function inverse($x) {
|
|
if (!$x) {
|
|
throw new Exception('Division par zéro.');
|
|
}
|
|
return 1/$x;
|
|
}
|
|
|
|
try {
|
|
echo inverse(5) . "\n";
|
|
echo inverse(0) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Exception reçue : ', $e->getMessage(), "\n";
|
|
}
|
|
|
|
// Continue execution
|
|
echo "Bonjour le monde !\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
0.2
|
|
Exception reçue : Division par zéro.
|
|
Bonjour le monde !
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Gestion de l'exception avec un bloc &finally;</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function inverse($x) {
|
|
if (!$x) {
|
|
throw new Exception('Division par zéro.');
|
|
}
|
|
return 1/$x;
|
|
}
|
|
|
|
try {
|
|
echo inverse(5) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Exception reçue : ', $e->getMessage(), "\n";
|
|
} finally {
|
|
echo "Première fin.\n";
|
|
}
|
|
|
|
try {
|
|
echo inverse(0) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Exception reçue : ', $e->getMessage(), "\n";
|
|
} finally {
|
|
echo "Seconde fin.\n";
|
|
}
|
|
|
|
// On continue l'exécution
|
|
echo "Bonjour le monde !\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
0.2
|
|
Première fin.
|
|
Exception reçue : Division par zéro.
|
|
Seconde fin.
|
|
Bonjour le monde !
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Interaction entre le bloc &finally; et &return;</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function test() {
|
|
try {
|
|
throw new Exception('foo');
|
|
} catch (Exception $e) {
|
|
return 'catch';
|
|
} finally {
|
|
return 'finally';
|
|
}
|
|
}
|
|
|
|
echo test();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
finally
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Héritage d'une exception</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class MyException extends Exception { }
|
|
|
|
class Test {
|
|
public function testing() {
|
|
try {
|
|
try {
|
|
throw new MyException('foo!');
|
|
} catch (MyException $e) {
|
|
// on la relance
|
|
throw $e;
|
|
}
|
|
} catch (Exception $e) {
|
|
var_dump($e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
$foo = new Test;
|
|
$foo->testing();
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
string(4) "foo!"
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Gestion des exceptions de capture multiple</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class MyException extends Exception { }
|
|
|
|
class MyOtherException extends Exception { }
|
|
|
|
class Test {
|
|
public function testing() {
|
|
try {
|
|
throw new MyException();
|
|
} catch (MyException | MyOtherException $e) {
|
|
var_dump(get_class($e));
|
|
}
|
|
}
|
|
}
|
|
|
|
$foo = new Test;
|
|
$foo->testing();
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
string(11) "MyException"
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Omettre la variable attrapé</title>
|
|
<para>Seulement permis dans PHP 8.0.0 et ultérieur.</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class SpecificException extends Exception {}
|
|
|
|
function test() {
|
|
throw new SpecificException('Oopsie');
|
|
}
|
|
|
|
try {
|
|
test();
|
|
} catch (SpecificException) {
|
|
print "A SpecificException was thrown, but we don't care about the details.";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<example>
|
|
<title>Throw en tant qu'expression</title>
|
|
<para>Seulement permis dans PHP 8.0.0 et ultérieur.</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class SpecificException extends Exception {}
|
|
|
|
function test() {
|
|
do_something_risky() or throw new Exception('It did not work');
|
|
}
|
|
|
|
try {
|
|
test();
|
|
} catch (Exception $e) {
|
|
print $e->getMessage();
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</simplesect>
|
|
</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
|
|
-->
|