Zend Framework 3中的GetServiceLocator [英] GetServiceLocator in Zend Framework 3

查看:81
本文介绍了Zend Framework 3中的GetServiceLocator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

早上好,我一直在学习使用框架(Zend Framework)进行编程. 根据我过去的经验,我使用的是骨架应用程序v.2.5.话虽如此,我所有以前开发的模块都围绕ServiceManager的servicelocator()工作. 有什么方法可以在zend Framework 3中安装ServiceManager(带有servicelocator功能)?

Good morning, i have been learning to program using a framework (Zend Framework). In my past experiences i was using a skeleton application v.2.5. That been said, all my past developed Modules work around servicelocator() from ServiceManager. Is there any way of installing ServiceManager(with the servicelocator functionality) in zend framework 3?

如果没有,您可以给我发送适当的方法来解决servicelocator吗?

If not, can you send me a propor way to work around servicelocator?

感谢您的关注,祝您有个美好的一天:)

Thank You for atention, have a awesome day :)

*/更新-以小模块为例. 作为示例,我将向您展示我在2.5中使用的登录身份验证模块:

*/ UPDATED - Small module as example. As an example i will show you a login authentication module that i was using back in 2.5:

我的Module.php

my Module.php

<?php

namespace SanAuth;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\Authentication\Storage;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Adapter\DbTable as DbTableAuthAdapter;

class Module implements AutoloaderProviderInterface
{
    public function getAutoloaderConfig()
    {
        return array(
             'Zend\Loader\StandardAutoloader' => array(
                 'namespaces' => array(
                     __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                 ),
              ),
        );
    }
    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function getServiceConfig()
    {
        return array(
            'factories'=>array(
         'SanAuth\Model\MyAuthStorage' => function($sm){
            return new \SanAuth\Model\MyAuthStorage('zf_tutorial');  
        },

        'AuthService' => function($sm) {
            $dbAdapter           = $sm->get('Zend\Db\Adapter\Adapter');
                $dbTableAuthAdapter  = new DbTableAuthAdapter($dbAdapter, 
                                          'users','user_name','pass_word', 'MD5(?)');

        $authService = new AuthenticationService();
        $authService->setAdapter($dbTableAuthAdapter);
                $authService->setStorage($sm->get('SanAuth\Model\MyAuthStorage'));

        return $authService;
    },
        ),
    );
}

}

我的AuthController:

my AuthController:

<?php
//module/SanAuth/src/SanAuth/Controller/AuthController.php
namespace SanAuth\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\Form\Annotation\AnnotationBuilder;
use Zend\View\Model\ViewModel;

use SanAuth\Model\User;

class AuthController extends AbstractActionController
{
    protected $form;
    protected $storage;
    protected $authservice;

    public function getAuthService()
    {
        if (! $this->authservice) {
            $this->authservice = $this->getServiceLocator()
                                  ->get('AuthService');
        }

        return $this->authservice;
    }

    public function getSessionStorage()
    {
        if (! $this->storage) {
            $this->storage = $this->getServiceLocator()
                              ->get('SanAuth\Model\MyAuthStorage');
        }

        return $this->storage;
    }

    public function getForm()
    {
        if (! $this->form) {
           $user       = new User();
           $builder    = new AnnotationBuilder();
           $this->form = $builder->createForm($user);
        }
        $this->form->setLabel('Entrar')
            ->setAttribute('class', 'comment_form')
            ->setAttribute('style', 'width: 100px;');

       return $this->form;
    }

    public function loginAction()
    {
        //if already login, redirect to success page 
        if ($this->getAuthService()->hasIdentity()){
           return $this->redirect()->toRoute('success');
        }

        $form       = $this->getForm();

        return array(
            'form'      => $form,
            'messages'  => $this->flashmessenger()->getMessages()
        );
    }

    public function authenticateAction()
    {
        $form       = $this->getForm();
        $redirect = 'login';

        $request = $this->getRequest();
        if ($request->isPost()){
            $form->setData($request->getPost());
            if ($form->isValid()){
                //check authentication...
                $this->getAuthService()->getAdapter()
                                     ->setIdentity($request->getPost('username'))
                                   ->setCredential($request->getPost('password'));

            $result = $this->getAuthService()->authenticate();
            foreach($result->getMessages() as $message)
            {
                //save message temporary into flashmessenger
                $this->flashmessenger()->addMessage($message);
            }

            if ($result->isValid()) {
                $redirect = 'success';
                //check if it has rememberMe :
                if ($request->getPost('rememberme') == 1 ) {
                    $this->getSessionStorage()
                         ->setRememberMe(1);
                    //set storage again 
                    $this->getAuthService()->setStorage($this->getSessionStorage());
                }
                $this->getAuthService()->getStorage()->write($request->getPost('username'));
                }
             }
         }

       return $this->redirect()->toRoute($redirect);
     }

    public function logoutAction()
    {
       $this->getSessionStorage()->forgetMe();
       $this->getAuthService()->clearIdentity();

       $this->flashmessenger()->addMessage("You've been logged out");
       return $this->redirect()->toRoute('login');
    }
}

我的SucessController:

My SucessController:

