2010-08-26 2 views
2

J'essaie de comprendre l'utilisation des exceptions dans PHP .. Comment ils fonctionnent et quand les utiliser ... La structure de base ci-dessous, est la bonne méthode .. Il semble un peu gonflé à moi?Exceptions PHP - ai-je la bonne idée?

Merci à l'avance pour tout conseiller ou vous aider ..

<?php 

class APIException extends Exception 
{ 
    public function __construct($message) 
    { 
     parent::__construct($message, 0); 
    } 

    public function __toString() 
    { 
     echo('Error: ' . parent::getMessage()); 
    } 

    public function __toDeath() 
    { 
     die("Oops: ". parent::getMessage()); 
    } 
} 

?> 

<?php 

require_once('exception.class.php'); 

class auth extends base 
{ 
    /* 
    * User functions 
    */ 

    public function user_create($args='') 
    { 
     try 
     { 
     if (!isset($arg['username']) || !isset($arg['password']) || 
       !isset($arg['question']) || !isset($arg['answer'])) 
     { 
      throw new APIException('missing variables, try again'); 
     } 
     } 
     catch (APIException $e) 
     { 
     $e->__toString(); 
     } 

     try 
     { 
     if ($this->user_exists()) 
     { 
      throw new APIException('user already exists'); 
     } 
     } 
     catch (APIException $e) 
     { 
     $e->__toString(); 
     } 
    } 

    protected function user_exists($name) 
    { 
     // Do SQL Query 
     try 
     { 
     $sql = "select * from user where username='$user'"; 
     if (!mysql_query($sql)) 
     { 
      throw new APIException('SQL ERROR'); 
     } 
     } 
     catch (APIException $e) 
     { 
     $e->__toDeath(); 
     } 
    } 
} 

?> 

Répondre

1

Non, vous ne les utilisez pas correctement. Jetez un oeil à ce

public function user_create($args='') 
{ 
    try 
    { 
    if (!isset($arg['username']) || !isset($arg['password']) || 
      !isset($arg['question']) || !isset($arg['answer'])) 
    { 
     throw new APIException('missing variables, try again'); 
    } 
    } 
    catch (APIException $e) 
    { 
    $e->__toString(); 
    } 
    //snip... 

Lorsque vous throw new APIException('missing variables, try again');, il sera juste pris par catch (APIException $e). L'un des points d'exception est que vous pouvez indiquer au code appelant la fonction que quelque chose s'est mal passé. Une utilisation plus appropriée pourrait ressembler à ceci.

public function user_create($args='') 
{ 
    if (!isset($arg['username']) || !isset($arg['password']) || 
     !isset($arg['question']) || !isset($arg['answer'])) 
    { 
     throw new APIException('missing variables, try again'); 
    } 
    //snip... 
// elsewhere 
try { 
    $foo->user_create('bar'); 
} catch(APIException $e) { 
    // handle error here 
    // log_error($e->getCode(), $e->getMessage()); 
} 

Notez que l'utilisation du bloc try/catch lorsque vous appel user_create. Pas dans user_create.

1

Syntaxe sage, qui est correct.

Bien que votre implémentation ne les utilise pas vraiment à leur plein potentiel, comme vous les utilisez fondamentalement comme if conditionnels.

La grande chose à propos des exceptions est qu'elles peuvent arriver n'importe où et que l'exception sera renvoyée vers le haut de votre code jusqu'à ce qu'elle soit interceptée. Vous pouvez donc avoir une classe User, avec une méthode login(). Vous encapsulez tout appel à login() dans un bloc try, puis lancez des exceptions dans la méthode login(). La méthode login() ne gère pas les exceptions, elle sait seulement que quelque chose a mal tourné et les lance. Votre bloc catch peut alors attraper les différents types d'exception et les traiter de manière appropriée.

1

N'utilisez jamais d'exceptions où vous attendez quelque chose pourrait mal se passer.

Par exemple:

$sql = "select * from user where username='$user'"; 
if (!mysql_query($sql)) 
{ 
    throw new APIException('SQL ERROR'); 
} 

Vous savez très bien que l'utilisateur n'a pas pu être trouvée (et honte à vous pour créer cette terrible !! sql non échappée), donc des exceptions de ne pas y être utilisés.

maintenant:

if (!(mysql_connect($hostname, $user, $pass))) 
{ 
    throw new Exception("Can't connect to db!"); 
} 

est valide parce que vous n'attendez honnêtement de ne pas être en mesure de se connecter à la DB.

Des exceptions sont destinées à vous donner plus que mourir invites, et sont destinés à être utilisés avec des « jolis messages d'erreur », à tout le moins:

try 
{ 
    // Run my Entire App 
} 
catch (Exception $e) 
{ 
    // Catch every exception, give them my pretty 404 page with a kinder explanation than a white screen or weird programming error message. 
    $error = $e->getMessage(); 
    include '404.tpl.php'; 
} 

Ils excellent à vous donner les options de sauvegarde:

try 
{ 
    // Let's try to log in the user: 
    login($user, $pass); 
} 
catch (Exception $e) 
{ 
    // Let's log them in as a guest, then... 
    login('guest', 'nobody'); 
} 

Même cela contredit le point ci-dessus; un si devrait être utilisé dans cet endroit.

0

I've askedarounda bit, et il ne semble pas y avoir de règles convenues pour savoir pourquoi et quand utiliser des exceptions. Les gens diront des choses sur «les utiliser dans des circonstances exceptionnelles», ou «les utiliser pour quelque chose que vous n'attendez pas» - je ne pense pas que ces réponses fournissent des indications particulières quant à quand et où les utiliser. Il semble que ce soit seulement une opinion personnelle. J'aimerais voir une norme raisonnable et objective, mais je soupçonne qu'elle n'existe pas. Donc, personnellement, je les utilise dans toutes mes classes pour m'assurer que je fais face à la situation (si je ne le fais pas, je reçois de gros messages d'exception non pris sur mon écran), et l'exécution du code ne se poursuit pas dans cette méthode. Je les utilise également pour appliquer des types dans les variables d'argument. L'exécution d'une méthode s'arrête sur une exception, et comme la plupart des objets PHP ne survivent pas à un chargement de page, il n'y a pas beaucoup de sens dans la vérification d'erreur avancée. Laissez-les exploser avec une exception, attrapez-les et donnez un message d'erreur à l'utilisateur afin qu'il puisse vous fournir des commentaires pour corriger la situation.