14

私は、実行中にスクリプトが例外をスローすると言うphpスクリプトを持っています。PHP を中断したところ (例外がスローされたところ) から再開したいと考えています。

コードの「catch」部分に同じ実行コードを入れる必要がありますか?

たとえば、mySQL に接続すると、接続がタイムアウトしたために失敗するとします。

   function someCode(){
        $pdostmt = $this->prepare($this->sql);
        if($pdostmt->execute($this->bind) !== false) {
            if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql))
                return $pdostmt->fetchAll($this->fetchOption);
            elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql))
                return $pdostmt->rowCount();
   }
   try {
        someCode();
        }   
    } catch (PDOException $e) {  
        //re-execute same code as within the try clause?
        someCode();
    }
4

4 に答える 4

30

まず第一に、例外がキャッチされない場合にのみ致命的であることを明確にする必要があります。例外をキャッチしても、スクリプトの実行は停止しません。tryブロックのスタックフレームを停止し、catchブロックに制御を移すだけです。そこから、スクリプトは通常どおり実行され続けます。

ここで例外をキャッチすることにより、例外がキャッチされた後も通常のスクリプト実行を再開します...

try {
  echo "Try...\n";
  throw new Exception("This is an exception");
} catch(Exception $e) {
  echo "Exception caught with message: " . $e->getMessage() . "\n";
}

echo "Script is still running...";

例外ハンドラを使用して、キャッチされなかった例外を処理する別の方法があります。ただし、try and catchステートメントを使用しない場合でも、実行フローは停止します。これは例外の性質です:

function myExceptionHandler($e) {
  echo "Uncaught exception with message: " , $e->getMessage(), "\n";
}

set_exception_handler('myExceptionHandler'); // Registers the exception handler

throw new Exception("This is Exception 1");
echo "Execution never gets past this point";
throw new Exception("This is Exception 2");
throw new Exception("This is Exception 3");

編集:あなたの質問を明確にした後、私はあなたが望むものは例外ハンドラーではないと述べるべきだと思いますが、あなたは実際には例外をまったく使いたくないのです。あなたがやろうとしていることは、例外をスローする必要はまったくありません。そのようなエラーを処理するだけの場合は、PDOを例外モードにしないでください。例外は、例外エラーを処理するためにのみ使用する必要があります。例外の要点は、約束を守ることです。たとえば、関数が常にPDOStatementオブジェクトを返すことを約束していて、それができない場合がある場合は、例外をスローするのが理にかなっています。これにより、発信者は、約束を守ることができないポイントに到達したことを知ることができます。

必要なのは基本的なエラー処理です...

function someCode(){
        $pdostmt = $this->prepare($this->sql);
        if($pdostmt->execute($this->bind) !== false) {
            if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql))
                return $pdostmt->fetchAll($this->fetchOption);
            elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql))
                return $pdostmt->rowCount();
        } else {
           return false;
        }
}

while (someCode() === false) {
  /* Call someCode() until you get what you want */
}
于 2012-12-19T15:31:21.880 に答える
0

実行中に例外が発生しない場合は、try catch の finally 部分を使用できる場合があります。

try {
  // some crashing code
} catch (Exception $e) {
  //some catch code
} finally {
  //code that will run anyways.
}
于 2012-12-19T15:23:37.490 に答える