在 ZF2 中创建服务
Creating a service in ZF2
我在理解在 ZF2 中跨不同控制器重用代码的最佳方式时遇到了一些问题。
一个解决方案是从我有我想要的功能的控制器扩展:
class someController extends whereMyFunctionIs {
//DO SOME THINGS THAT MAY OR MAY NOT NEED foo function
}
所以控制器是:
class whereMyFunctionIs {
public function foo() {
return "bar";
}
//and a some other functions...
}
这项工作但不是很聪明,因为我将不得不从 whereMyFunctionIs 扩展我的所有控制器,并且它可以具有许多我的控制器可能不需要的功能。我希望只有当我真正需要它们时才可以使用和加载单一功能。阅读 ZF2 文档,我看到一个解决方案可能是创建服务。但我不能让它们正常工作。这是我得到的:
IndexController(我正在测试的地方):
public function indexAction() {
$auth = $this->getServiceLocator()->get('Application\Service\Authentication');
}
Module.php(在我的模块主应用程序中)
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\UserTable' => function($sm) {
$tableGateway = $sm->get('UserTableGateway');
$table = new UserTable($tableGateway);
return $table;
},
'UserTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new User());
return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
},
'Application\Service\Authentication' => 'Application\Service\AuthenticationFactory',
),
);
}
Application\src\Service 我有两个文件:Authentication.php 和 AuthenticationFactory.php,其中:
Authentication.php
class Authentication {
public function isUser($email, $password) {
return $email;
}
}
AuthenticationFactory.php
<?php
namespace Application\Service\Authentication;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class AuthenticationFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$authentication = new Authentication(
$serviceLocator->get('Application\Model\Asset\AbstractAsset')
);
return $authentication;
}
}
正在执行 IndexController 我得到:
An error occurred during execution; please try again later.
Informazioni aggiuntive:
Zend\ServiceManager\Exception\ServiceNotCreatedException
File:
C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:1059
Messaggio:
While attempting to create applicationserviceauthentication(alias: Application\Service\Authentication) an invalid factory was registered for this instance type.
Stack trace:
#0 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php(633): Zend\ServiceManager\ServiceManager->createFromFactory('applicationserv...', 'Application\Ser...')
#1 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php(593): Zend\ServiceManager\ServiceManager->doCreate('Application\Ser...', 'applicationserv...')
#2 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php(525): Zend\ServiceManager\ServiceManager->create(Array)
#3 C:\WT-NMP\WWW\marketplace\module\Application\src\Application\Controller\IndexController.php(16): Zend\ServiceManager\ServiceManager->get('Application\Ser...')
#4 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\Controller\AbstractActionController.php(83): Application\Controller\IndexController->indexAction()
#5 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#6 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#7 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\Controller\AbstractController.php(116): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#9 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\DispatchListener.php(113): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#10 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#11 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#12 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#13 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\Application.php(313): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 C:\WT-NMP\WWW\marketplace\public\index.php(17): Zend\Mvc\Application->run()
#15 {main}
这是跨控制器重用代码的正确方法吗?如果是,我缺少什么?
错误是由这一行引起的:
namespace Application\Service\Authentication;
需要:
namespace Application\Service;
假设您忘记在服务 class 本身中包含名称空间并且它是正确的。我认为服务与其工厂混淆,实例化了错误的对象(服务而不是工厂),因此出现错误。
这种方法还可以,尽管从我在 zf2 github 页面上阅读的内容来看,如今从控制器工厂向控制器注入服务更为有利(也许一直如此)。
至于功能(一些可重复使用的小代码,不是完整的服务等),您也可以考虑使用 PHP 特性。
我在理解在 ZF2 中跨不同控制器重用代码的最佳方式时遇到了一些问题。
一个解决方案是从我有我想要的功能的控制器扩展:
class someController extends whereMyFunctionIs {
//DO SOME THINGS THAT MAY OR MAY NOT NEED foo function
}
所以控制器是:
class whereMyFunctionIs {
public function foo() {
return "bar";
}
//and a some other functions...
}
这项工作但不是很聪明,因为我将不得不从 whereMyFunctionIs 扩展我的所有控制器,并且它可以具有许多我的控制器可能不需要的功能。我希望只有当我真正需要它们时才可以使用和加载单一功能。阅读 ZF2 文档,我看到一个解决方案可能是创建服务。但我不能让它们正常工作。这是我得到的:
IndexController(我正在测试的地方):
public function indexAction() {
$auth = $this->getServiceLocator()->get('Application\Service\Authentication');
}
Module.php(在我的模块主应用程序中)
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\UserTable' => function($sm) {
$tableGateway = $sm->get('UserTableGateway');
$table = new UserTable($tableGateway);
return $table;
},
'UserTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new User());
return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
},
'Application\Service\Authentication' => 'Application\Service\AuthenticationFactory',
),
);
}
Application\src\Service 我有两个文件:Authentication.php 和 AuthenticationFactory.php,其中:
Authentication.php
class Authentication {
public function isUser($email, $password) {
return $email;
}
}
AuthenticationFactory.php
<?php
namespace Application\Service\Authentication;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class AuthenticationFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$authentication = new Authentication(
$serviceLocator->get('Application\Model\Asset\AbstractAsset')
);
return $authentication;
}
}
正在执行 IndexController 我得到:
An error occurred during execution; please try again later.
Informazioni aggiuntive:
Zend\ServiceManager\Exception\ServiceNotCreatedException
File:
C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:1059
Messaggio:
While attempting to create applicationserviceauthentication(alias: Application\Service\Authentication) an invalid factory was registered for this instance type.
Stack trace:
#0 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php(633): Zend\ServiceManager\ServiceManager->createFromFactory('applicationserv...', 'Application\Ser...')
#1 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php(593): Zend\ServiceManager\ServiceManager->doCreate('Application\Ser...', 'applicationserv...')
#2 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php(525): Zend\ServiceManager\ServiceManager->create(Array)
#3 C:\WT-NMP\WWW\marketplace\module\Application\src\Application\Controller\IndexController.php(16): Zend\ServiceManager\ServiceManager->get('Application\Ser...')
#4 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\Controller\AbstractActionController.php(83): Application\Controller\IndexController->indexAction()
#5 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#6 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#7 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\Controller\AbstractController.php(116): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#9 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\DispatchListener.php(113): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#10 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#11 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#12 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#13 C:\WT-NMP\WWW\marketplace\vendor\zendframework\zendframework\library\Zend\Mvc\Application.php(313): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 C:\WT-NMP\WWW\marketplace\public\index.php(17): Zend\Mvc\Application->run()
#15 {main}
这是跨控制器重用代码的正确方法吗?如果是,我缺少什么?
错误是由这一行引起的:
namespace Application\Service\Authentication;
需要:
namespace Application\Service;
假设您忘记在服务 class 本身中包含名称空间并且它是正确的。我认为服务与其工厂混淆,实例化了错误的对象(服务而不是工厂),因此出现错误。
这种方法还可以,尽管从我在 zf2 github 页面上阅读的内容来看,如今从控制器工厂向控制器注入服务更为有利(也许一直如此)。
至于功能(一些可重复使用的小代码,不是完整的服务等),您也可以考虑使用 PHP 特性。