如何使serviceManager在类zf2上工作

周日SL

我在module.php上定义了一些服务,这些服务按预期的方式声明为:

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'Marketplace\V1\Rest\Service\ServiceCollection' =>  function($sm) {
                    $tableGateway = $sm->get('ServiceCollectionGateway');
                    $table = new ServiceCollection($tableGateway);
                    return $table;
                },
            'ServiceCollectionGateway' => function ($sm) {
                    $dbAdapter = $sm->get('PdoAdapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new ServiceEntity());
                    return new TableGateway('service', $dbAdapter, null, $resultSetPrototype);
                },
            'Marketplace\V1\Rest\User\UserCollection' =>  function($sm) {
                    $tableGateway = $sm->get('UserCollectionGateway');
                    $table = new UserCollection($tableGateway);
                    return $table;
                },
            'UserCollectionGateway' => function ($sm) {
                    $dbAdapter = $sm->get('PdoAdapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new UserEntity());
                    return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
                },
        ),
    );
}

我用它们将我的数据库表映射到一个对象。从项目的主类中,我可以毫无问题地访问它们。看一下我的项目文件树:

在此处输入图片说明

例如,userResource.php扩展了abstractResource,此函数有效:

public function fetch($id)
{
    $result = $this->getUserCollection()->findOne(['id'=>$id]);
    return $result;
}

在ResourceAbstract内部,我有:

<?php

namespace Marketplace\V1\Abstracts;

use ZF\Rest\AbstractResourceListener;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class ResourceAbstract extends AbstractResourceListener implements ServiceLocatorAwareInterface {

    protected $serviceLocator;


    public function getServiceCollection() {
        $sm = $this->getServiceLocator();
        return $sm->get('Marketplace\V1\Rest\Service\ServiceCollection');
    }

    public function getUserCollection() {
        $sm = $this->getServiceLocator();
        return $sm->get('Marketplace\V1\Rest\User\UserCollection');
    }

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
    }

    public function getServiceLocator() {
        return $this->serviceLocator;
    }

} 

正如Zf2文档所建议的那样,我需要实现ServiceLocatorAwareInterface才能使用serviceManager。到目前为止,一切都很好。然后,我决定添加一个新类,称为Auth。

此类与abstractResource差别不大,它在loginController中这样调用:

<?php
namespace Marketplace\V1\Rpc\Login;

use Zend\Mvc\Controller\AbstractActionController;
use Marketplace\V1\Functions\Auth;

class LoginController extends AbstractActionController
{
    public function loginAction()
    {
        $auth = new Auth();
        $data = $this->params()->fromPost();
        var_dump($auth->checkPassword($data['email'], $data['password']));

        die;
    }


}

这是Auth:

<?php

namespace Marketplace\V1\Functions;


use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class Auth implements ServiceLocatorAwareInterface {

    protected $serviceLocator;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
    }

    public function getServiceLocator() {
        return $this->serviceLocator;
    }

    public function checkPassword($email, $rawPassword) {

        $user = $this->getServiceLocator()->get('Marketplace\V1\Rest\User\UserCollection')->findByEmail($email);
        if($user)
            return false;

        $result = $this->genPassword($rawPassword, $user->salt);

        if($result['password'] === $user->password)
            return true;
        else
            return false;

    }

    public function genPassword($rawPassword, $salt = null) {
        if(!$salt)
            $salt = mcrypt_create_iv(22, MCRYPT_DEV_URANDOM);
        $options = [
            'cost' => 11,
            'salt' => $salt,
        ];
        return ['password' => password_hash($rawPassword, PASSWORD_BCRYPT, $options), 'salt' => bin2hex($salt)];
    }

}

如您所见,它遵循与abtractResource相同的路径,但在这种情况下,当我执行loginController时,我得到一个错误:

Fatal error</b>:  Call to a member function get() on null in C:\WT-NMP\WWW\MarketPlaceApi\module\Marketplace\src\Marketplace\V1\Functions\Auth.php on line 25

那指的是这一行: $user = $this->getServiceLocator()->get('Marketplace\V1\Rest\User\UserCollection')->findByEmail($email);

这意味着getServiceLocator为空。为什么我不能让serviceLocator在Auth类上工作,但是我可以在abstractResource中工作呢?

猜测

这是因为ServiceLocator通过称为“ setter注入”的机制注入。为此,在这种情况下,某些东西(例如ServiceManager)需要调用类的设置器setServiceLocator当您直接实例化时Auth,情况并非如此。您需要将类添加到服务定位器中,例如作为可调用服务。

例如:

public function getServiceConfig()
{
    return array(
        'invokables' => array(
            'Auth' => '\Marketplace\V1\Functions\Auth',
        ),
    );
}

或者,更恰当地说,因为它不为工厂使用匿名函数,请将其放在模块配置文件“ modules / Marketplace / config / module.config.php”中:

// ... 
'service_manager' => array(
    'invokables' => array(
        'Auth' => '\Marketplace\V1\Functions\Auth',
    ),
),

您可以Auth从控制器中的服务定位器获取

$auth = $this->getServiceLocator()->get('Auth');

代替:

$auth = new Auth;

这样,服务定位器将为Auth构造,检查其实现了哪些接口以及何时发现确实实现了接口,ServiceLocatorAwareInterface然后它将运行setter并将其自身的实例传递给它。有趣的事实:控制器本身以相同的方式注入了服务定位器的实例(这是实现完全相同的接口此类的祖先)。另一个有趣的事实:即行为可能在将来改变这里讨论

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ZF2:如何从自定义类中获取ServiceManager实例

来自分类Dev

ZF2:如何将Application ServiceManager配置为自动添加类?

来自分类Dev

zf2 Zend \ ServiceManager \ Exception \ ServiceNotCreatedException

来自分类Dev

ZF2:如何在测试过程中重置ServiceManager

来自分类Dev

ZF2测试-serviceManager忽略了模拟对象

来自分类Dev

ZF2测试-serviceManager忽略了模拟对象

来自分类Dev

如何在zf2中使用辅助类?

来自分类Dev

ZF2 setCookie无法正常工作

来自分类Dev

PHP ZF2:找不到类

来自分类Dev

ZF2 ServiceManager无法创建doctrine.entitymanager.orm_default

来自分类Dev

ZF2 ServiceManager无法创建doctrine.entitymanager.orm_default

来自分类Dev

如何使用wordpress运行zf2?

来自分类Dev

ZF2如何调用函数

来自分类Dev

ZF2:如何翻译表单注释?

来自分类Dev

如何使学说和ZF2表单注释一起工作

来自分类Dev

ZF2如何在抽象实体类中注入服务定位器或插件

来自分类Dev

如何在实体类中使用URL ZF2

来自分类Dev

如何在zf2中使用帮助器类?

来自分类Dev

ZF2翻译

来自分类Dev

Resque找不到作业类ZF2命名空间

来自分类Dev

使用ZF2更新类更新多个表

来自分类Dev

在生产中找不到ZF2类

来自分类Dev

ZF2-PHPUnit-ServiceManager错误

来自分类Dev

如何在ZF2中扩展字段集以使用Doctrine的类表继承映射策略

来自分类Dev

如何使用Composer安装PayumModule(ZF2)

来自分类Dev

如何在ZF2中添加列以选择语句?

来自分类Dev

ZF2如何将变量传递给表单

来自分类Dev

如何在ZF2中默认返回JsonModel?

来自分类Dev

zf2验证:如何验证相关字段?