php error-handling try-catch

php - ¿Por qué usar la palabra clave "finalmente"?



error-handling try-catch (2)

Esta pregunta ya tiene una respuesta aquí:

Entiendo para qué se usa la palabra clave "finalmente" en varios idiomas, sin embargo, me cuesta entender por qué la usarías fuera de que exista una preferencia de formato en el gusto.

Por ejemplo, en PHP:

try { possibleErrorThrownFunction(); } catch (CustomException $customException) { // handle custom error } catch (Exception $exception) { // handle the error } finally { // run this code every single time regardless of error or not }

¿Cuál es la diferencia entre lo que está haciendo este código y esto?

try { possibleErrorThrownFunction(); } catch (CustomException $customException) { // handle custom error } catch (Exception $exception) { // handle the error } // run this code every single time regardless of error or not

¿Esa última línea no siempre se ejecuta de todos modos debido a que se detecta el error? En cuyo caso, no hay ningún caso para usar realmente, a menos que solo desee mantener un formato de estilo de código.

Un ejemplo de un caso en el que una declaración finally es necesaria y distinta de simplemente poner código después de las declaraciones try / catch sería útil si me falta algo aquí.


Respuesta corta

Finally , se garantiza que los bloques se ejecuten sin importar lo que suceda dentro de los bloques try y catch , antes de permitir que el programa se bloquee.

Esto se explica aquí: https://www.php.net/manual/en/language.exceptions.php aunque la explicación no es particularmente detallada.

Algunos detalles más

Un ejemplo que me viene a la cabeza es si se trata de flujos de entrada / salida o algo similar que debe cerrarse después de su uso para evitar una pérdida de memoria. Para usar su ejemplo:

try { memoryUser.startReading(someFileOrSomething); } catch (CustomException $customException) { // handle custom error } catch (Exception $exception) { // handle the error invisibleBug.whoops(); // i.e. something goes wrong in this block } memoryUser.Close(); // because something went wrong in the catch block, // this never runs, which, in this case, causes a memory leak

En este caso, envolviendo el memoryUser.Close(); en un bloque finally se aseguraría de que esa línea se ejecute antes de que explote el resto del programa, evitando la pérdida de memoria incluso en un fallo catastrófico.

TL; DR

Por lo tanto, la mayoría de las veces, la gente coloca el bloque finalmente allí para garantizar que se ejecute una línea importante, incluso si pasan por alto algo en los bloques de captura. Así es como siempre lo he visto usado.

Esperemos que esto ayude :)


Lo especial de un bloque finally {} es que siempre se ejecutará al final del bloque try {} .

  • Se ejecutará si el código en el bloque try {} se completa con éxito.

  • Se ejecutará si el código en el bloque try {} arroja una excepción que fue atrapada por un catch {} . ( finally {} ejecuta después de la catch {} .)

  • Se ejecutará si el código en el bloque try {} arroja una excepción que no fue manejada por ningún bloque catch {} , o si no hubo ninguno. (El bloque finally {} se ejecuta antes de que la excepción se propague a la persona que llama).

  • Se ejecutará si el código en el bloque try {} arroja una excepción, y el código en el catch {} arroja otra excepción (o vuelve a lanzar la misma excepción).

  • Incluso se ejecutará si el código en el bloque try {} , o en un bloque catch {} , usa return . (Al igual que con una excepción no detectada, el finally {} ejecuta antes de que la función realmente regrese). ¡El bloque finally {} puede incluso usar el propio return , y su valor de retorno anulará el valor que el otro bloque intentó devolver!

(Hay un caso extremo en el que finally {} no se ejecutará un bloque finally {} , y es si todo el proceso se destruye, por ejemplo, al ser asesinado o al llamar a exit() o die() .)