2

当我从类中调用函数时,我无法理解何时抛出和捕获异常。

请想象我的QuizMaker班级是这样的:

// Define exceptions for use in class
private class CreateQuizException extends Exception {}
private class InsertQuizException extends Exception {}

class QuizMaker()
{

    // Define the items in my quiz object
    $quiz_id = null;
    $quiz_name = null;

    // Function to create a quiz record in the database
    function CreateQuizInDatabase()
    {

        try
        {

            $create_quiz = // Code to insert quiz

            if (!$create_quiz)
            {
                // There was an error creating record in the database
                throw new CreateQuizException("Failed inserting record");
            }
            else
            {
                // Return true, the quiz was created successfully
                return true;
            }

        }
        catch (CreateQuizException $create_quiz_exception)
        {
            // There was an error creating the quiz in the database
            return false;
        }
    }

    function InsertQuestions()
    {
        try
        {
            $insert_quiz = // Code to insert quiz

            if (!$insert_quiz)
            {
                // There was an error creating record in the database
                throw new CreateQuizException("Failed inserting quiz in to database");
            }
            else
            {
                // Success inserting quiz, return true
                return true;
            }
        }
        catch (InsertQuizException $insert_exception)
        {
            // Error inserting question
            return false;
        }
    }
}

...并使用此代码,我使用该类在数据库中创建一个新测验

    class QuizMakerException extends Exception {}

try
{
    // Create a blank new quiz maker object
    $quiz_object = new QuizMaker();

    // Set the quiz non-question variables
    $quiz_object->quiz_name = $_POST['quiz_name'];
    $quiz_object->quiz_intro = $_POST['quiz_intro'];
            //... and so on ...

    // Create the quiz record in the database if it is not already set
    $quiz_object->CreateQuizRecord();

    // Insert the quiz in to the database
    $quiz_object->InsertQuestions();

}
catch (QuizMakerException $quiz_maker_error)
{
    // I want to handle any errors from these functions here
}

对于这段代码,QuizMakerException如果任何函数没有执行我希望它们执行的操作(此时它们返回 TRUE 或 FALSE),我想调用 a。

当此代码中的任何函数未执行我想要的操作时,捕获的正确方法是什么?目前他们只是返回 TRUE 或 FALSE。

  • 真的必须在调用每个函数之间放置大量 if/else 语句吗,我认为这就是异常的全部意义所在,它们只是停止在 try/catch 中执行进一步的语句?
  • 我是否从catch我的函数中抛出 QuizMakerException?

什么是正确的做法?

帮助!

4

3 回答 3

3

好吧,通常在抛出异常的函数中,比如你的InsertQuestions方法,你不想捕获任何异常,你想抛出它们或让那些发生“冒泡”。然后您的“控制器”代码可以确定如何处理异常。

如果您的目标是在CreateQuizRecord失败时停止,我会在各自的 try 块中换CreateQuizRecord行。InsertQuestions

异常的一个优点是它们可以告诉您的不仅仅是简单的布尔通过/失败。将您的基本异常扩展到“Invalid_Parameter”之类的内容并测试特定异常,或者 - 不太理想 - 从异常的属性中推断。你可以嵌套你的 catch 块来单独处理异常。

我是否从我的函数捕获中抛出 QuizMakerException?

是的。通常,您的代码// Code to insert quiz本身会返回异常。假设模型未能插入它可能会引发数据库异常。在这种情况下,您可以让该数据库异常冒泡,或者做您现在正在做的事情并简单地捕获它以反过来抛出另一个异常(尽管这样做有点使您的异常变得愚蠢)。

我真的必须在调用每个函数之间放置大量 if/else 语句吗,我认为这就是异常的全部意义所在,它们只是停止在 try/catch 中执行进一步的语句?

我是这样看的,每个抛出异常的调用,然后是一个后续调用,该调用依赖于这个不抛出任何异常的调用,应该包装在一个 try 块中。假设您想优雅地处理它,如果您只是想让它出错并停止,请不要处理异常。你会得到一个错误和堆栈跟踪。有时这是可取的。

于 2012-09-06T19:49:39.857 回答
2

你可能想稍微改变一下结构。您的 QuizMaker 类可以变成:

<?php

// Define exceptions for use in class
public class CreateQuizException extends Exception {}
public class InsertQuizException extends Exception {}

class QuizMaker()
{

    // Define the items in my quiz object
    $quiz_id = null;
    $quiz_name = null;

    // Function to create a quiz record in the database
    function CreateQuizInDatabase()
    {

        try
        {

            $create_quiz = // Code to insert quiz

            if (!$create_quiz)
            {
                // There was an error creating record in the database
                throw new CreateQuizException("Failed inserting record");
            }
            else
            {
                // Return true, the quiz was created successfully
                return true;
            }

        }
        catch (Exception $create_quiz_exception)
        {
            // There was an error creating the quiz in the database
            throw new CreateQuizException(
                "Failed inserting record " . 
                $create_quiz_exception->getMessage()
            );
        }
    }

    function InsertQuestions()
    {
        try
        {
            $insert_quiz = // Code to insert quiz

            if (!$insert_quiz)
            {
                // There was an error creating record in the database
                throw new InsertQuizException("Failed inserting quiz in to database");
            }
            else
            {
                // Success inserting quiz, return true
                return true;
            }
        }
        catch (Exception $insert_exception)
        {
            // Error inserting question
            throw new InsertQuizException(
                "Failed inserting quiz in to database " . 
                $create_quiz_exception->getMessage()
            );
        }
    }
}

实际上,如果您无法正确插入记录,则会引发 Insert 异常。如果该代码块出现任何问题,您将捕获它并再次抛出一个 Insert 异常。Create 函数(或您可能拥有的任何其他函数)也是如此。

在主代码块中,您可以拥有:

try
{
    // Create a blank new quiz maker object
    $quiz_object = new QuizMaker();

    // Set the quiz non-question variables
    $quiz_object->quiz_name = $_POST['quiz_name'];
    $quiz_object->quiz_intro = $_POST['quiz_intro'];
            //... and so on ...

    // Create the quiz record in the database if it is not already set
    $quiz_object->CreateQuizRecord();

    // Insert the quiz in to the database
    $quiz_object->InsertQuestions();

}
catch (InsertQuizException $insert_exception)
{
    // Insert error
}
catch (CreateQuizException $create_quiz_exception)
{
    // Create error
}
catch (Exception $quiz_maker_error)
{
    // Any other error
}

如果您不想在那里有多个 catch 块,只需保留 catch(Exception) 一个,然后在其中检查引发的每个异常的类型,以指定从那里采取的操作。

高温高压

于 2012-09-06T19:48:50.640 回答
0

最好的办法是一开始就不必抛出异常。当程序崩溃并且它们不是用来处理错误输出时会引发异常。如果你的函数返回任何东西(甚至是错误的东西),它不需要异常。

要回答您的问题,如果需要使用很多 if/else,那么您必须使用它们。

于 2012-09-06T19:45:27.873 回答