1

これまでコードでTry-catchを使用したことはありませんが、今は使用する必要があり、その動作を完全に理解していないようです。explodeを使用して取得した文字列にデータがあります。

$groupNumbers = array();
$str = $dataGroups['groups'];
$groupNumbers = explode(",", $str);
$count = count($groupNumbers);

次に、すべての要素が数値であるかどうかを確認し、数値である場合はデータベースクエリを続行します。そうでない場合は、アクションを中止してエラーを返します。

これが私がしていることです:

for ($i = 0; $i < $count; ++$i)
    {
        try
        {
            is_numeric($groupNumbers[$i]);

        }
        catch (Exception $ex)
        {
            process_exception_to_json($ex);
        }
    }

evrery要素が数値の場合、SQLを実行するアクティブレコードを作成します。

$ this-> db-> insert_batch('users_groups'、$ datas);

明らかにそのように書かれているので、要素が数値でなくても、アクションは中止されず、insert_batchは、回避したい無効な値で実行されます。これを行う正確な方法は何ですか。例外を取得し、同時にアクションを中止できます。ありがとう

レロン

4

4 に答える 4

2

これは、is_numericDocsが例外をスローせず、値を返すためです。失敗したり、例外をスローしたりすることはありません。

あなたはそれをこのようにする必要があるでしょう(ほんの一例です、それは不必要なので私はそれを提案しません):

try
{
    if (!is_numeric($groupNumbers[$i])) {
        throw new RuntimeException('Not numeric.');
    }

}
catch (Exception $ex)
{
    process_exception_to_json($ex);
}

代わりに、独自のグループ番号タイプを作成します。

try
{
    $groupNumbers = GroupNumbers::createFromString($dataGroups['groups']);
}
catch (Exception $ex)
{
    process_exception_to_json($ex);
}

次のタイプの場合:

class GroupNumbers extends ArrayObject
{
    public function construct(Array $numbers) {
        foreach ($numbers as $number)
        {
            if (!is_numeric($number))
            {
                throw new InvalidArgumentException(sprintf('Not numeric "%s".', $number));
            }
        }
        parent::__construct($numbers);
    }
    public static function createFromString($string) {
        return new self(explode(",", $string));
    }
}

文字列処理がカプセル化され、外部ループがなくなりGroupNumbers、文字列に実際の数値がある場合にのみインスタンス化されます。

クラスに精通していない場合は、手続き型スタイルでも同様のメリットがあります。おそらく理解しやすいでしょう(しかしほとんど同じです):

try
{
    $groupNumbers = GroupNumbers_createFromString($dataGroups['groups']);
}
catch (Exception $ex)
{
    process_exception_to_json($ex);
}

function GroupNumbers_createFromString($string)
{
    $numbers = explode(",", $string);
    foreach ($numbers as $number)
    {
        if (!is_numeric($number))
        {
            throw new InvalidArgumentException(sprintf('Not numeric "%s".', $number));
        }
    }
    return $numbers;
}
于 2012-04-04T08:38:40.470 に答える
1

検証したい場合は、Exceptionここで使用する必要はありません

for ($i = 0; $i < $count; ++$i)
{
    if((int) $groupNumbers[$i] <= 0) {
        process_exception_to_json($groupNumbers[$i]);
        break; //optinal
    }
}
于 2012-04-04T08:43:05.053 に答える
1

is_numeric例外をスローしないので、例は何もしません。これは次のように機能します。

for ($i = 0; $i < $count; ++$i)
{
    try
    {
        if (is_numeric($groupNumbers[$i]) !== true)
        {
            throw new Exception($groupNumbers[$i] . ' is not numeric');
        }
    }

    catch (Exception $ex)
    {
        process_exception_to_json($ex);
    }
}

以下は(ほぼ)同じことを達成します:

for ($i = 0; $i < $count; ++$i)
{
    if (is_numeric($groupNumbers[$i]) !== true)
    {
        process_exception_to_json($groupNumbers[$i] . ' is not numeric');
    }
}
于 2012-04-04T08:39:32.887 に答える
0

tryブロック内で実際に例外をスローする何かを行う必要があります。is_numeric()はfalseを返すだけなので、機能しません。この意志:

try {
    if (!is_numeric($groupNumbers[$i]) {
        throw new exception('Uh-oh!');
    } 
} catch (Exception $ex) {
    process_exception_to_json($ex);
}

これはおそらく次のように行うのが最適です。

function checkNumbers($groupNumbers) {
    for ($i = 0; $i < count($groupNumbers); ++$i) {
        if (!is_numeric($groupNumbers[$i]) {
            throw new Exception('"'.$groupNumbers[$i]." is non-numeric!");
        } 
    }
}

try {
    checkNumbers($numbers);
    // Won't get this far if it throws an exception
    $this->db->insert_batch('users_groups', $numbers);
} catch (Exception $ex) {
    process_exception_to_json($ex);
}

例外はコード内に非常に深くネストすることができ、主な利点は、エラーメッセージが特定のものであり、多くの真または偽の値について心配する必要なしにバブルアップすることです。checkNumbers()から数十の連鎖関数が呼び出されている可能性があり、エラーが何であれ、JSONに送信する準備ができているcatchブロックにポップアップ表示されます。

于 2012-04-04T08:50:34.147 に答える