Zend Framework 3 中的 GetServiceLocator

2024-03-28

早上好,我一直在学习使用框架(Zend Framework)进行编程。 根据我过去的经验,我使用的是骨架应用程序 v.2.5。也就是说,我过去开发的所有模块都围绕 ServiceManager 的 servicelocator() 工作。 有没有办法在 zend Framework 3 中安装 ServiceManager(具有 servicelocator 功能)?

如果没有,您能给我发送一个解决服务定位器的正确方法吗?

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

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

我的模块.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;
    },
        ),
    );
}

}

我的验证控制器:

<?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');
    }
}

我的成功控制器:

<?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();
    }
 }

我的用户.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:

<?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 中不再有服务定位器,因为它被视为反模式。

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

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


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

首先,使用 Composer 进行自动加载,而不是使用旧的 Zend 东西。在 Module.php 中,删除自动加载。删除自动加载类映射 https://github.com/samsonasik/SanAuth/blob/master/autoload_classmap.php还需要文件。

添加一个composer.json 文件并设置PSR-0 或PSR-4 自动加载(如果您不知道如何操作,请询问)。

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

<?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)。

让我们只关注一个简​​单的控制器。其他人也需要重复同样的事情。

<?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 https://github.com/samsonasik/SanAuth/blob/master/config/module.config.php#L10(将服务作为参数注入)。

看github上的代码,据我所知,master分支引入了ZF3兼容性,所以你看一下!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Zend Framework 3 中的 GetServiceLocator 的相关文章

随机推荐

  • ssrs 2008级联参数

    我目前正在使用 SQL 2008 R2 和 SQL Server Report Service 2008 我正在使用以下参数创建报告 Staff name Client name Lab lab date 等 当用户选择 Staff 名称时
  • Common Lisp 类型声明未按预期工作

    当我在 Common Lisp 中定义一个函数时 如下所示 defun foo n declare type fixnum n n 42 我期待一个像这样的电话 foo a 立即失败 但在调用时失败 是个declareform 不保证静态类
  • 如何绕过 .NET 中未处理的异常处理来克服 StackOverflowException

    在遇到 NET 中的一些 StackOverflowExceptions 后 我注意到它们完全绕过了 NET 提供的未处理的异常处理程序 Application ThreadException AppDomain UnhandledExce
  • JavaScript - 修复计算器的 da*n 插入符号

    我正在用 javascript 制作一个计算器 到目前为止它的计算结果是 sin cos tan cot sec csc并且arc and hyberbolic所有亚型中 sqrt cbrt y th root and pow 问题是我不想
  • 检索早于提要中包含的 RSS 帖子

    创建 RSS 阅读器时 您可以下载 RSS 提要链接指向的 XML 格式文档 并且可以手动解析它或使用 SyndicateFeed 命名空间中的功能 因此 如果我们以 Scott Guthrie 的博客为例 您下载 RSS feed 文档h
  • 将 Highcharts 最大 Y 值设置为精确值而不进行四舍五入

    每次我在 Highcharts 中设置最小值和最大值时 我都不会得到具有我发送的精确最小值和最大值的图表 但总是有些接近的值 似乎 Highcharts 正在为轴选择一个间隔范围 如果我的最大值不符合正确的间隔 它就会被忽略或四舍五入 例如
  • 防止 VS Code IntelliSense 在函数名称后插入 ={}

    自上次 Visual Studio Code 更新以来 我在 IntelliSense 自动完成方面遇到了问题 一般来说 如果我想将函数设置为 prop 这是此问题最常见的用例 那么 VS Code 不只是插入函数名称 而是添加 括号 那么
  • 如何在没有 jQuery 的情况下模拟 ajaxStart 和 ajaxStop?

    我一直在查看 jQuery 代码 但它有点庞大 这是一件容易的事吗 知道怎么做吗 我想要这样做的原因是因为我不想将它用于网页 而是用于 C 应用程序 该应用程序需要知道何时有 ajax 活动在网页浏览器 http msdn microsof
  • 如何使用php使用多个数据库?

    我在互联网上阅读了多个问题 包括这个堆栈溢出问题 https stackoverflow com questions 274892 how do you connect to multiple mysql databases on a si
  • D3.js - 如何添加具有默认滚轮鼠标缩放行为的缩放按钮

    因此 我使用默认的 d3 behavior zoom 获得了带有鼠标缩放的世界地图 并进行了限制以防止地图被完全拖出页面 开始工作时很痛苦 但现在可以了 我现在的问题是 这个项目还需要界面中无用的缩放 和 按钮 并且我找不到具有两种缩放类型
  • 使用 JQuery 进行本地化?

    我不知道如何使用 JQuery 处理本地化 我想设置一个innerHTML使用德语文本 但如果浏览器配置为使用英语 那么我想设置英语文本 在 PHP 中 我使用 gettext 来完成此类操作 但是如何在 JavaScript jQuery
  • Automapper:检查 MapFrom 中的 null

    使用版本 4 制作地图时如何检查 null 我尝试过 Value 但那不存在于Null Mapper CreateMap
  • 我应该如何在 Java 中为 Android 手机实现准确的音高检测?

    我想开发一个应用程序 需要通过 Android 手机的麦克风对乐器进行精确的音高检测 我读到的大多数建议都涉及使用快速傅里叶变换 FFT 但他们提到它在准确性和处理能力方面存在问题 考虑到它应该在智能手机上顺利运行 一个答案建议误差幅度为
  • net-snmp解析代码,如何解析MIB?

    我在学习代码库 解析MIB In parse c and parse h代码保留一个哈希桶 indexed bucket tree list 还有一个树结构 其中包含一个指向的next指针Next node in hashed list o
  • a*b* 是正则吗?

    I know anbn for n gt 0 is not regular by the pumping lemma but I would imagine a b to be regular since both a b don t ha
  • .NET Framework 上的 System.Numerics.Vector 初始化性能

    System Numerics Vector 为 NET Core 和 NET Framework 带来了 SIMD 支持 它适用于 NET Framework 4 6 和 NET Core Baseline public void Sim
  • Google Apps 脚本是否支持外部 IDE?

    我正在使用 Google Apps 脚本 想知道是否可以使用 Google 提供的编辑器之外的任何类型的编辑器 我购买了 Sublime Text 并且想使用它 Google 提供的那个很恶心 文本很小 尽管我有一个巨大的屏幕和语法颜色 我
  • Android 单选按钮

    我在 Android 中有一个单选按钮组 看起来像 选择颜色 Red Blue Orange Green 我需要选择单选按钮及其值 我在 radiogroup 中以这种方式有 4 个单选按钮rg rb1a RadioButton findV
  • Chrome CLI 的参数 --virtual-time-budget 的真正含义是什么?

    我知道该论点的文档 virtual time budget 在源中 https cs chromium org chromium src headless app headless shell switches ccChromium 但我觉
  • Zend Framework 3 中的 GetServiceLocator

    早上好 我一直在学习使用框架 Zend Framework 进行编程 根据我过去的经验 我使用的是骨架应用程序 v 2 5 也就是说 我过去开发的所有模块都围绕 ServiceManager 的 servicelocator 工作 有没有办