4

在控制器中创建一个不是动作的函数是不好的做法吗?

例子:createCookie下面Controller中的函数

protected $translator;
protected $cookie;

public function __construct($translator, $cookie)
{
    $this->translator = $translator;
    $this->cookie = $cookie;
}

public function changeLanguageAction()
{
    $language = $this->params()->fromRoute('lang', 'en');
    $this->createCookie('xuage', $language, '/');
    $this->getResponse()->getHeaders()->addHeader($this->cookie);
    $this->redirect()->toRoute('home');
}

public function createCookie($name, $value, $path)
{
    $this->cookie->setName($name);
    $this->cookie->setValue($value);
    $this->cookie->setPath($path);
}
4

3 回答 3

1

在我看来,这可能导致您的代码更难维护,因为:

  • 您不能在不同的控制器之间共享“createCookie”功能,并且您将您的功能复制到不同的控制器。
  • 即使您将控制器扩展为基本控制器,这也可能导致过度扩展并再次使您的代码无法维护。
  • 也许这不符合“单一责任原则”。

为此,我建议您使用:

于 2017-02-02T16:27:18.050 回答
1

我有点同意Jannes Botis的观点,但我会更灵活一点……

如果您查看Matthew 的上一篇博文(部分Using zend-soap within a zend-mvc application),您可以看到他使用了一个私有函数 ( populateServer),这仅在上述两个操作的上下文中才有原因。

我可以看到你使用了zend-framework3,所以我实际上推荐的是使用PSR7 中间件堆栈来分派你的请求并在“下一个”中间件中生成 cookie。截至今天,我不确定路由是否支持堆栈,因此您可能需要通过构造函数传递一个可调用对象并在它存在时调用它。

final class MyAction()
{
    private $next;

    public function __construct(callable $next = null)
    {
        $this->next = $next;
    }

    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) : ResponseInterface
    {
        // your business code
        if ($this->next) {
            $call = $this->next;
            $call($request, $response);
        }
        if ($next) {
            $next($request, $response);
        }
        return $response;
    }
}

如果您沿着这条路线走,请告诉我们情况如何:)

于 2017-02-03T09:53:53.500 回答
1

我建议在此服务中CookieService使用公共方法创建一个。createCookie然后,您可以将此服务注入您的控制器类并在您的操作中调用此方法,而不会使用额外的 cookie 相关逻辑污染您的控制器类。

protected $translator;
protected $cookieService;

public function __construct($translator, CookieService $cookie)
{
    $this->translator = $translator;
    $this->cookieService = $cookieService;
}

public function changeLanguageAction()
{
    $language = $this->params()->fromRoute('lang', 'en');
    $this->cookieService->createCookie('xuage', $language, '/');
    $this->redirect()->toRoute('home');
}

将 cookie 添加到响应中也可以在此服务中完成。所以这条线将在你的内部解决CookieService

$this->getResponse()->getHeaders()->addHeader($this->cookie);
于 2017-02-03T09:53:05.220 回答