Tratamento de exceções do PHP: uma introdução para iniciantes

O PHP possui um controle de exceções muito similar a outras linguagens de programação, fazendo com que o tratamento de exceções seja uma ferramenta muito interessante para os usuários da linguagem. Este artigo trata do controle e tratamento de exceções do PHP utilizando uma linguagem simples voltada para aqueles que não conhecem nada do assunto.

[ Hits: 34.207 ]

Por: EVERTON DA ROSA em 31/03/2011 | Blog: http://everton3x.github.io


Um exemplo um pouco mais complexo



Agora que sabemos o básico sobre tratamento de exceções no PHP, podemos trabalhar com um exemplo um pouco mais complexo.

Para isso, vamos utilizar um script PHP/HTML representando um sistema de login (apenas fins didáticos).

<?php
if($_POST['action'] == 'login'){//Se $_POST['action'] está definida...
    //Validação dos campos do formulário
    try{//tente..
        if(!$_POST['user'] OR !$_POST['password']){//se $_POST['user'] ou $_POST['password'] não forma definidos...
            throw new Exception('Usuário ou senha em branco!');//... dipare uma exceção
        }
    }catch(Exception $e){//...se try falhar, pegue a exceção...
        echo $e->getMessage();//... exiba a mensagem e...
        goto fim;//.. vá para o final (usado apenas para garantir que o formulário de login seja exibido)
    }

    //Realizar login
    try{//... se validação foi positiva, tente...
        if($_POST['user'] != 'guest' OR $_POST['password'] != '123'){//se usuário e senha não conferem...
            throw new Exception('Usuário ou senha não conferem');//... dispare uma exceção

        }else{//...senão...
            echo 'Login realizado!';//..escreva esta mensagem
        }
    }catch(Exception $e){//se try falhar...
        echo $e->getMessage();//... exiba a mensagem e...
        goto fim;//.. vá para o final (usado apenas para garantir que o formulário de login seja exibido)
    }
}

fim://apenas para fazer o formulário ser exibido.
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>
    </head>
    <body>
        <form method="post">
            <fieldset>
                <legend>Login</legend>
                <label for="user">Usuário</label>
                <input id="user" name="user" type="text" />
                <label for="password">Senha</label>
                <input id="password" name="password" type="password" />

                <!--
                Este campo serve para ativar o processo de login.
                -->
                <input name="action" type="hidden" value="login"/>
            </fieldset>
            <input type="submit" value="Enviar" />
            <input type="reset" value="Limpar" />

        </form>
    </body>
</html>

Como podemos ver no código acima, se a variável "action" for passada para a página do script (via POST), o script de login PHP será executado.

