Pregunta

Hola a todos,

He estado luchando con este problema durante más de una semana y finalmente se decidió a pedir ayuda con la esperanza de que alguien sepa la respuesta.

Estoy desarrollando una aplicación que está utilizando Google Protocol Buffers como el formato de intercambio de datos.Estoy usando DrSlump PHP la aplicación, que vamos a llenar las instancias de una clase con los datos y, a continuación, serializa en una cadena binaria (o decodificar cadenas binarias en objetos de PHP).

He conseguido poner en práctica mi costumbre ProtobufStrategy cuya selectRenderer(ViewEvent $e) devuelve una instancia de ProtobufRenderer en caso de que el evento contiene una instancia de ProtobufModel.El renderizador, a continuación, extractos de mi costumbre de los parámetros del modelo llamando $model->getOptions() para determinar qué mensaje debe ser enviado de vuelta al cliente, se serializa los datos y salidas de la cadena binaria a php://output.

Para que tenga más sentido, veamos el ejemplo siguiente mensaje:

message SearchRequest {
    required string query = 1;
    optional int32 page_number = 2;
    optional int32 result_per_page = 3;
}

Si quería responder al cliente con este mensaje, me gustaría volver algo como esto, de mi acción:

public function getSearchRequestAction()
{
    [..]
    $data = array(
        'query'           => 'my query',
        'page_number'     => 3,
        'result_per_page' => 20,
    );
    return new ProtobufModel($data, array(
        'message' => 'MyNamespace\Protobuf\SearchRequest',
    ));
}

Como puedes ver estoy utilizando ViewModelel segundo parámetro, $opciones, para decir el mensaje que necesita ser serializado.Que luego, como se mencionó anteriormente, se extrae del interior de la representador llamando $model->getOptions().

Tan lejos, tan bueno.Mis acciones de los controladores de salida de datos binarios como se esperaba.

Sin embargo, estoy teniendo problemas con el manejo de excepciones.Mi plan era coger todas las excepciones y responder al cliente con una instancia de mi Excepción mensaje, que tiene este aspecto:

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;
}

En teoría debería funcionar fuera de la caja, pero no lo hace.El problema es que Zend\Mvc\View\Http\ExceptionStrategy::prepareExceptionViewModel(MvcEvent $e) devuelve una instancia de ViewModel, que , obviamente, no contiene el adicional $opciones la información que necesito.

También devuelve ViewModel y no ProtobufModel, lo que significa que el Zend invoca el predeterminado ViewPhpRenderer y salidas de la excepción como una página HTML.

Lo que quiero hacer es reemplazar el valor predeterminado ExceptionStrategy (y eventualmente también el RouteNotFoundStrategy con mis propias clases, que sería devolver algo como esto:

$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',
));

...y no puedo encontrar la manera de hacerlo...

He intentado crear mi propia ExceptionStrategy clase y alias a la existente ExceptionStrategy servicio, pero Zend se quejó de que un servicio con ese nombre ya existe.

Tengo la sospecha de que estoy en el camino correcto con la costumbre de la estrategia de extensión de la que no puedo encontrar una manera de reemplazar la de por defecto.

Me di cuenta de que el defecto ExceptionStrategy y la consola de uno se registró en Zend/Mvc/View/Http/ViewManager.Espero no tener que agregar vista personalizada a los gerentes a alcanzar una cosa tan simple, pero por favor, corríjanme si estoy equivocado.

Cualquier ayuda será apreciada!

¿Fue útil?

Solución

La forma más fácil es hacer un poco de fudging.

En primer lugar, registrar su oyente para que se ejecute en una prioridad mayor que la ExceptionStrategy;desde que se registra el valor de prioridad, esto significa que cualquier prioridad mayor que 1.

A continuación, en el oyente, antes de volver, asegúrese de que establece el "error" en la MvcEvent a un falsy valor:

$e->setError(false);

Una vez que hayas hecho esto, el valor predeterminado ExceptionStrategy va a decir, "nada más que hacer aquí, se mueven a lo largo" y regresar temprano, antes de hacer nada con el ViewModel.

Mientras estás en ello, también debe asegurarse de que usted cambie el resultado de instancia en el evento:

$e->setResult($yourProtobufModel)

como esto se asegurará de que esto es lo que es inspeccionado por los demás oyentes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top