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は、関数のいずれかが目的の機能を実行しない場合にaを呼び出します(現時点では、TRUEまたはFALSEを返します)。

このコードの関数のいずれかが私が望むことを実行しない場合にキャッチするための正しい方法は何ですか?現時点では、単にTRUEまたはFALSEを返します。

  • 各関数の呼び出しの間に本当にたくさんのif/elseステートメントを配置する必要がありますか?それが例外の要点だと思いました、それらは単にtry / catch内のさらなるステートメントの実行を停止しますか?
  • 関数内からQuizMakerExceptionをスローしcatchますか?

正しいことは何ですか?

ヘルプ!

4

3 に答える 3

3

通常、例外をスローする関数、たとえばInsertQuestionsメソッドでは、例外をキャッチしたくない、例外をスローしたい、または発生した例外を「バブルアップ」させたいと考えています。次に、「コントローラ」コードで例外の処理方法を決定できます。

ここでの目標が失敗した場合に停止することである場合、CreateQuizRecord私はラップCreateQuizRecordし、InsertQuestionsそれぞれを独自のtryブロックに入れます。

例外の利点の1つは、単純なブールパス/フェイル以上のものを通知できることです。基本例外を「Invalid_Parameter」などに拡張して特定の例外をテストするか、理想的には例外のプロパティから推測します。キャッチブロックをネストして、例外を個別に処理できます。

関数のキャッチ内から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()
            );
        }
    }
}

事実上、レコードを正しく挿入できない場合は、挿入例外をスローします。そのコードブロックで問題が発生した場合は、それをキャッチして、挿入例外を再度スローします。同じことが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)を1つ保持してから、スローされる各例外のタイプをチェックインして、そこから実行されるアクションを指定します。

HTH

于 2012-09-06T19:48:50.640 に答える
0

最善の方法は、そもそも例外をスローする必要がないことです。プログラムがクラッシュすると例外がスローされ、間違った出力を処理するように作成されません。関数が何かを返す場合(間違っている場合でも)、例外は必要ありません。

あなたの質問に答えるために、多くのifs / elsesを使用する必要がある場合は、それらを使用する必要があります。

于 2012-09-06T19:45:27.873 に答える