<?php
//module/SanAuth/src/SanAuth/Controller/SuccessController.php
namespace SanAuth\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class SuccessController extends AbstractActionController
{
    public function indexAction()
    {
        if (! $this->getServiceLocator()
                 ->get('AuthService')->hasIdentity()){
            return $this->redirect()->toRoute('login');
        }

        return new ViewModel();
    }
 }

我的User.php:

my User.php:

<?php
namespace SanAuth\Model;

use Zend\Form\Annotation;

/**
 * @Annotation\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty")
 * @Annotation\Name("User")
 */
class User
{
    /**
     * @Annotation\Type("Zend\Form\Element\Text")
     * @Annotation\Required({"required":"true" })
     * @Annotation\Filter({"name":"StripTags"})
     * @Annotation\Options({"label":"Utilizador:  "})
     */
    public $username;

    /**
     * @Annotation\Type("Zend\Form\Element\Password")
     * @Annotation\Required({"required":"true" })
     * @Annotation\Filter({"name":"StripTags"})
     * @Annotation\Options({"label":"Password:  "})
     */
    public $password;

    /**
     * @Annotation\Type("Zend\Form\Element\Checkbox")
     * @Annotation\Options({"label":"Lembrar "})
     */
    public $rememberme;

    /**
     * @Annotation\Type("Zend\Form\Element\Submit")
     * @Annotation\Attributes({"value":"Entrar"})
     */
    public $submit;
}

和MyAuthStorage.php:

And MyAuthStorage.php:

<?php
namespace SanAuth\Model;

use Zend\Authentication\Storage;

class MyAuthStorage extends Storage\Session
{
    public function setRememberMe($rememberMe = 0, $time = 1209600)
    {
         if ($rememberMe == 1) {
             $this->session->getManager()->rememberMe($time);
         }
    }

    public function forgetMe()
    {
        $this->session->getManager()->forgetMe();
    } 
}

推荐答案

ZF3中没有服务定位符,因为它被视为反模式.

There is no more service locator in ZF3 as it is considered as an antipattern.

正确的处理方法是在服务管理器中使用工厂,并将特定的依赖项传递给您的类.

The proper way to proceed is to use factories in the service manager, and pass specific dependencies into your class.

如果您可以显示任何代码,我们将很乐意为您提供进一步的帮助.

If you have any code you can show, I'll be happy to help you further.

根据提供的示例进行编辑.

Edit according to the example provided.

首先,使用composer进行自动加载,而不要使用旧的Zend.在Module.php中,删除自动加载功能.还需要删除 autoload_classmap 文件.

First thing first, use composer for autoloading rather than the old Zend stuff. In Module.php, remove the autoloading. Removing the autoload_classmap file is also required.

添加composer.json文件并设置您的PSR-0或PSR-4自动加载功能(如果您不知道如何,请询问).

Add a composer.json file and set your PSR-0 or PSR-4 autoloading (ask if you don't know how).

回到Module类,您还需要更改服务管理器配置.我在这里保留您的匿名函数,但您应该使用适当的类.

Back on the Module class, you also need to change the service manager configuration. I'm keeping your anonymous functions here but you should use proper classes.

<?php

namespace SanAuth;

use Zend\Authentication\Storage;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Adapter\DbTable as DbTableAuthAdapter;

final class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    public function getServiceConfig()
    {
        return [
            'factories'=> [
                \SanAuth\Model\MyAuthStorage::class => function($container){
                    return new \SanAuth\Model\MyAuthStorage('zf_tutorial');
                },
                'AuthService' => function($container) {
                    $dbAdapter = $sm->get(\Zend\Db\Adapter\Adapter::class);
                    $dbTableAuthAdapter = new DbTableAuthAdapter($dbAdapter, 'users','user_name','pass_word', 'MD5(?)');
                    $authService = new AuthenticationService();
                    $authService->setAdapter($dbTableAuthAdapter);
                    $authService->setStorage($container->get(SanAuth\Model\MyAuthStorage::class));

                    return $authService;
                },
            ),
        );
    }
}

另外,请考虑使用password_ *函数而不是MD5(或其他,但无论如何都不使用md5).

Also, please consider using password_* functions rather than MD5 (or whatever, but not md5 anyways).

让我们只关注一个简​​单的控制器.对于其他事物,需要重复同样的事情.

Let's focus on just one simple controller. Same things needs to be repeated for the others.

<?php

namespace SanAuth\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Authentication\AuthenticationService;

final class SuccessController extends AbstractActionController
{
    private $authenticationService;

    public function __construct(AuthenticationService $authenticationService)
    {
        $this->authenticationService = $authenticationService;
    }

    public function indexAction()
    {
        if (! $this->authenticationService->hasIdentity()){
            return $this->redirect()->toRoute('login');
        }

        return new ViewModel();
    }
}

显然,您需要更新工厂: https://github.com/samsonasik/SanAuth/blob/master/config/module.config.php#L10 (将服务作为参数注入).

Obviously you need to update the factory: https://github.com/samsonasik/SanAuth/blob/master/config/module.config.php#L10 (inject the service as parameter).

看看github上的代码,master分支从我所看到的内容中介绍了ZF3兼容性,所以在那里看看!

Looking at the code on github, the master branch introduces ZF3 compatibility from what I can see, so have a look there!

这篇关于Zend Framework 3中的GetServiceLocator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