Question

Salut à tous,

J'ai été aux prises avec ce problème depuis plus d'une semaine et a finalement décidé de demander de l'aide en espérant que quelqu'un connaît la réponse.

Je développe une application, qui est l'aide de Google Protocol Buffers comme le format d'échange de données.Je suis à l'aide de DrSlump du PHP la mise en œuvre, qui vous permet de compléter des instances de classe avec des données, puis de les sérialiser dans une chaîne binaire (ou décoder des chaînes binaires en objets PHP).

J'ai réussi à mettre en place à mon habitude ProtobufStrategy dont selectRenderer(ViewEvent $e) retourne une instance de ProtobufRenderer dans le cas où l'événement contient une instance de ProtobufModel.Le moteur de rendu, puis des extraits de mon personnalisée paramètres du modèle en appelant $model->getOptions() pour déterminer le message doit être envoyé au client, sérialise les données et les sorties de la chaîne binaire de php://output.

Pour faire plus de sens, regardons l'exemple suivant message:

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

Si je voulais répondre au client avec ce message, je voudrais revenir à quelque chose comme cela à partir de mon action:

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

Comme vous pouvez le voir je suis en utilisant ViewModeldeuxième paramètre, $options, de dire à qui le message doit être sérialisé.Que peut alors, comme mentionné plus tôt, être extraites à l'intérieur du moteur de rendu en appel $model->getOptions().

Pour l'instant, donc bon.Mes actions de contrôleur de sortie des données binaires comme prévu.

Cependant, je suis d'avoir des problèmes avec la gestion des exceptions.Mon plan est d'attraper toutes les exceptions et répondre au client avec une instance de ma Exception message, qui ressemble à ceci:

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 théorie, il devrait travailler hors de la boîte, mais il ne le fait pas.Le problème est que Zend\Mvc\View\Http\ExceptionStrategy::prepareExceptionViewModel(MvcEvent $e) retourne une instance de ViewModel, qui ne contient évidemment pas le supplémentaires $options les informations dont j'ai besoin.

Aussi il retourne ViewModel et pas ProtobufModel, ce qui signifie que le Zend invoque le défaut ViewPhpRenderer et les sorties de l'exception, comme une page HTML.

Ce que je veux faire est remplacez la valeur par défaut ExceptionStrategy (et éventuellement le RouteNotFoundStrategy) avec mes propres classes, ce qui serait le retour à quelque chose comme ceci:

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

...et je ne trouve pas le moyen de le faire...

J'ai essayé de créer mon propre ExceptionStrategy de la classe et de l'alias à l'existant ExceptionStrategy service mais Zend s'est plaint que le service avec ce nom existe déjà.

Je soupçonne que je suis sur la bonne voie avec la stratégie de l'extension, je ne peux pas trouver un moyen de remplacer celui par défaut.

J'ai remarqué que, par défaut, ExceptionStrategy et la console s'inscrire dans Zend/Mvc/View/Http/ViewManager.J'espère que je n'aurai pas à ajouter une vue personnalisée des gestionnaires à atteindre une telle chose simple, mais s'il vous plaît, corrigez-moi si je me trompe.

Toute aide sera appréciée!

Était-ce utile?

La solution

Le plus simple est de faire un peu de fausser.

Tout d'abord, enregistrez votre auditeur à une priorité plus élevée que la ExceptionStrategy;depuis, il s'inscrit à la priorité par défaut, cela signifie une priorité supérieure à 1.

Ensuite, dans votre auditeur, avant de le retourner, assurez-vous de définir le "erreur" dans la MvcEvent à un falsy valeur:

$e->setError(false);

Une fois que vous avez fait cela, le défaut ExceptionStrategy va dire, "rien à faire ici, se déplacent à l'aller et au retour au début, avant de faire quoi que ce soit avec le ViewModel.

Pendant que vous y êtes, vous aussi, assurez-vous de changer le résultat de l'instance dans les cas suivants:

$e->setResult($yourProtobufModel)

pour s'assurer que c'est ce qui est inspecté par d'autres auditeurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top