【问题标题】:Creating a service in ZF2在 ZF2 中创建服务
【发布时间】:2015-02-08 16:35:30
【问题描述】:

我在理解 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}

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

【问题讨论】:

    标签: php zend-framework zend-framework2


    【解决方案1】:

    错误是由这一行引起的:

    namespace Application\Service\Authentication;
    

    必须是:

    namespace Application\Service;
    

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

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

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

    【讨论】:

    • PHP 的行为方式对我来说很奇怪。我预计会出现错误或其他情况。
    • php 不这样做,这是因为 Zf2 不只是尝试将其作为工厂运行。它会检查它是否为 1,如果不是,它将抛出您看到的错误。
    猜你喜欢
    • 2015-08-03
    • 2014-05-15
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多