gpt4 book ai didi

php - 在 ZF2 模块中定义自定义 ExceptionStrategy

转载 作者:可可西里 更新时间:2023-10-31 23:11:50 26 4
gpt4 key购买 nike

大家好,

我已经为这个问题苦苦挣扎了一个多星期,最后决定寻求帮助,希望有人知道答案。

我正在开发一个使用 Google's Protocol Buffers 的应用程序作为数据交换格式。我正在使用 DrSlump 的 PHP implementation ,它让您用数据填充类实例,然后将它们序列化为二进制字符串(或将二进制字符串解码为 PHP 对象)。

我已经设法实现了我的自定义 ProtobufStrategy,如果事件包含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 的第二个参数 $options 来告知需要序列化的消息。然后,如前所述,可以通过调用 $model->getOptions() 在渲染器中提取。

到目前为止,还不错。我的 Controller 操作按预期输出二进制数据。

但是,我在处理异常方面遇到了问题。我的计划是捕获所有异常并用我的Exception 消息实例响应客户端,如下所示:

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 中注册。我希望我不必添加自定义 View 管理器来实现如此简单的事情,但如果我错了,请纠正我。

任何帮助将不胜感激!

最佳答案

最简单的方法是做一些捏造。

首先,注册您的监听器以比 ExceptionStrategy 更高的优先级运行;因为它以默认优先级注册,这意味着任何高于 1 的优先级。

然后,在您的监听器中,在您返回之前,确保将 MvcEvent 中的“error”设置为假值:

$e->setError(false);

完成后,默认的 ExceptionStrategy 会说,“这里没什么可做的,继续前进”,然后在对 ViewModel 做任何事情之前提前返回。

当你这样做的时候,你还应该确保你改变了事件中的结果实例:

$e->setResult($yourProtobufModel)

因为这将确保这是其他听众检查的内容。

关于php - 在 ZF2 模块中定义自定义 ExceptionStrategy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12693762/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com