if($_POST['action'] == 'login'){

Primeiramente é feita a validação dos campos, ou seja, se os campos "user" e "password" foram passados:

try{//tente..
        if(!$_POST['user'] OR !$_POST['password']){//se $_POST['user'] ou $_POST['password'] não forma definidos...
            throw new Exception('Usuário ou senha em branco!');//... dipare uma exceção
        }
    }catch(Exception $e){//...se try falhar, pegue a exceção...
        echo $e->getMessage();//... exiba a mensagem e...
        goto fim;//.. vá para o final (usado apenas para garantir que o formulário de login seja exibido)
    }

O bloco "try" contém o código para testar se os dados foram passados. Utilizamos o "if" para decidir disparar a exceção ou não.

Já o bloco "catch" exibe a mensagem de erro se isso ocorreu.

O código "goto fim;" destina-se apenas a fazer com que o formulário de login sempre apareça. Além disso, o uso do "goto" é importante para interromper a execução do código restante (no caso a parte de realização do login).

Vamos a um exemplo sobre o fluxo de execução do "try" e "catch" antes de prosseguir.

Do jeito que está, esta primeira parte do script seria executada da seguinte forma:

1. Execução do código dentro do "try". 1.1. Execução da linha if(!$_POST['user'] OR !$_POST['password']). Nesta parte, se "user" ou "password" está indefinido, o comando dentro do "if" é executado, senão, não. 1.2. Se "user" ou "password" são indefinidos, throw new Exception('Usuário ou senha em branco!'); é executado. A partir dai, qualquer código que exista dentro do bloco "try" será ignorado, passando diretamente para o código dentro do "catch".

Ilustrando isso, se tivéssemos o seguinte:

try{//tente..
        if(!$_POST['user']){
            throw new Exception('Usuário  em branco!');
        }
        if(!$_POST['password']){
            throw new Exception('Senha em branco!');
        }
    }catch(Exception $e){//...se try falhar, pegue a exceção...
        echo $e->getMessage();//... exiba a mensagem e...
        goto fim;//.. vá para o final (usado apenas para garantir que o formulário de login seja exibido)
    }

Se enviássemos o formulário com o usuário em branco, teríamos apenas a mensagem "Usuário em branco" seguida do formulário de login.

Ou seja, sempre que throw new Exception("Mensagem sua") aparecer, o código pulará diretamente para o bloco "catch" correspondente ao "try" que está sendo processado.

Bom, agora que fechamos esse parêntese, continuaremos com nosso exemplo inicial.

try{//... se validação foi positiva, tente...
        if($_POST['user'] != 'guest' OR $_POST['password'] != '123'){//se usuário e senha não conferem...
            throw new Exception('Usuário ou senha não conferem');//... dispare uma exceção

        }else{//...senão...
            echo 'Login realizado!';//..escreva esta mensagem
        }
    }catch(Exception $e){//se try falhar...
        echo $e->getMessage();//... exiba a mensagem e...
        goto fim;//.. vá para o final (usado apenas para garantir que o formulário de login seja exibido)
    }

O código acima funciona exatamente como o primeiro bloco "try/catch", porém o teste é realizado pelo "if" com a finalidade de verificar se o usuário e senha conferem com o configurado.

Você pode ainda não estar convencido de que utilizar "try/catch" seja mais difícil do que utilizar "if/else". Vou mostrar que você não está totalmente certo na próxima parte deste texto.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Um exemplo um pouco mais complexo
   3. TRY/CATCH é melhor que IF/ELSE?
   4. Conclusão
Outros artigos deste autor

PHP Orientado a Objetos: Para quem está começando

PHP5 Orientado a Objetos: Visibilidade, herança e extensões de classes

Considerações sobre as distribuições

Qual o valor de seu trabalho

SLiM: Simple Login Manager - Mini review

Leitura recomendada

Gedit - Um bom editor pra programar em PHP!

If inline para PHP

Ato 2 - comandos de saída, constantes e operadores em PHP (básico)

Renascendo na Programação

MVC - Conceito e exemplo em PHP

  
Comentários
[1] Comentário enviado por removido em 03/04/2011 - 23:37h

Veja que é só uma dica:

$login =@ $_REQUEST['login']; // suprime erros de tela

try {
if ( $login ) {
echo 'Ok';
}
else{
throw new Exception('Falhou', 0);
}
catch( Exception $e ) {
echo $e->getMessage();
}
...bla, bla, bla

[2] Comentário enviado por everton3x em 04/04/2011 - 08:08h

Grato ./.ronin!
O símbolo @ suprime a exibição de mensagens de erro do PHP.

[3] Comentário enviado por jmurray em 08/04/2011 - 08:29h

Cara, dar comando GOTO em código php é uma péssima prática de programação. Creio que seria mais conveniente você colocar essa validação em uma classe que trata os dados de login e colocar um flag dizendo se a validação foi bem sucedida.

Sua intenção ditática é bem intencionada, mas creio que você deve dar uma melhorada no seu estilo de programar ! GOTO == spaghetti code

[4] Comentário enviado por everton3x em 08/04/2011 - 11:17h

Caro jmurray:
Concordo com você que GOTO em PHP é péssima idéia, visto que existem formas melhores para substitui-lo. Entretanto:
1º - Como você mesmo disse: é um código didático.
2º - Não utilizo GOTO em meus códigos não-didáticos e mesmo nos didáticos, esta foi a primeira vez, visto que não conhecia este comando.
3º - Obrigado pela crítica.

[5] Comentário enviado por Ragen em 08/04/2011 - 22:03h

@everton3x, vou fazer uma crítica aqui e espero que seja encarada como construtiva.

Quando alguém vai fazer uma introdução Especialmente para iniciantes, o assunto discutido tem que muito bem dominado e conhecido - por que tem coisa pior que influenciar iniciantes a estudar ou fazer coisas pelo método errado/não adotar as boas práticas de programação?

Todavia, toda ação de compartilhar é bastante apreciada e é por conta dela que essa comunidade existe. Fica os parabéns pela iniciativa de produzir o material.

Abraco

[6] Comentário enviado por everton3x em 09/04/2011 - 08:23h

Obrigado pela crítica Ragen, talvez eu tenha "errado a mão" um pouco neste texto. Vou me policiar mais nas próximas vezes.

[7] Comentário enviado por fmpfmp em 11/04/2011 - 13:37h

Interessante, eu praticamente não uso try/catch em PHP. A maior vantagem que eu vejo é quando você tem muitas condições a serem checadas. Então você precisaria de vários if/else onde apenas um try resolveria. Em compensação você não tem controle das condições que estão erradas porque ele pega a primeira que vier e vai direto pro catch.

[8] Comentário enviado por removido em 11/04/2011 - 18:55h

E uso muito try/catch em POO: Setters methods para throws e desvios condicionais e getters methods para try/catchs.

Entretanto ele é muito interessante para controle da saida de erros conhecidos. Eu costumo chamar esse recurso de programação orientada a erros... Mas ele deve ter um outro nome...

[9] Comentário enviado por everton3x em 11/04/2011 - 20:00h

./.ronin:

Que tal colocar uns exemplos pra gente dar uma olhada?


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts