在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...
}

这可以工作,但不是很聪明,因为我必须从扩展我的所有控制器,其中MyFunctionIs,它可以具有许多我的控制器可能不需要的功能。我希望只有在我真正需要的时候才能使用和加载单个函数。阅读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 I中有两个文件:Authentication.php和AuthenticationFactory.php,其中:

验证.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;

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

这种方法是可以的,尽管从我在zf2 github页面上读到的内容来看,将服务从控制器工厂注入控制器现在更有利(也许一直如此)。

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