Перенаправление из библиотеки

0

Я создаю как веб-приложение Symfony 2.6, так и библиотеку композиторов. Библиотека композитора ничего не знает о Symfony и нуждается в работе с другими фреймворками (или вообще без фреймворка).

В какой-то момент библиотека должна перенаправить пользователя. Конечно, в простой библиотеке естественно называть PHP- header('Location: x'). Это отлично работает при тестировании библиотеки с прямым PHP и без фреймворка. Но в приложении Symfony контроллер, вызывающий библиотеку, все равно должен создать объект Response и вернуть его. Фактически создание пустого Response завершает очистку перенаправления. Я предполагаю, что классы Symfony создают совершенно новый набор заголовков, перезаписывая набор Location в библиотеке.

Итак, не заставляя мою библиотеку зависить от Symfony, как она может перенаправить пользователя?

Теги:

2 ответа

3
Лучший ответ

Используйте интерфейс, который ваша библиотека определяет и использует посредством инъекции зависимостей.

interface Redirector {
    public function redirect($location, $code);
}

В своей библиотеке вы можете передать его как аргумент конструкторам классов, например:

class FooBar {
    private $redirector;

    public function __construct(Redirector $red) {
        $this->redirector = $red;
    }

    // ...
}

Реализация этого интерфейса может использовать механизмы symfony для выполнения фактического перенаправления, и ваша библиотека не зависит от какой-либо реализации.

Возможной реализацией может быть:

class SimpleRedirector implements Redirector {
     public function redirect($location, $code) {
          header('Location: ' . $location, true, $code);
          die();
     }
}
  • 0
    Так просто и умно. Я собираюсь попробовать это и посмотреть, каково это.
  • 0
    И посмотрите на PSR7
1

Полностью согласен с SirDarius. Это простой дизайн по контракту (DbC). Ваш компонент объявляет интерфейс, которое любое приложение может реализовать по-своему.

Я думал о том, как реализовать его symfony. Обычный простой способ перенаправления PHP в PHP довольно прост. Но чистая реализация Symfony сложнее, поскольку действие контроллера должно возвращать объект ответа и не может просто умереть, потому что ядро должно завершиться. В этом случае Redirector является службой области с запросом на состояние, сохраняя данные перенаправления и предоставляя метод getResponse.

<?php

class RedirectionService implements Redirector {
    private $location;
    private $code;

    public function redirect($location, $code) {
        $this->location = $location;
        $this->code = $code;
    }

    public function getResponse() {
        $response = new RedirectResponse($this->location, $this->code);
        return $response;
    }
}

// ...

public function someAction() {
    // defined in services.yml and gets our service injected
    $libraryService = $this->get('library_service');
    $libraryService->work();

    $redirectionService = $this->get('redirection_service');
    $response = $redirectionService->getResponse();
    return $response;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню