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.