Introduzione a Zend Framework 2 per chi proviene da Zend Framework 1, tenuta allo Zend Framework Day di Milano del 01/02/2013. Introduzione alle nuove caratteristiche e pattern architetturali di ZF2
Zend Framework 2 non è l'evoluzione di ZF, ma un progetto nuovo: il codice è stato riscritto e poche sono le parti in comune con la versione precedente. Lo sviluppatore abituato a ZF1 non ha vita facile, ed è fondato il timore di dover imparare tutto da capo. In questo talk vediamo come cambiare le vecchie abitudini di sviluppatori ZF1, per sfruttare al meglio le potenzialità del nuovo strumento. Attraverso esempi concreti, in cui vedremo all'opera i nuovi pattern e le best practice, mostriamo come - partendo con il piede giusto - il passaggio a ZF2 possa essere meno traumatico del previsto. Il talk è orientato soprattutto a chi già conosce ZF1, ma gli argomenti affrontati possono essere utili anche a chi si avvicina a ZF per la prima volta.
1 of 149
Download to read offline
More Related Content
Fare con Zend Framework 2 ciò che facevo con ZF1
1. Zend Framework 2
Fare con
ciò che facevo con ZF1
Zend Framework Day – Milano – 01/02/2013
49. index.php
<?php
/**
* This makes our life easier when dealing with paths. Everything is
* relative to the application root now.
*/
chdir(dirname(__DIR__));
// Setup autoloading
require 'init_autoloader.php';
// Run the application!
ZendMvcApplication::init(require 'config/application.config.php')->run();
55. Module.php
<?php [...]
class Module implements
AutoloaderProviderInterface,
ConfigProviderInterface,
ServiceProviderInterface {
public function getAutoloaderConfig() {[...]}
public function getConfig($env = null) {
return include __DIR__ . '/config/module.config.php';
}
public function getControllerPluginConfig() {[...]}
public function getViewHelperConfig() {[...]}
public function getServiceConfig() {[...]}
}
65. Controller Semplice in ZF2
<?php
namespace ApplicationController;
use ZendMvcControllerAbstractActionController;
use ZendViewModelViewModel;
class IndexController extends AbstractActionController
{
public function indexAction()
{
$timestamp = time();
return new ViewModel(array(
'timestamp' => $timestamp
));
}
}
68. Controller ZF1
[…]
class IdraulicoController extends Zend_Controller_Action {
public function installaCaldaia () {
$operatore = new Operatore();
$esito = $operatore->installaCaldaia();
$this->view->esito =$esito;
}
69. Scendiamo nel dettaglio
[…]
class IdraulicoController extends Zend_Controller_Action {
public function installaCaldaia () {
$operatore = new Operatore();
$esito = $operatore->installaCaldaia();
$this->view->esito =$esito;
}
70. Com’è fatto questo oggetto?
[…]
Class Operatore {
public function __constructor () {
$this->caldaia = new Caldaia();
}
public function getCaldaia() {
return $this->caldaia;
}
public function installaCaldaia() {
// Fai qualcosa con $this->caldaia
}
}
71. Dipendenza. Siamo vincolati!
[…]
Class Operatore {
public function __constructor () {
$this->caldaia = new Caldaia();
}
public function getCaldaia() {
return $this->caldaia;
}
public function installaCaldaia() {
// Fai qualcosa con $this->caldaia
}
}
73. Siamo vincolati
[…]
Class Operatore {
public function __constructor (Caldaia $caldaia) {
$this->caldaia = $caldaia;
}
public function getCaldaia() {
return $this->caldaia;
}
public function installaCaldaia() {
// Fai qualcosa con $this->caldaia
}
}
74. Siamo vincolati
[…]
Class Operatore {
public function __constructor (Caldaia $caldaia) {
$this->caldaia = $caldaia;
}
public function getCaldaia() {
return $this->caldaia;
}
public function installaCaldaia() {
// Fai qualcosa con $this->caldaia
}
}
75. Test operatore
[…]
class OperatoreTest extends TestCase {
function testInstallaCaldaia() {
$caldaia = mockCaldaia();
$operatore = new Operatore($caldaia);
$esito = $operatore->installaCaldaia();
$this->assertTrue($esito);
}
}
95. Uso del Service Locator?
[…]
class Termostato implements ServiceLocatorAwareInterface {
[…]
public function getTemperatura() {
$sm = $this->getServiceLocator();
$sensore = $sm->get(‘AziendaModelTermoSensore');
return $sensore->getTemperatura();
}
public function setServiceLocator(ServiceLocatorInterface
$serviceLocator) {
$this->serviceLocator = $serviceLocator; }
public function getServiceLocator() {
return $this->serviceLocator; }
}
96. Abuso del Service Locator
[…]
class Termostato implements ServiceLocatorAwareInterface {
[…]
public function getTemperatura() {
$sm = $this->getServiceLocator();
$sensore = $sm->get(‘AziendaModelTermoSensore');
return $sensore->getTemperatura();
}
public function setServiceLocator(ServiceLocatorInterface
$serviceLocator) {
$this->serviceLocator = $serviceLocator; }
public function getServiceLocator() {
return $this->serviceLocator; }
}
98. Abuso del Service Locator
[…]
class Termostato implements ServiceLocatorAwareInterface {
[…]
public function getTemperatura() {
$sm = $this->getServiceLocator();
$sensore = $sm->get(‘AziendaModelTermoSensore');
return $sensore->getTemperatura();
}
public function setServiceLocator(ServiceLocatorInterface
$serviceLocator) {
$this->serviceLocator = $serviceLocator; }
public function getServiceLocator() {
return $this->serviceLocator; }
}
99. Factory per il Controller
[…]
Class IdraulicoControllerFactory implements
FactoryInterface {
public static function
createService(ServiceLocatorInterface $services) {
$sm = $services->getServiceLocator();
$operatore = $sm->get(‘Operatore');
return new IdraulicoController($operatore);
}
[…]
}
?>
102. Scambio di messaggi
class IdraulicoController {
public function installaCaldaiaAction() {
$operatore = $this->serviceLocator->get(‘operatore’);
$esito = $I_operatore->installaCaldaia();
$I_logger = new Logger();
$I_logger->log(‘Installazione Caldaia’);
return new ViewModel(‘operatore’ => $operatore,
‘esito’ => $esito);
}
}
103. Mi trovo nel posto giusto?
class IdraulicoController {
public function installaCaldaiaAction() {
$operatore = $this->serviceLocator->get(‘operatore’);
$esito = $I_operatore->installaCaldaia();
$I_logger = new Logger();
$I_logger->log(‘Installazione Caldaia’);
return new ViewModel(‘operatore’ => $operatore,
‘esito’ => $esito);
}
}
106. Problema di estendibilità
$s_msg = ‘Installazione Caldaia’;
$I_logger = new Logger();
$I_logger->log($s_msg);
$I_mailer = new Mailer();
$I_mailer->mail($s_msg);
[…]
117. Esempio con controller plugin
<?php
namespace ApplicationController;
use ZendMvcControllerAbstractActionController;
use ZendViewModelViewModel;
class IndexController extends AbstractActionController
{
public function redirectAction()
{
$this->redirect()->toUrl(‘http://www.zfday.it’);
}
}
119. Factory per il Controller
[…]
use ZendMvcControllerAbstractActionController;
use ZendViewModelViewModel;
class IndexController extends AbstractActionController
{
public function scriviNomeAction()
{
$nome = $this->getEvent()
->getRouteMatch()->getParam('slug');
return (‘nome’ => $nome);
}
}
122. Ma non ho ancora l’EM!
[…]
use ZendMvcControllerAbstractActionController;
use ZendViewModelViewModel;
class IndexController extends AbstractActionController
{
public function __construct()
{
$this->azienda = $this->getEvent()
->getRouteMatch()->getParam(‘azienda');
}
}
123. Sulla Dependency Injection…
[…]
// Sul costruttore
public function __construct($dipendenza) {
$this->dipendenza = $dipendenza;
}
// Con setters
Public function __construct() {
}
Public function setDipendenza() {
$this->dipendenza = $dipendenza;
}
124. Agisco sul setter
[…]
use ZendMvcControllerAbstractActionController;
use ZendViewModelViewModel;
class IdraulicoController extends AbstractActionController
{
public function setEventManager(EventManagerInterface $events) {
parent::setEventManager($events);
$controller = $this;
$events->attach('dispatch', function ($e) use ($controller) {
$this->name = $controller->params()->fromRoute(‘azienda',
‘Sconosciuta');
}
}}
Vedasi anche il post di M. W. O’Phinney: http://www.mwop.net/blog/2012-07-30-the-new-init.html
127. View
//view index/index.phtml
<div class="row">
<!-- Including header partial -->
<?php echo $this->partial('partials/header.phtml', array()); ?>
<!-- Stampiamo la data -->
<h1>Actual time is: <?php echo $this->timestamp;?></h1>
</div>
128. View con helper
//usando il view helper printData
//view index/index.phtml
<div class="row">
<!-- Including header partial -->
<?php echo $this->partial('partials/header.phtml', array()); ?>
<!-- Stampiamo la data -->
<h1>Actual time is:
<?php echo $this->printData($this->timestamp);?>
</h1>
</div>
129. Helper
//Creando un viewHelper per formattare la data
// Va registrato tra gli invokables del SM dei ViewHelpers
<?php
namespace ApplicationViewHelper;
class PrintData extends ZendViewHelperAbstractHelper {
public function __invoke($timestamp) {
$date = new DateTime();
$date->setTimestamp($timestamp);
$result = $date->format('d-m-Y H:i');
return $result;
}
}
131. Creando una form
//Creiamo il file ContactForm dentro nostro modulo Application/src/Form
<?php
namespace ApplicationForm;
use ZendFormElement;
use ZendFormForm;
class ContactForm extends Form
{
public function __construct()
{
parent::__construct();
// …
}
//...
}
135. Validation: inputFilter
//creiamo l'imput filter contactFilter.php dentro Application/src/Form
<?php
namespace ApplicationForm;
use ZendInputFilterInputFilter;
use ZendValidatorHostname as HostnameValidator;
class ContactFilter extends InputFilter
{
public function __construct()
{
//aggiungiamo i filtri
}
}
137. Controller: Usando la form
namespace ApplicationController;
use ZendMvcControllerAbstractActionController;
use ApplicationFormContact;
use ApplicationFormContactFilter;
class IndexController extends AbstractActionController
{
public function contactAction()
{
$form = new Contact();
$filter = new ContactFilter();
$form->setInputFilter($filter);
return new ViewModel(array(
'form' => $form
);
}
}
145. In sintesi
1. Maggior enfasi sul riuso. Tenere a mente
che ci sono i Moduli
2. Su ZF2 si segue maggiormente un
approccio orientato alla configurazione
piuttosto che convenzione
3. Lo strumento cerca di favorire il
disaccoppiamento (EventManager) e
l’inversione di controllo
(ServiceManager, DI)
145