Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
O PHP 5.5 adiciona suporte para os blocos finally, que existem no Java e no Ruby (ensure) e provavelmente em outras linguagens.
Eu entendo que o finally é executado independentemente de o try ter falhado e caído em um catch ou não (me corrijam se estiver errado).
Mas qual o propósito disso? seria a mesma coisa de escrever um código depois do último catch?
É também um meio de evitar duplicação de código. Não tenho acesso ao 5.5 aqui para testar, mas o cenário, mesmo que sintaticamente errado pode valer a pena:
Sem finally
$conn = new MySQLi( /** ... */ );
try {
// Do something with MySQLi Object
} catch( Exception $e ) {
$conn -> close();
// Handles the Exception
}
$conn -> close();
Com finally
$conn = new MySQLi( /** ... */ );
try {
// Do something with MySQLi Object
} catch( Exception $e ) {
// Handles the Exception
} finally {
$conn -> close();
}
E a conexão será fechada independentemente de ter havido um sucesso ou um erro.
Mas, como andei lendo em alguns blogs Internet a fora, não é um recursos assim tão importante pelo menos não para programadores mais experientes que manipulam suas conexões de forma mais abstrata que se encerram automaticamente quando os objetos são destruídos.
A questão é que o finally faz parte do try-catch.
Como bem explicou o @João Rafael Martins, o bloco dentro do finally vai ser executado sempre, independente de você ter ou não um retorno, ou que você repasse a exceção para fora da pilha
<?php
class MyOuterException extends Exception {}
class MyInnerException extends Exception {}
function outer ($launchAnException = null) {
$inner = function () use ($launchAnException) {
if ($launchAnException) {
throw new MyInnerException();
}
printf('inner goes well' . PHP_EOL);
};
try {
$inner();
} catch(MyInnerException $e) {
throw new MyOuterException('Hello');
// O escopo de outer é encerrado aqui.
} finally {
// Ei, espere, tem que executar isso ANTES de
// lançar MyOuterException
printf('Hello from finally' . PHP_EOL);
// Agora sim, está liberado. Pode lançar aquela
// exceção que você queria.
}
}
printf('Calling whithout arguments...' . PHP_EOL);
outer();
try {
printf(PHP_EOL . 'Please, throw me an awesome exception (yn)...' . PHP_EOL);
outer(true); printf('MyOuterException says: "%s".', $e->getMessage());
}Eu entendi melhor agora, mas ainda não vejo o uso dele como algo útil, uma vez que utilizo eventos para manipular as exceptions, logs, etc etc.
Melhorando minha pergunta: teria algo que sem finally não conseguiríamos fazer? ou ele é apenas um goto da vida?
Longe de ser goto. Ele é o ponto de convergência entre o Try e os diversos catch'es possíveis. Como o @Bruno Augusto disse, é pra evitar duplicação de código
try {
if (foo) {
throw new FooException();
}
bar();
baz(); log_error($e->getMessage());
baz();
}try {
if (foo) {
throw new FooException();
}
bar(); log_error($e->getMessage());
}
baz();try {
if (foo) {
throw new FooException();
}
return bar();class MyOuterException extends Exception {}
class MyInnerException extends Exception {}
function outer ($launchAnException = null) {
$inner = function () use ($launchAnException) {
if ($launchAnException) {
throw new MyOuterException();
}
printf('inner goes well' . PHP_EOL);
};
try {
$inner();
} catch(MyInnerException $e) {
throw new MyOuterException('Hello');
// O escopo de outer é encerrado aqui.
} finally {
// Ei, espere, tem que executar isso ANTES de
// lançar MyOuterException
printf('Hello from finally' . PHP_EOL);
// Agora sim, está liberado. Pode lançar aquela
// exceção que você queria.
}
}
outer(true);
Seria quase a mesma coisa, porém o finally é executado antes de sair do try/catch/finally block. ex:
/* Output:
Finally called!
42
*/
fonte: http://www.adayinthelifeof.nl/2013/02/12/php5-5-trycatchfinally/