我正在构建一个Symfony 2.6 Web应用程序和一个作曲家库。作曲家库对Symfony一无所知,需要与其他框架一起运行(或根本没有框架)。
在某些时候,图书馆需要重定向用户。当然,在一个简单的库中调用PHP的header('Location: x')
是很自然的。这在使用直接PHP和没有框架测试库时工作正常。但是在Symfony应用程序中,调用库的控制器仍然需要创建一个Response
对象并将其返回。实际上,创建一个空的Response
最终会清除重定向。我假设Symfony类创建了一组全新的标题,覆盖了库中的Location
集。
因此,如果不让我的库依赖于Symfony,它如何重定向用户?
答案 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;
}