PHP异常 - 我有正确的想法吗?

时间:2010-08-26 16:07:58

标签: php class exception-handling

我试图理解PHP中异常的使用..它们如何工作以及何时使用它们......下面的基本结构,是正确的方法..对我来说似乎有些臃肿?

提前感谢任何建议或帮助..

<?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();
      }
   }
}

?>

4 个答案:

答案 0 :(得分:1)

语法明智,这是正确的。

虽然你的实现并没有真正充分利用它们,因为你基本上将它们用作if条件。

关于异常的好处是它们可以在任何地方发生,并且异常将被“抛出”你的代码直到它被捕获。

因此,您可以拥有User类,并使用login()方法。您在try块中包含对login()的任何调用,然后在login()方法中抛出异常。 <{1}}方法不处理异常,只知道出错了并抛出它们。

然后,您的catch块可以捕获不同类型的Exception并适当地处理它们。

答案 1 :(得分:1)

不,你没有正确使用它们。看看这个

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...

当您throw new APIException('missing variables, try again');时,它会被catch (APIException $e)抓住。

其中一个例外是,你可以告诉代码调用函数出错了。更合适的用法可能看起来像这样。

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());
}

请注意,当您调用 user_create时,您使用try / catch块。不在user_create内。

答案 2 :(得分:1)

永远不要在期望出现错误的地方使用例外。

例如:

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

你很清楚用户无法找到(并且因为创建了这样可怕的非转义sql而感到羞耻!),所以不能在那里使用异常。

现在:

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

是有效的,因为你真的不希望无法连接到数据库。

例外意味着为您提供的不仅仅是模具提示,而且至少应该与“漂亮的错误信息”一起使用:

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';
}

他们擅长为您提供备份选项:

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');
}

即使这与上述观点相矛盾;一个if应该在这个地方使用。

答案 3 :(得分:0)

I've asked around a bit,似乎没有就使用例外的原因和时间达成一致的规则。人们会说“在特殊情况下使用它们”,或“将它们用于你不期望的事物” - 我不认为这些答案在何时何地使用它们时提供任何特定的指导。这似乎只是个人意见。我希望看到一个合理的,客观的标准,但我怀疑它不存在。

所以个人而言,我在我的所有课程中都使用它们以确保我处理这种情况(如果我不这样做,我的屏幕上会出现大丑的'未捕获的异常'消息),并且代码执行不会继续那种方法。我还使用它们来强制参数变量中的类型。方法的执行在异常时停止,并且因为大多数PHP对象不通过页面加载,所以在高级错误检查中没有多大意义。只是让他们爆炸,异常,抓住它,并给用户一个错误消息,以便他们可以提供一些反馈来纠正这种情况。