大家在自定義ExceptionStrategy,定義ZF2模塊
我一直在這個問題掙扎了一個多星期,最後決定求助,希望有人知道答案。
我正在開發一個應用程序,它使用Google's Protocol Buffers作爲數據交換格式。我使用DrSlump的PHP implementation,讓我們用數據填充類實例,然後將它們序列化爲二進制字符串(或將二進制字符串解碼爲PHP對象)。
我設法實現了我的自定義ProtobufStrategy
,其selectRenderer(ViewEvent $e)
返回ProtobufRenderer
的實例,以防事件包含ProtobufModel
的實例。渲染器然後通過調用$model->getOptions()
來從模型中提取我的自定義參數,以確定哪些消息需要發送回客戶端,將數據序列化並將二進制字符串輸出到php://輸出。
爲了使它更有意義,讓我們來看看下面的樣本消息:
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
的第二個參數,$選項,告訴需要序列化其消息。如前所述,這可以通過調用$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)
返回ViewModel
的實例,顯然它不包含我需要的其他$ options信息。
此外,它返回ViewModel
而不是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',
));
,我還可以」找不到做它的方式......
我試圖創造我自己的ExceptionStrategy
類和別名它對現有的ExceptionStrategy服務,但Zend公司抱怨說,這樣的名稱的服務已經存在。
我懷疑自己在自定義策略擴展的正確路徑上,我無法找到覆蓋默認路徑的方法。
我注意到,默認ExceptionStrategy
和控制檯之一在Zend/Mvc/View/Http/ViewManager
登記。我希望我不需要添加自定義視圖管理器來實現這樣一個簡單的事情,但請,請糾正我,如果我錯了。
任何幫助將不勝感激!
恭喜你撰寫了一篇寫得很好,經過深入研究的問題! – markus