在 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 特性。