こんにちは、みんな、
私はこの問題に 1 週間以上悩まされてきましたが、最終的に誰かが答えを知っていることを願って助けを求めることにしました。
Google の Protocol Buffersをデータ交換フォーマットとして使用するアプリケーションを開発しています。DrSlump の PHP実装を使用しています。これにより、クラス インスタンスにデータを入力し、それらをバイナリ文字列にシリアル化できます (またはバイナリ文字列を PHP オブジェクトにデコードできます)。
イベントに のインスタンスが含まれている場合に のインスタンスProtobufStrategy
をselectRenderer(ViewEvent $e)
返すカスタムを実装することができました。次にレンダラーは、どのメッセージをクライアントに送り返す必要があるかを決定するために呼び出して、モデルからカスタム パラメーターを抽出し、データをシリアル化し、バイナリ文字列をphp://outputに出力します。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()
。
ここまでは順調ですね。私のコントローラー アクションは、期待どおりにバイナリ データを出力します。
ただし、例外の処理に問題があります。私の計画は、すべての例外をキャッチし、次のような例外メッセージのインスタンスでクライアントに応答することでした。
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)
、のインスタンスを返すことです。これには、必要な追加の$options情報ViewModel
が含まれていません。
ViewModel
また、それはand notを返しますProtobufModel
。これは、Zend がデフォルトViewPhpRenderer
を呼び出し、例外を HTML ページとして出力することを意味します。
私がやりたいのはExceptionStrategy
、デフォルト(および最終的には) を独自のクラスに置き換えることですRouteNotFoundStrategy
。これは、次のようなものを返します。
$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',
));
...そして、私はそれを行う方法を見つけることができません...
独自のクラスを作成し、それを既存のExceptionStrategyExceptionStrategy
サービスにエイリアスしようとしましたが、Zend はそのような名前のサービスが既に存在すると不満を漏らしました。
カスタム戦略拡張機能を使用して正しい道を進んでいる疑いがあります。デフォルトのものをオーバーライドする方法が見つかりません。
ExceptionStrategy
デフォルトとコンソールが に登録されていることに気付きましたZend/Mvc/View/Http/ViewManager
。このような単純なことを達成するためにカスタム ビュー マネージャーを追加する必要がないことを願っていますが、間違っている場合は修正してください。
どんな助けでも大歓迎です!