从库中重定向

时间:2015-02-06 15:00:57

标签: php symfony

我正在构建一个Symfony 2.6 Web应用程序和一个作曲家库。作曲家库对Symfony一无所知,需要与其他框架一起运行(或根本没有框架)。

在某些时候,图书馆需要重定向用户。当然,在一个简单的库中调用PHP的header('Location: x')是很自然的。这在使用直接PHP和没有框架测试库时工作正常。但是在Symfony应用程序中,调用库的控制器仍然需要创建一个Response对象并将其返回。实际上,创建一个空的Response最终会清除重定向。我假设Symfony类创建了一组全新的标题,覆盖了库中的Location集。

因此,如果不让我的库依赖于Symfony,它如何重定向用户?

2 个答案:

答案 0 :(得分: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();
     }
}

答案 1 :(得分:1)

完全同意SirDarius。 它是一个简单的按合同设计(DbC)模式。 您的组件正在声明任何应用程序可以以自己的方式实现的界面。

我想过如何实现它symfony。简单的旧PHP重定向方式非常简单。但是干净的Symfony实现更加困难,因为控制器操作必须返回一个响应对象,并且不能因为内核必须终止而死亡。在这种情况下,重定向器是一个有状态请求范围服务,保存重定向数据并提供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;
}