Zend Framework 2:将变量传递给View Helper

时间:2014-11-17 20:28:56

标签: php zend-framework2

我创建了一个View Helper来显示数据库表中的最新广告。由于我有不同类型的广告,我希望能够从我的View中传递一个变量,我称之为View Helper来显示特定的广告。

我很抱歉我无法以更好的方式解释它,但我仍然是ZF2的初学者。我将添加源代码,希望这将使它更清晰。请注意,我有一本书中的源代码随机显示了比萨饼,并将其更改为显示我的广告。我可能仍然在其中有代码,这实际上并不需要,所以请不要怀疑......好的,这里的代码:

1。视图:index.html

<?php foreach ($this->latestAdvert() as $value){ ?>
      <li><?php echo $value->getAdvertTitle();?></li>
<?php }?>

2。视图助手:广告\视图\助手\ LatestAdvert.php

namespace Advert\View\Helper;
use Zend\View\Helper\AbstractHelper;

class LatestAdvert extends AbstractHelper
{

   protected $random = null;


   public function __construct($random)
   {
     $this->setLatestAdvert($random);
   }


   public function setLatestAdvert($random)
   {
     $this->random = $random;
   }


   public function getLatestAdvert()
   {
     return $this->random;
   }


   public function __invoke()
   {
     $latestAdverts = $this->getLatestAdvert();
     return $latestAdverts;
   }
}

第3。工厂:广告\查看\助手\ LatestAdvertFactory.php

namespace Advert\View\Helper;

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

class LatestAdvertFactory implements FactoryInterface
{

    public function createService(ServiceLocatorInterface $serviceLocator) 
    {
      $locator = $serviceLocator->getServiceLocator();
      $service = $locator->get('Advert\Service');
      $random  = $service->fetchSingleByRandom();
      $helper  = new LatestAdvert($random);

      return $helper;
    }
}

4。服务:Advert \ Service \ LatestAdvertService .php

namespace Advert\Service;

use Advert\Entity\Advert as AdvertEntity;
use Doctrine\ORM\EntityManager;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\Debug\Debug;

class LatestAdvertService implements ServiceManagerAwareInterface
{

  /**
   * Service manager.
   * @var Zend\ServiceManager\ServiceManager
   */
   private $serviceManager = null;

  /**
   * Sets service manager.
   * @param Zend\ServiceManager\ServiceManager $serviceManager Service manager.
   */
  public function setServiceManager(ServiceManager $serviceManager)
  {
    $this->serviceManager = $serviceManager;
  }

  /**
   * Returns service manager.
   * @return type
   */
  public function getServiceLocator()
  {
    return $this->serviceManager;
  }


  public function fetchSingleByRandom()
  {     
    // Get Doctrine entity manager.
    $entityManager =  $this->getServiceLocator()
                           ->get('doctrine.entitymanager.orm_default');
    $advertType = 'wanted'; // This should be removed
    $random = $entityManager->getRepository('Advert\Entity\Advert')
                            ->findAdvertsByDate($advertType);

    return $random; 
  }
}

5。模块:Advert \ Module.php

public function getServiceConfig()
{
    return array(
        'invokables' => array(
                 'Advert\Service' => 'Advert\Service\LatestAdvertService',
                    ),
    );
}

public function getViewHelperConfig()
{
    return array(
        'factories' => array(           
            'latestAdvert' => 'Advert\View\Helper\LatestAdvertFactory',
        ),

    );
}

正如您在#4中看到的,我有一个名为$ advertType的变量。当我在index.html中调用视图Helper时,我想设置变量,f.e。 $ this-&gt; latestAdvert(&#39;想要&#39;),但是如何通过我的所有文件传递此变量?我只是找不到解决方案。有没有人得到我的提示如何实现它?非常感谢你提前。

!UPDATE!

正如SenseException在下面指出的那样,将服务定位器注入服务是一种不好的做法,而我应该将存储库或实体管理器注入服务,我现在已经为实体管理器制定了第一个工作解决方案。 / p>

为此,我更新了2个文件:module.php和LatestAdvertService.php

#5 module.php

public function getServiceConfig()
{
    return array(
            'factories' => array(

                    'Advert\Service' => function ($sl) {
                        $entityManager =   $sl->get('doctrine.entitymanager.orm_default');
                        $myService = new Service\LatestAdvertService();
                        $myService->setEntityManager($entityManager);
                        //or you can set repository
                        //$repository = $entityManager->getRepository('Advert\Entity\Advert');
                        //$myService->setRepository($repository);
                        return $myService;
                    },

4。服务:Advert \ Service \ LatestAdvertService .php

namespace Advert\Service;

use Advert\Entity\Advert as AdvertEntity;
use Doctrine\ORM\EntityManager;

class LatestAdvertService 
{


  public function setEntityManager(EntityManager $entityManager)
  {
    $this->entityManager = $entityManager;
  }

  public function setRepository(Repository $repository) {
   $this->repository = $repository;
  }


  public function fetchSingleByAdvertType($advertType)
  {

    $random = $this->entityManager->getRepository('Advert\Entity\Advert')->findAdvertsByDate($advertType);  
//  $random = $this->repository->findAdvertsByDate($advertType);

    return $random;
  }
}

我试图注入存储库,但收到以下错误消息:

传递给Advert \ Service \ LatestAdvertService :: setRepository()的参数1必须是Advert \ Service \ AdvertRepository的实例,广告\存储库\ AdvertRepository的实例,在 <中调用< /强>

我将继续为存储库注入找到解决方案,并在成功时进行更新。

1 个答案:

答案 0 :(得分:2)

这个解决方案怎么样:

namespace Advert\View\Helper;

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

class LatestAdvertFactory implements FactoryInterface
{

    public function createService(ServiceLocatorInterface $serviceLocator) 
    {
      $locator = $serviceLocator->getServiceLocator();
      $service = $locator->get('Advert\Service');
      $helper  = new LatestAdvert($service);

      return $helper;
    }
}

当然是辅助类:

namespace Advert\View\Helper;
use Zend\View\Helper\AbstractHelper;

class LatestAdvert extends AbstractHelper
{

   protected $service;


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

   public function __invoke($advertType)
   {
       $latestAdverts = $this->service->fetchSingleByAdvertType($advertType);
       return $latestAdverts;
   }
}

对于服务:

public function fetchSingleByAdvertType($advertType)
{
    $entityManager =  $this->getServiceLocator()
                           ->get('doctrine.entitymanager.orm_default');

    $random = $entityManager->getRepository('Advert\Entity\Advert')
                            ->findAdvertsByDate($advertType);

    return $random; 
}

我尽量让您的代码尽可能接近原始代码,但请听一些有关服务定位器的建议。将服务定位器注入服务是一种不好的做法,就像在LatestAdvertService中一样。由于您只需要一个服务器存储库,只需将其注入其中即可。如果您需要服务中的实体管理器,请将其注入。你的单元测试会感谢你。