getServicelocator()
macht Fehler. Es braucht also einen alternativen Weg. Und erstreckt sich AbstractTableGateway
oder ServiceLocatorAwareInterface
haben Fehler.
Factory-Implementierung wird Controller helfen, Objekte zu bekommen.
* User Beispielcode wird Album ähnlich sein.
1) Factory-Klasse (RegisterControllerFactory.php) * kopiert Funktion create in Controller
namespace Users\Controller\Factory;
use Users\Controller\RegisterController;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
class RegisterControllerFactory
{
public function __invoke($serviceLocator)
{
$sm = $serviceLocator;
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user' /* table name */, $dbAdapter, null, $resultSetPrototype);
$user = new \Users\Model\User();
$userTable = new \Users\Model\UserTable($tableGateway);
$controller = new RegisterController($userTable, $serviceLocator);
return $controller;
}
}
2) Controller (RegisterController) Namespace Users \-Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Users\Form\RegisterForm;
use Users\Form\RegisterFilter;
use Users\Model\User;
use Users\Model\UserTable;
use Zend\ServiceManager\ServiceLocatorInterface;
class RegisterController extends AbstractActionController
{
protected $userTable;
protected $serviceManager;
public function __construct(UserTable $userTable, ServiceLocatorInterface $serviceManager)
{
$this->userTable = $userTable;
$this->serviceManager = $serviceManager;
}
public function indexAction()
{
$form = new RegisterForm();
$viewModel = new ViewModel(array('form' => $form));
return $viewModel;
}
public function processAction()
{
if (!$this->request->isPost()) {
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'index'
));
}
$post = $this->request->getPost();
$form = new RegisterForm();
$inputFilter = new RegisterFilter();
$form->setInputFilter($inputFilter);
$form->setData($post);
if (!$form->isValid()) {
$model = new ViewModel(array(
'error' => true,
'form' => $form,
));
$model->setTemplate('users/register/index');
return $model;
}
// Create user
$this->createUser($form->getData());
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'confirm'
));
}
public function confirmAction()
{
$viewModel = new ViewModel();
return $viewModel;
}
protected function createUser(array $data)
{ /*able to delete or modify */
$sm = $this->serviceManager;
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user' /* table name */, $dbAdapter, null, $resultSetPrototype);
$user = new User();
$user->exchangeArray($data);
$userTable = new UserTable($tableGateway);
$userTable->saveUser($user);
return true;
}
}
3) module.config.php
return array(
'controllers' => array(
'invokables' => array(
'Users\Controller\Index' => 'Users\Controller\IndexController',
'Users\Controller\login' => 'Users\Controller\LoginController',
//delete 'Users\Controller\Register'
),
'factories' => array(
'Users\Controller\Register' => 'Users\Controller\Factory\RegisterControllerFactory',
),
),
Nun, danke, es funktioniert wirklich! Und wie man mit anderen Klassen als Klasse sein soll, erweitert AbstractTableGateway zum Beispiel mit den Klassen der Forms (extends Zend \ Form), den Klassen der Elemente (extends Zend \ Form \ Element)? Wie benutze ich den ServiceLocator?Oder verwenden Sie es dort ist eine schlechte Idee? .. – Eremite
Wenn die Klasse durch den ServiceManager erstellt wird, die die bewusste Schnittstelle implementiert, dann wird der ServiceManager injiziert, nachdem die Klasse erstellt wurde. Für Zend \ Form kann dies ein Problem darstellen, da die meisten Elemente im Konstruktor erstellt werden (SM wird nach diesem Punkt eingefügt). Es gibt einen Blogbeitrag, der darüber spricht - http://www.michaelgallego.fr/blog/?p=205 – DrBeza
Ich habe den Kern Ihrer Methode verstanden. Es ist nicht klar, wie ServiceManager automatisch die setServiceManager-Methode aufruft, wenn Sie eine Instanz der form extends Form-Klasse erstellen, die Sie in Ihrem Blog beschreiben. Sie schreiben die Notwendigkeit, das Array 'invokables' für den ServiceManager zu verwenden, könnten Sie im Detail sagen, wie dies zu tun ist. Vielen Dank. – Eremite