早上好,我一直在学习使用框架(Zend Framework)进行编程。 在我过去的经历中,我使用的是骨架应用程序v.2.5。话虽如此,我过去开发的所有模块都是围绕来自ServiceManager的servicelocator()工作的。 有没有办法在zend框架3中安装ServiceManager(带有servicelocator功能)?
如果没有,你可以给我一个使用servicelocator工作的方法吗?
感谢您的关注,祝您有个美好的一天:)
* / UPDATED - 小模块为例。 作为一个例子,我将向您展示我在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;
},
),
);
}
}
我的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:
<?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();
}
}
答案 0 :(得分:2)
ZF3中没有更多服务定位器,因为它被视为反模式。
正确的方法是在服务管理器中使用工厂,并将特定的依赖项传递到您的类中。
如果您有任何可以展示的代码,我们将很乐意为您提供进一步的帮助。
根据提供的示例进行编辑。
首先,使用composer进行自动加载而不是旧的Zend。在Module.php中,删除自动加载。还需要删除autoload_classmap文件。
添加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(将服务注入参数)。
查看github上的代码,master分支从我所看到的内容中引入了ZF3兼容性,所以看看那里!