web-dev-qa-db-ja.com

KernelEvents :: REQUESTイベントから404を発行する方法

KernelEvents :: REQUESTイベントから404を発行しようとしていますが、次のエラーが発生します。

Fatal error: Maximum function nesting level of '256' reached, aborting! in /var/www/vendor/symfony/http-foundation/HeaderBag.php on line 162

これが私のクラスです

<?php

namespace Drupal\my_module\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;

class MyClass implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['my404Check'];

    return $events;
  }

  public function my404Check(GetResponseEvent $event) {
    // Do some logic here to check if it should be a 404.
    throw new NotFoundHttpException();
  }

}

ここでは例外をスローできないと思いますが、404を発行する方法に関する他のドキュメントを表示できません。

2
leon.nk

リクエストイベントの早い段階でレスポンスを設定できます。

 public function my404Check(GetResponseEvent $event) {

    // only return a response for a master request
    if (!$event->isMasterRequest()) {
      return;
    }

    // Do some logic here to check if it should be a 404.

    $response = new Response('', Response::HTTP_NOT_FOUND);
    $event->setResponse($response);
  }

イベントディスパッチャーは、応答が既に設定されているかどうかを確認し、コードを実行せずにこの応答を返し、Drupal応答を作成します。

3
4k4

私はこれが古いことを知っていますが、他の誰かがこれを見つけた場合に備えて...応答を設定するだけでは不十分でした)。また、手動で応答を作成するのではなく、コードの他の場所と同じようにNotFoundHttpExceptionを単にスローすることも好みます。

このアプローチでは、イベントからキャッチした例外を単にNotFoundHttpExceptionに「変換」します。例外の二重ロギングを回避するために、コアのExceptionLoggingSubscriberよりも高い優先度を使用していることに注意してください。

  /**
   * {@inheritdoc}
   *
   * Use priority > 50 to run before core's ExceptionLoggingSubscriber.
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::EXCEPTION][] = ['onException', 60];
    return $events;
  }

  /**
   * Return a 404.
   *
   * @param GetResponseForExceptionEvent $event
   */
  public function onException(GetResponseForExceptionEvent $event) {
    $e = $event->getException();
    if ({{CUSTOM LOGIC HERE}}) {
      $new_exception = new NotFoundHttpException($e->getMessage());
      $event->setException($new_exception);
    }
  }
0
twill