Zend 框架中的 GetServiceLocator
GetServiceLocator in Zend Framework 3
早上好,我一直在学习使用框架(Zend Framework)进行编程。
在我过去的经验中,我使用的是骨架应用程序 v.2.5。也就是说,我过去开发的所有模块都围绕 ServiceManager 的 servicelocator() 工作。
有什么方法可以在 zend framework 3 中安装 ServiceManager(具有 servicelocator 功能)?
如果没有,你能给我一个绕过 servicelocator 的适当方法吗?
感谢您的关注,祝您度过愉快的一天:)
*/ 已更新 - 以小模块为例。
作为示例,我将向您展示我在 2.5 中使用的登录身份验证模块:
我的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;
},
),
);
}
}
我的授权控制器:
<?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();
}
}
我的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:
<?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 中不再有服务定位器,因为它被视为反模式。
正确的方法是在服务管理器中使用工厂,并将特定的依赖项传递到您的 class。
如果您有任何代码可以展示,我很乐意进一步帮助您。
根据提供的示例进行编辑。
首先,使用 composer 进行自动加载,而不是使用旧的 Zend 东西。在 Module.php 中,删除自动加载。还需要删除 autoload_classmap 文件。
添加一个 composer.json 文件并设置你的 PSR-0 或 PSR-4 自动加载(如果你不知道如何操作,请询问)。
返回模块 class,您还需要更改服务管理器配置。我在这里保留你的匿名函数,但你应该使用正确的 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)。
让我们只关注一个简单的控制器。其他人需要重复同样的事情。
<?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(将服务作为参数注入)。
看github上的代码,master分支据我所知引入了ZF3兼容性,就去看看吧!
早上好,我一直在学习使用框架(Zend Framework)进行编程。 在我过去的经验中,我使用的是骨架应用程序 v.2.5。也就是说,我过去开发的所有模块都围绕 ServiceManager 的 servicelocator() 工作。 有什么方法可以在 zend framework 3 中安装 ServiceManager(具有 servicelocator 功能)?
如果没有,你能给我一个绕过 servicelocator 的适当方法吗?
感谢您的关注,祝您度过愉快的一天:)
*/ 已更新 - 以小模块为例。 作为示例,我将向您展示我在 2.5 中使用的登录身份验证模块:
我的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;
},
),
);
}
}
我的授权控制器:
<?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();
}
}
我的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:
<?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 中不再有服务定位器,因为它被视为反模式。
正确的方法是在服务管理器中使用工厂,并将特定的依赖项传递到您的 class。
如果您有任何代码可以展示,我很乐意进一步帮助您。
根据提供的示例进行编辑。
首先,使用 composer 进行自动加载,而不是使用旧的 Zend 东西。在 Module.php 中,删除自动加载。还需要删除 autoload_classmap 文件。
添加一个 composer.json 文件并设置你的 PSR-0 或 PSR-4 自动加载(如果你不知道如何操作,请询问)。
返回模块 class,您还需要更改服务管理器配置。我在这里保留你的匿名函数,但你应该使用正确的 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)。
让我们只关注一个简单的控制器。其他人需要重复同样的事情。
<?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(将服务作为参数注入)。
看github上的代码,master分支据我所知引入了ZF3兼容性,就去看看吧!