简体   繁体   中英

Zend Framework function that isn't an action in controller

Is it bad practice to create a function in a controller that isn't an action?

example: The createCookie function in the below 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);
}

In my opinion, this can lead to making your code more difficult to maintain, due to the fact:

  • You cannot share "createCookie" function between different controllers and you replicate your functions to different controllers.
  • Even if you extend your controllers to a base one, this can lead to overextending and again making your code unmaintainable.
  • Maybe this is not following the " Single responsibility principle ".

For this, I would suggest you use:

I would suggest creating a CookieService with a public method createCookie inside this service. You can then inject this service inside your controller class and call this method inside your action without polluting your controller class with the additional cookie related logic.

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

Adding the cookie to the response could be done inside this service as well. So this line would be solved inside your CookieService :

$this->getResponse()->getHeaders()->addHeader($this->cookie);

I kind of agree with Jannes Botis , but I would be a little more flexible...

If you look at one of Matthew's last blog post (section Using zend-soap within a zend-mvc application ), you can see he uses a private function ( populateServer ), which only has a reason in the context of both of the actions above.

I can see you used the zend-framework3 , so what I would actually recommend is to use a PSR7 middleware stack to dispatch your request and generate the cookies in the "next" middleware. As of today, I am not sure the stack are supported in the routes, so you would probably need to pass a callable through your constructor and call it if it exists.

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

Let us know how it goes if you go down this route :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM