【问题标题】:Zend Framework function that isn't an action in controllerZend Framework 函数不是控制器中的动作
【发布时间】:2017-02-02 13:33:45
【问题描述】:

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

例子:下面Controller中的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);
}

【问题讨论】:

    标签: php model-view-controller zend-framework2 zend-framework3


    【解决方案1】:

    我建议在此服务中使用公共方法 createCookie 创建一个 CookieService。然后,您可以将此服务注入您的控制器类并在您的操作中调用此方法,而不会使用额外的 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);
    

    【讨论】:

      【解决方案2】:

      我有点同意 Jannes Botis,但我会更灵活一点...

      如果您查看Matthew's last blog post 之一(Using zend-soap within a zend-mvc application 部分),您会发现他使用了一个私有函数 (populateServer),这仅在上述两个操作的上下文中才有原因。

      我可以看到您使用了zend-framework3,所以我实际上建议使用PSR7 middleware 堆栈来分派您的请求并在“下一个”中间件中生成 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;
          }
      }
      

      如果你沿着这条路走,请告诉我们进展如何 :)

      【讨论】:

        【解决方案3】:

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

        • 您不能在不同的控制器之间共享“createCookie”函数,并且将您的函数复制到不同的控制器。
        • 即使您将控制器扩展为基本控制器,这也可能导致过度扩展并再次使您的代码无法维护。
        • 也许这不是在“Single responsibility principle”之后。

        为此,我建议您使用:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多