mirror of
https://github.com/php/doc-es.git
synced 2026-03-24 07:22:16 +01:00
522 lines
14 KiB
XML
522 lines
14 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 7a75b854c8c52226d38397e7e8177e339fdb273f Maintainer: seros Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<chapter xml:id="language.exceptions" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Excepciones</title>
|
|
<para>
|
|
PHP tiene un modelo de excepciones similar al de otros lenguajes de programación.
|
|
Una excepción puede ser lanzada ("&throw;n"), y atrapada ("&catch;ed") dentro de
|
|
PHP. El código puede estar dentro de un bloque &try; para facilitar la captura
|
|
de excepciones potenciales. Cada bloque &try; debe tener al menos un
|
|
bloque &catch; o &finally; correspondiente.
|
|
</para>
|
|
<para>
|
|
Si se lanza una excepción y el alcance de la función actual no tiene un bloque &catch;,
|
|
la excepción "subirá" por la pila de llamadas hasta encontrar un bloque &catch;
|
|
que coincida. Todos los bloques &finally; que encuentre en el camino se ejecutarán.
|
|
Si la pila de llamadas se desenrolla hasta el alcance global sin encontrar un bloque &catch;
|
|
coincidente, el programa terminará con un error fatal, a menos que se haya
|
|
configurado un manejador de excepciones global.
|
|
</para>
|
|
<para>
|
|
El objeto lanzado debe ser un &instanceof; <interfacename>Throwable</interfacename>.
|
|
Intentar lanzar un objeto que no lo sea resultará en un error fatal de PHP.
|
|
</para>
|
|
<para>
|
|
A partir de PHP 8.0.0, la palabra clave &throw; es una expresión y puede usarse en cualquier
|
|
contexto de expresión. En versiones anteriores, era una declaración y debía estar en su propia línea.
|
|
</para>
|
|
|
|
<sect1 annotations="chunk:false" xml:id="language.exceptions.catch">
|
|
<title><literal>catch</literal></title>
|
|
<para>
|
|
Se pueden usar múltiples bloques &catch; para atrapar diferentes clases de
|
|
excepciones. La ejecución normal (cuando no es lanzada ninguna excepción dentro del bloque
|
|
&try;) continuará después del último bloque &catch; definido en la sencuencia.
|
|
Las excepciones pueden ser lanzadas ("&throw;n") (o relanzadas) dentro de un bloque &catch;.
|
|
</para>
|
|
<para>
|
|
Cuando una excepción es lanzada, el código siguiente a la declaración no será
|
|
ejecutado, y PHP intentará encontrar el primer bloque &catch; coincidente.
|
|
Si una excepción no es capturada, se emitirá un Error Fatal de PHP con un
|
|
mensaje "<literal>Uncaught Exception ...</literal>" ("Excepción No Capturada"), a menos que se haya
|
|
definido un manejador con <function>set_exception_handler</function>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 annotations="chunk:false" xml:id="language.exceptions.finally">
|
|
<title><literal>finally</literal></title>
|
|
<para>
|
|
En PHP y posterior, se puede utilizar un bloque &finally; después o
|
|
en lugar de los bloques &catch;. El código de dentro del bloque &finally; siempre se
|
|
ejecutará después de los bloques &try; y &catch;, independientemente de que se haya
|
|
lanzado una excepción o no, y antes de que la ejecución normal continúe.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 annotations="chunk:false" xml:id="language.exceptions.exception-handler">
|
|
<title>Manejador global de excepciones</title>
|
|
<para>
|
|
Si se permite que una excepción suba hasta el alcance global, puede ser capturada
|
|
por un manejador global de excepciones si está configurado. La función <function>set_exception_handler</function>
|
|
puede establecer una función que será llamada en lugar de un bloque &catch; si no se invoca
|
|
ningún otro bloque. El efecto es esencialmente el mismo que si todo el programa
|
|
estuviera envuelto en un bloque &try;-&catch; con esa función como el &catch;.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 annotations="chunk:false" xml:id="language.exceptions.notes">
|
|
&reftitle.notes;
|
|
|
|
<note>
|
|
<para>
|
|
Las funciones internas de PHP utilizan principalmente la
|
|
<link linkend="ini.error-reporting">Información de Errores</link>, sólo las extensiones
|
|
<link linkend="language.oop5">Orientadas a objetos</link>
|
|
modernas utilizan excepciones. Sin embargo, los errores se pueden traducir a
|
|
excepciones simplemente con <link linkend="class.errorexception">ErrorException</link>.
|
|
</para>
|
|
<example>
|
|
<title>Convertir el informe de errores a excepciones</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">Biblioteca Estándar de PHP (SPL)</link> proporciona
|
|
una buena cantidad de <link linkend="spl.exceptions">excepciones integradas</link>.
|
|
</para>
|
|
</tip>
|
|
</sect1>
|
|
|
|
<sect1 annotations="chunk:false" xml:id="language.exceptions.examples">
|
|
&reftitle.examples;
|
|
|
|
<example>
|
|
<title>Lanzar una Excepción</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function inverso($x) {
|
|
if (!$x) {
|
|
throw new Exception('División por cero.');
|
|
}
|
|
return 1/$x;
|
|
}
|
|
|
|
try {
|
|
echo inverso(5) . "\n";
|
|
echo inverso(0) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Excepción capturada: ', $e->getMessage(), "\n";
|
|
}
|
|
|
|
// Continuar la ejecución
|
|
echo 'Hola Mundo\n';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
0.2
|
|
Excepción capturada: División por cero.
|
|
Hola Mundo
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Manejo de excepciones con un bloque <literal>finally</literal></title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function inverse($x) {
|
|
if (!$x) {
|
|
throw new Exception('División por cero.');
|
|
}
|
|
return 1/$x;
|
|
}
|
|
|
|
try {
|
|
echo inverse(5) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Excepción capturada: ', $e->getMessage(), "\n";
|
|
} finally {
|
|
echo "Primer finally.\n";
|
|
}
|
|
|
|
try {
|
|
echo inverse(0) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Excepción capturada: ', $e->getMessage(), "\n";
|
|
} finally {
|
|
echo "Segundo finally.\n";
|
|
}
|
|
|
|
// Continuar ejecución
|
|
echo 'Hola Mundo\n';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
0.2
|
|
Primer finally.
|
|
Excepción capturada: División por cero.
|
|
Segundo finally.
|
|
Hola Mundo
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Interaction between the &finally; block and &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>Excepciones anidadas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class MiExcepción extends Exception { }
|
|
|
|
class Prueba {
|
|
public function probar() {
|
|
try {
|
|
try {
|
|
throw new MiExcepción('foo!');
|
|
} catch (MiExcepción $e) {
|
|
// relanzarla
|
|
throw $e;
|
|
}
|
|
} catch (Exception $e) {
|
|
var_dump($e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
$foo = new Prueba;
|
|
$foo->probar();
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
string(4) "foo!"
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<example>
|
|
<title>Multi catch exception handling</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>Omitting the caught variable</title>
|
|
<para>Only permitted in PHP 8.0.0 and later.</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 as an expression</title>
|
|
<para>Only permitted in PHP 8.0.0 and later.</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function test() {
|
|
do_something_risky() or throw new Exception('It did not work');
|
|
}
|
|
|
|
try {
|
|
test();
|
|
} catch (Exception $e) {
|
|
print $e->getMessage();
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.exceptions.extending">
|
|
<title>Ampliar las Excepciones</title>
|
|
<para>
|
|
Una clase de Excepción definida por el usuario puede ser definida ampliando la clase
|
|
Exception interna. Los miembros y las propiedades de abajo muestran lo que es accesible
|
|
dentro de la clase hija que deriva de la clase Exception interna.
|
|
</para>
|
|
<example>
|
|
<title>La clase Exception Interna</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Exception
|
|
{
|
|
protected $message = 'Unknown exception'; // mensaje de excepción
|
|
private $string; // caché de __toString
|
|
protected $code = 0; // código de excepción definido por el usuario
|
|
protected $file; // nombre de archivo fuente de la excepción
|
|
protected $line; // línea fuente de la excepción
|
|
private $trace; // determinación del origen
|
|
private $previous; // excepción previa si la excepción está anidada
|
|
|
|
public function __construct($message = null, $code = 0, Exception $previous = null);
|
|
|
|
final private function __clone(); // Inhibe la clonación de excepciones.
|
|
|
|
final public function getMessage(); // mensaje de excepción
|
|
final public function getCode(); // código de excepción
|
|
final public function getFile(); // nombre de archivo fuente
|
|
final public function getLine(); // línea fuente
|
|
final public function getTrace(); // un array de backtrace()
|
|
final public function getPrevious(); // excepción anterior
|
|
final public function getTraceAsString(); // string formateado del seguimiento del origen
|
|
|
|
// Sobrescribible
|
|
public function __toString(); // string formateado para mostrar
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<para>
|
|
Si una clase extiende la clase Exception interna y redefine el <link
|
|
linkend="language.oop5.decon">constructor</link>, se recomienda encarecidamente
|
|
que también llame a <link
|
|
linkend="language.oop5.paamayim-nekudotayim">parent::__construct()</link>
|
|
para asegurarse que toda la información disponible haya sido asignada apropiadamente. El
|
|
método <link linkend="language.oop5.magic">__toString()</link> puede ser sobrescrito
|
|
para proporcionar una salida personalizada cuando el objeto es presentado como un string.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Las excepciones no se pueden clonar. Intentar <link
|
|
linkend="language.oop5.cloning">clonar</link> una Excepción resultará en un
|
|
error <constant>E_ERROR</constant> fatal.
|
|
</para>
|
|
</note>
|
|
<example>
|
|
<title>Extender la clase Exception</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
/**
|
|
* Definir una clase de excepción personalizada
|
|
*/
|
|
class MiExcepción extends Exception
|
|
{
|
|
// Redefinir la excepción, por lo que el mensaje no es opcional
|
|
public function __construct($message, $code = 0, Exception $previous = null) {
|
|
// algo de código
|
|
|
|
// asegúrese de que todo está asignado apropiadamente
|
|
parent::__construct($message, $code, $previous);
|
|
}
|
|
|
|
// representación de cadena personalizada del objeto
|
|
public function __toString() {
|
|
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
|
|
}
|
|
|
|
public function funciónPersonalizada() {
|
|
echo "Una función personalizada para este tipo de excepción\n";
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Crear una clase para probar la excepción
|
|
*/
|
|
class ProbarExcepción
|
|
{
|
|
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:
|
|
// lanzar la excepción personalizada
|
|
throw new MiExcepción('1 no es un parámetro válido', 5);
|
|
break;
|
|
|
|
case self::THROW_DEFAULT:
|
|
// lanzar la predeterminada.
|
|
throw new Exception('2 no está permitido como parámetro', 6);
|
|
break;
|
|
|
|
default:
|
|
// No hay excepción, el objeto se creará.
|
|
$this->var = $avalue;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Ejemplo 1
|
|
try {
|
|
$o = new ProbarExcepción(ProbarExcepción::THROW_CUSTOM);
|
|
} catch (MiExcepción $e) { // Será atrapada
|
|
echo "Atrapada mi excepción\n", $e;
|
|
$e->funciónPersonalizada();
|
|
} catch (Exception $e) { // Skipped
|
|
echo "Atrapada la Excepción Predeterminada\n", $e;
|
|
}
|
|
|
|
// Continuar la ejecución
|
|
var_dump($o); // Null
|
|
echo "\n\n";
|
|
|
|
|
|
// Ejemplo 2
|
|
try {
|
|
$o = new ProbarExcepción(ProbarExcepción::THROW_DEFAULT);
|
|
} catch (MiExcepción $e) { // Este tipo no coincide
|
|
echo "Atrapada mi excepción\n", $e;
|
|
$e->funciónPersonalizada();
|
|
} catch (Exception $e) { // Will be caught
|
|
echo "Atrapada la Excepción Predeterminada\n", $e;
|
|
}
|
|
|
|
// Continuar la ejecución
|
|
var_dump($o); // Null
|
|
echo "\n\n";
|
|
|
|
|
|
// Ejemplo 3
|
|
try {
|
|
$o = new ProbarExcepción(ProbarExcepción::THROW_CUSTOM);
|
|
} catch (Exception $e) { // Será atrapada
|
|
echo "Atrapada la Excepción Predeterminada\n", $e;
|
|
}
|
|
|
|
// Continuar la ejecución
|
|
var_dump($o); // Null
|
|
echo "\n\n";
|
|
|
|
|
|
// Ejemplo 4
|
|
try {
|
|
$o = new ProbarExcepción();
|
|
} catch (Exception $e) { // Saltado, sin excepción
|
|
echo "Atrapada la Excepción Predeterminada\n", $e;
|
|
}
|
|
|
|
// Continuar la ejecución
|
|
var_dump($o); // ProbarExcepción
|
|
echo "\n\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</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
|
|
-->
|