Zend Framework 2:何在 Module.php 中设置 Cookie 以从其他模块访问

Zend Framework 2: Ho to set Cookie in Module.php to access from other Modules

我创建了一个展示广告的项目。每个广告都有一个位置。

当前显示广告的列表。我现在想要我的 layout.phtml 中的位置列表,点击该位置后应过滤广告。

为此,我创建了一个名为 Geolocation 的新模块。然后我创建了两个新的视图助手;一个显示所有位置,另一个显示所选位置的名称,该名称存储在 Cookie 中。

当您单击列表中的某个位置时,会向 Geolocation Controller 发出 AJAX 请求。控制器调用服务中的方法将位置存储在 cookie 中。

我现在正在更改我的广告模块中的 SQL 查询和存储库以接受位置(如果已设置):

public function countAdvertsByCategory($location=false)

通常,我会在我的广告控制器中添加 $location = $_COOKIE['ChosenCounty'],但我确信有更好的方法。

我原以为我可以将其添加到地理定位模块的 module.php 中。如果该模块包含变量,$location 将设置为 cookie 值,否则将被忽略。

这是正确的方法还是最佳做法?我该怎么做?

更新

我现在已经改变了我的工厂:

namespace Application\Navigation;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class MyNavigationFactory implements FactoryInterface
{
  public function createService(ServiceLocatorInterface $serviceLocator)
  { 
    // previous without Geolocation
    $navigation =  new MyNavigation();
    return $navigation->createService($serviceLocator); 

    $location = $serviceLocator->get('Geolocation\Service\Geolocation');
    $navigation =  new MyNavigation($location);
    return $navigation->createService($serviceLocator);
  }

但是,如果我现在删除我的地理位置模块,那么我的应用程序模块中用于创建导航的工厂将失败,这意味着我的工厂现在依赖于我不想要的这个新模块。我怎样才能避免这种情况?

您可以将 cookie 值作为 'service' 添加到服务管理器。每当您需要 $location 时,您只需从服务管理器中检索它即可。

创建一个访问所需 cookie 变量的工厂。

namespace GeoLocation\Service;

use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;

class GeoLocationFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $request = $serviceLocator->get('Request');
        $cookies = $request->getHeaders()->get('cookie');

        return isset($cookies->location) ? $cookies->location : false;
    }
}

然后在module.config.php.

中向服务管理器注册
'service_manager' => [
    'factories' => [
        'GeoLocation\Service\GeoLocation' => 'GeoLocation\Service\GeoLocationFactory',
    ],
],

然后您可以更新 AdvertService 以要求值

class AdvertService
{
    protected $location;

    public function __construct($location)
    {
        $this->location = $location;
    }

    public function getAdvertsByCategory()
    {
        return $this->repository->countAdvertsByCategory($this->location);
    }
}

然后您可以创建一个新的 AdvertServiceFactory,它将使用

获取服务并将其注入 AdvertService::__construct
$serviceManager->get('GeoLocation\Service\GeoLocation');