我一直在阅读ZF2服务定位器组件,可以说我理解它是如何被使用的。然而,我有一个问题,我觉得它很愚蠢,但问一下也没什么坏处。
我希望在我的模块中有一个名为Component的命名空间,我可以将通用代码放在如FunctionComponent.php,MailerComponent.php或ExcelComponent.php中。这将允许我在我的控制器中做一些事情。
我想尝试的是让控制器定义他们有兴趣使用的组件(见下文):
class SalesController extends AbstractController
{
protected $components = ['Excel'];
//In some action
public function exportAction()
{
$data = ['data to be exported'];
/**
$data : data to be exported
boolean : Whether to force download or save the file in a dedicated location
*/
$this->Excel->export($data, true);
}
}
想法是创建一个ComponentCollection,它可能实现FactoryInterface或ServiceLocatorInterface,然后让它在我的Module类中触发MvcEvent时检查每个控制器,并让ComponentCollection注入所有控制器组件并使它们可以访问而不使用服务定位器如下图所示:
$excel = $sm->get('Application\Component\Excel');
我很清楚这可能看起来像是一个令人生畏的问题,但我觉得学习框架的最好方法就是玩弄它并尝试做到难以想象。
答案 0 :(得分:1)
您应该在某处创建BaseController
,然后从Controllers
扩展您的所有BaseController
。然后,您可以在BaseController
中注入依赖项,并在孩子的任何地方使用。例如,我在我的Controller
中执行此操作以设置标题:
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
class BaseController extends AbstractActionController
{
/**
* Sets the head title for every page
*
* @param string $title
*/
public function setHeadTitle($title)
{
$viewHelperManager = $this->getServiceLocator()->get('ViewHelperManager');
// Getting the headTitle helper from the view helper manager
$headTitleHelper = $viewHelperManager->get('headTitle');
// Setting a separator string for segments
$headTitleHelper->setSeparator(' - ');
// Setting the action, controller, module and site name as title segments
$siteName = 'Ribbon Cutters';
$translator = $this->getServiceLocator()->get('translator');
$title = $translator->translate($title);
$headTitleHelper->append(ucfirst($title));
$headTitleHelper->append($siteName);
}
}
您可以定义属性,而不是定义方法。
public $headTitleHelper
并在BaseController
$this->headTitleHelper = $this->getServiceLocator()->get('ViewHelperManager')->get('headTitle');
现在您可以在子控制器中使用$this->headTitleHelper
。
然后
<?php
namespace Application\Controller;
use Zend\View\Model\ViewModel;
use Application\Controller\BaseController;
class IndexController extends BaseController
{
/**
* Property for setting entity manager of doctrine
*/
protected $em;
/**
* landing page
*
* @return ViewModel
*/
public function indexAction()
{
$this->setHeadTitle('Welcome'); // Welcome - Ribbon Cutters
$viewModel = new ViewModel();
return $viewModel;
}
/**
* Sets and gives Doctrine Entity Manager
*
* @return Doctrine Entity Manager
*/
protected function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->em;
}
}
我认为这可以帮助你。