在ZF2中创建服务

时间:2015-02-08 16:35:31

标签: php zend-framework zend-framework2

我有一些问题需要了解在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}

这是跨控制器重用代码的正确方法吗?如果是的话,我错过了什么?

1 个答案:

答案 0 :(得分:4)

错误是由此行引起的:

namespace Application\Service\Authentication;

需要:

namespace Application\Service;

假设您忘记在服务类本身中包含命名空间并且它是正确的。我认为服务与其工厂混淆,错误的对象被实例化(服务不是工厂),因而错误。

这种方法还可以,但是从我在zf2 github页面上阅读的内容来看,从控制器工厂向控制器注入服务现在更有利(可能一直都是这样)。

至于功能(所以一些可重复使用的小代码,而不是完整的服务等),你也可以考虑使用PHP的特性。