Zend框架中不是控制器动作的函数

4

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

例如:下面控制器中的createCookie函数。

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);
}
3个回答

1
在我看来,这可能会使您的代码更难维护,原因如下:
  • 您无法在不同的控制器之间共享“createCookie”函数,并且需要将函数复制到不同的控制器中。
  • 即使您将控制器扩展到基本控制器,这也可能导致过度扩展,再次使您的代码难以维护。
  • 也许这不符合“单一职责原则”。
为此,我建议您使用:

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);

1

我有点同意Jannes Botis的看法,但我会更灵活一些...

如果您查看Matthew的最新博客文章在zend-mvc应用程序中使用zend-soap部分),您可以看到他使用了一个私有函数(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;
    }
}

如果您选择这条路,请告诉我们进展如何 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接