문제

안녕하세요 여러분,

저는 이 문제로 일주일 넘게 씨름하다가 마침내 누군가가 답을 알고 있기를 바라면서 도움을 요청하기로 결정했습니다.

나는 다음을 사용하는 응용 프로그램을 개발 중입니다. Google의 프로토콜 버퍼 데이터 교환 형식으로.DrSlump의 PHP를 사용하고 있습니다. 구현, 를 사용하면 클래스 인스턴스를 데이터로 채운 다음 이를 바이너리 문자열로 직렬화할 수 있습니다(또는 바이너리 문자열을 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, 분명히 추가 내용이 포함되어 있지 않습니다. $옵션 나에게 필요한 정보.

또한 그것은 반환 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 클래스를 생성하고 이를 기존 클래스에 별칭으로 지정합니다. 예외전략 서비스인데 Zend는 그러한 이름을 가진 서비스가 이미 존재한다고 불평했습니다.

사용자 정의 전략 확장을 사용하여 올바른 길을 가고 있다는 의심이 듭니다. 기본 전략 확장을 재정의하는 방법을 찾을 수 없습니다.

나는 기본값이 ExceptionStrategy 그리고 콘솔 하나가 등록됩니다 Zend/Mvc/View/Http/ViewManager.이렇게 간단한 작업을 수행하기 위해 사용자 정의 보기 관리자를 추가할 필요가 없기를 바라지만, 제가 틀렸다면 정정해 주시기 바랍니다.

어떤 도움이라도 주시면 감사하겠습니다!

도움이 되었습니까?

해결책

가장 쉬운 방법은 약간의 퍼지를 수행하는 것입니다.

먼저 ExceptionStrategy보다 높은 우선순위로 실행되도록 리스너를 등록합니다.기본 우선순위로 등록되므로 이는 1보다 높은 우선순위를 의미합니다.

그런 다음 리스너에서 반환하기 전에 MvcEvent의 "오류"를 잘못된 값으로 설정했는지 확인하세요.

$e->setError(false);

이 작업을 수행하면 기본 ExceptionStrategy는 "여기서 할 일이 없습니다. 계속 진행하세요"라고 말하고 ViewModel로 작업을 수행하기 전에 일찍 돌아옵니다.

그 동안 이벤트의 결과 인스턴스도 변경했는지 확인해야 합니다.

$e->setResult($yourProtobufModel)

이는 다른 청취자가 검사하는 내용을 보장하기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top