【问题标题】:PHP exceptions - do i have the correct idea?PHP 异常 - 我有正确的想法吗?
【发布时间】:2011-04-04 08:54:41
【问题描述】:

我正在尝试了解 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();
      }
   }
}

?>

【问题讨论】:

    标签: php class exception-handling


    【解决方案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】:

      语法上是正确的。

      虽然您的实现并未真正充分发挥它们的潜力,但您基本上将它们用作if 条件。

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

      所以你可以有一个User 类和一个login() 方法。您将对login() 的任何调用包装在一个try 块中,然后在login() 方法中抛出异常。 login() 方法不处理异常,它只知道出了问题并抛出它们。

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

      【讨论】:

        【解决方案3】:

        永远不要使用您预期可能出错的异常。

        例如:

        $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!");
        }
        

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

        Exceptions 的目的不仅仅是为您提供死亡提示,而且至少用于“漂亮的错误消息”:

        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。

        【讨论】:

          【解决方案4】:

          I've askedarounda bit,对于为什么以及何时使用例外似乎没有商定的规则。人们会说“在特殊情况下使用它们”或“将它们用于您不期望的事情”——我认为这些答案并没有为何时何地使用它们提供任何特定的指导。这似乎只是个人意见。我很想看到一个合理、客观的标准,但我怀疑它不存在。

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

          【讨论】:

            猜你喜欢
            • 2021-05-18
            • 1970-01-01
            • 1970-01-01
            • 2023-03-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多