2017-01-10 13 views
1

を得、それは発電機で例外をキャッチし、ちょうど次の値を生成することは可能ですか?私は以下の例のコードのようなものを試しましたが、例外で停止し、次の値を "期待通り"にしません。PHPジェネレータ:キャッチ例外と

function generator(){ 
    foreach($aLotOfWork as $task){ 
     try { 
     $promise = doSomethingThatCanFailBadly($task); 

     yield $promise; 
     } catch (Exception $e) { 
     echo "oh.. there is an error, but I don't care and continue"; 
     } 
    } 
    } 

この人は単にPHPでの例外をキャッチし、に行くためにどのようを知りたかったので、私見これは、(php: catch exception and continue execution, is it possible?)の複製ではありません。私の場合、は既にすべての例外をキャッチしますが、ジェネレータは停止し、意図した通りに進まません。

+0

[php:例外をキャッチして実行を継続する可能性がありますか?](http://stackoverflow.com/questions/2132759/php-catch-exception-and-continue-execution-is-it-possible ) –

+1

ただ、 '引き続き追加;'ステートメントを、あなたは罰金 – Paradoxis

+0

@RobertoGeukeこんにちはなければなりません、私はまた、他のポストを見つけましたが、これらは、2つの異なる場合があります。私はすでにtry/catchを使用していますが、別の動作が必要です。他の人はtry/catch構造を探していました。 – NaN

答えて

0

あなたは配列に発電機の出力を保存する必要があるだろう、と個々の利回り中に例外がスローされた場合、右の例外処理で、それは単に配列に取得することはできません。

例では、doSomethingThatCanFailBadlyが例外をスローした場合、プログラムフローはcatchブランチになります。だから、実際にはdoSomethingThatCanFailBadlyには$promiseに割り当てることができる戻り値がありません。その時点では何も得られません。

+0

ジェネレータ関数の代わりに配列を使うこともできますが、ジェネレータを使う必要があります。なぜなら、プログラマが既に動作している間に新しい「タスク」を追加したいからです。しかし、それを参照として渡すことで可能かもしれないが、それは汚いハックのように簡単ではない。 – NaN

+1

私は可能であっても参照を混乱させるべきではないと思います。それはコードの自殺です:) –

1

あなたのコードが正しいと、それはこれをチェック、例外を捕捉してまいります。

$ cat so.php 
<?php 

function doSomethingThatCanFailBadly($task) { 
    if ($task == 3) { 
    throw new Exception(); 
    } 
    return $task; 
} 

function generator(){ 
    $aLotOfWork = array(1,2,3,4,5); 
    foreach($aLotOfWork as $task){ 
     try { 
     $promise = doSomethingThatCanFailBadly($task); 

     yield $promise; 
     } catch (Exception $e) { 
     echo "oh.. there is an error, but I don't care and continue\n"; 
     } 
    } 
    } 


foreach (generator() as $number) { 
    echo "$number\n"; 
} 
?> 

$ php so.php 
1 
2 
oh.. there is an error, but I don't care and continue 
4 
5 

があなたのエラーのスタックトレースを見てください。たぶん、何が起こっていることはあなたのdoSomethingThatCanFailBadlyメソッド内で何かが例外を生成されていることが、それはまたそれをキャッチし、それがあなたのcatchブロックに到達する前にdie()exit()で終了し強制されます。あなたがそのような場合にできることはあまりありません。あなたはおそらくregister_shutdown_functionを使用して、それが役立つかどうかを見ることができますが、それはあまりにも見た目が乱雑です。

0

@palakoは非常にうまく問題を説明したが、彼は本当に私の場合のためのソリューションを提供していません。私はこのジェネレータを使用してPromisesを生成し、コンシューマ(GuzzleのEachPromiseメソッド)はExceptionでの作業をやめているようです。そこで私はの声明をreturn RejectedPromise('error message')に置き換えました。

私は、これは非常事態固有のソリューションであることを認めざるを得ないが、あなたはあまりにも他の設定に似たような操作を行うことができますだけではなく、例外を使用するオブジェクトを返します。