ZF2モジュールでカスタムExceptionStrategyを定義します
-
12-12-2019 - |
質問
こんにちは、
私は一週間以上この問題に苦労していて、ついに誰かが答えを知っていることを望んでいるのを助けることを求めることにしました。
Googleのプロトコルバッファをデータ交換フォーマットとして使用しています。 DrslumpのPHP 実装を使用しています。これでクラスインスタンスにデータを入力してから、それらをバイナリ文字列にシリアル化する(またはデコード)。 PHPオブジェクトへのバイナリストリング)
ProtobufStrategy
のインスタンスが含まれている場合、selectRenderer(ViewEvent $e)
がProtobufRenderer
のインスタンスを返すカスタムProtobufModel
を実装することができました。次に、レンダラは$model->getOptions()
を呼び出してクライアントに送信する必要があるメッセージをクライアントに送信し、データをシリアル化し、バイナリ文字列をに出力するかを判断し、バイナリ文字列を出力します。
それ以上の意味を上げるために、次のサンプルメッセージを見てみましょう。
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
.
このメッセージを使用してクライアントに応答したい場合は、このようなものからこのようなものを返します。
public function getSearchRequestAction()
{
[..]
$data = array(
'query' => 'my query',
'page_number' => 3,
'result_per_page' => 20,
);
return new ProtobufModel($data, array(
'message' => 'MyNamespace\Protobuf\SearchRequest',
));
}
.
は、ViewModel
の2番目のパラメータ、 $ options を使用して、どのメッセージをシリアル化する必要があるかを確認します。それから、前述のように、$model->getOptions()
を呼び出してレンダラの内部に抽出できます。
これまでのところ、とてもいいです。 My Controller Actionsは予想通りバイナリデータを出力します。
しかし、私は例外の取り扱いに関する問題を抱えています。私の計画はすべての例外を捉え、私の例外メッセージのインスタンスを含むクライアントに返信することでした。
message Exception {
optional string message = 1;
optional int32 code = 2;
optional string file = 3;
optional uint32 line = 4;
optional string trace = 5;
optional Exception previous = 6;
}
.
理論的には、箱から出しているはずですが、そうではありません。この問題は、Zend\Mvc\View\Http\ExceptionStrategy::prepareExceptionViewModel(MvcEvent $e)
がViewModel
のインスタンスを返します。これにより、必要な $ OPTIONS 情報が必要な情報が含まれていません。
もViewModel
ではなく、ZendがデフォルトのProtobufModel
を呼び出してExceptionをHTMLページとして出力することを意味します。
私がやりたいことデフォルトのViewPhpRenderer
(そして最終的にはExceptionStrategy
)を自分のクラスで置き換えます。
$data = array(
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
'previous' => $e->getPrevious(),
);
return new ProtobufModel($data, array(
'message' => 'MyNamespace\Protobuf\Exception',
));
.
...そして私はそれをやる道を見つけることができません...
私は自分のRouteNotFoundStrategy
クラスとエイリアスを既存の ExceptyStrategy サービスに作成しましたが、Zendはそのような名前を持つサービスがすでに存在することを不平を言っています。
私は私が右側のパスに疑いがありますカスタム戦略の拡張はデフォルトのものを上書きする方法が見つかりません。
デフォルトのExceptionStrategy
とコンソールがExceptionStrategy
に登録されていることに気付きました。私はそのような簡単なことを達成するためにカスタムビューマネージャを追加する必要がないが、私が間違っているなら私を修正してください。
任意の助けが高くなるでしょう!
解決
最も簡単な方法は少し障害をすることです。
まず、Listenerを登録して、ExceptionStrategyよりも高い優先順位で実行されます。デフォルトの優先順位に登録されているので、これは1より高い優先順位を意味します。
その後、リスナーで、戻る前に、MVCEEventの「エラー」を偽造の値に設定してください。
$e->setError(false);
.
あなたがそれをしたら、デフォルトの例外論格は、「viewModelで何かをする前に、ここでは行動することはありません」と言っています。
あなたがそれをしている間に、イベントで結果インスタンスを変更することもできます。
$e->setResult($yourProtobufModel)
.
これが他のリスナーによって検査されているものであることを保証するようになる。