SlideShare a Scribd company logo
1 of 76
Download to read offline
High Performance Web
Apps con PHP
e Symfony 2

di Giorgio Cefaro ed Eugenio Pombi
Giorgio Cefaro




@giorrrgio
giorgiocefaro.com
Eugenio Pombi




@euxpom
nerd2business.net
Symfony 2

First, Symfony2 is a reusable set of standalone,
decoupled, and cohesive PHP components that solve
common web development problems. Then, based on
these components, Symfony2 is also a full-stack web
framework.
                                     Fabien Potencier
Request > Response
http://symfony.com/download
get the git repo
git clone git@bitbucket.org:eux/pugx_book.git

git tag -l

git checkout {nomeTag}

git stash

                            nerd2business.net
http://pugx-book.localhost/config.php
tag cap1


git checkout cap1
parameters-dist.yml
parameters:
  database_driver: pdo_mysql
  database_host: 127.0.0.1
  database_port: ~
  database_name: pugx_book
  database_user: root
  database_password: ~

  mailer_transport: smtp
  mailer_host:     127.0.0.1
  mailer_user:     ~
  mailer_password: ~

  locale:      en
  secret:      ThisTokenIsNotSoSecretChangeIt
composer
curl -s https://getcomposer.org/installer | php

composer.json
composer.lock

./composer.phar update
./composer.phar install

minimum-stability
virtual host
<VirtualHost *:80>
 ServerName pugx-book.localhost
 DocumentRoot "/PATH TO PROJECT/pugx_book/web"
 DirectoryIndex index.php
 <Directory "/PATH TO PROJECT/pugx_book/web">
    AllowOverride All
    Require all granted
 </Directory>
</VirtualHost>

PATH TO PUGX PROJECT
/etc/hosts


127.0.0.1   pugx-book.localhost
struttura
bundle
tag cap2


git checkout cap2
il nostro bundle
   php app/console generate:bundle
         --namespace=PUGX/BookBundle
         --format=yml
Bundle namespace [PUGX/BookBundle]:
Bundle name [PUGXBookBundle]:
Target directory [/home/USERNAME/PATH/pugx_book/src]:
Configuration format (yml, xml, php, or annotation) [yml]:

Do you want to generate the whole directory structure [no]? yes
DefaultControllerTest.php

DefaultControllerTest.php

src/PUGX/BookBundle/Tests/Controller/
     DefaultControllerTest.php



phpunit -c app/
front controller
/web/app.php
/web/app_dev.php

/app/config/config.yml
/app/config/config_dev.yml
/app/config/config_prod.yml
/app/config/config_test.yml
routing
/app/config/routing.yml

pugx_book:
   resource: "@PUGXBookBundle/Resources/config/routing.yml"
   prefix:   /




/src/PUGX/BookBundle/Resources/config/routing.yml

pugx_book_homepage:
    pattern: /
    defaults: { _controller: PUGXBookBundle:Default:index }
controller

In genere costituito da una classe che raggruppa una serie
di azioni definite attraverso metodi pubblici.



Il nostro primo controller:
src/PUGX/BookBundle/Controller/DefaultController.php
twig
return $this->render('PUGXBookBundle:Default:index.html.twig');


PUGXBookBundle: <NomeVendor><NomeBundle>
Default:         <NomeController>
index.html.twig: <NomeTemplate>



//src/PUGX/BookBundle/Resources/views/Default/index.html.twig
Hello world!



http://symfony.com/it/doc/2.1/book/templating.html
yay! live coding
//src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php

$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertRegExp("/Welcome/i", $crawler->filter('h1')->text());
$this->assertTrue($crawler->filter('p')->count() > 0);

//nav bar
$this->assertTrue($crawler->filter('.navbar')->count() > 0);
$this->assertEquals(1, $crawler->filter('.navbar > li')->count());
$this->assertRegExp("/home/i", $crawler->filter('.navbar > li:nth-
child(1)')->text());
PHPUnit asserts

verifichiamo che la risposta sia valida
$this->assertTrue($client->getResponse()->isSuccessful());


ci assicuriamo che l’elemento h1 contenga la parola "Welcome":
$this->assertRegExp("/Welcome/i", $crawler->filter('h1')->text());


$crawler è un'istanza del componente DomCrawler di Sf2, permette di manipolare
documenti XML e HTML attraverso xpath e css selector:
http://symfony.com/doc/2.1/components/dom_crawler.html
PHPUnit asserts
ci assicuriamo che ci sia almeno un elemento p nella pagina di risposta:
$this->assertTrue($crawler->filter('p')->count() > 0);


verifichiamo che ci sia un oggetto del DOM che abbia la classe css navbar:
$this->assertTrue($crawler->filter('.navbar')->count() > 0);


verifichiamo che la navbar contenga un solo elemento li:
$this->assertEquals(1, $crawler->filter('.navbar > li')->count());


infine verifichiamo che il primo elemento li di navbar contenga il testo home
$this->assertRegExp("/home/i", $crawler->filter('.navbar > li:nth-
child(1)')->text());
DefaultControllerTest.php

DefaultControllerTest.php

src/PUGX/BookBundle/Tests/Controller/
     DefaultControllerTest.php



phpunit -c app/
DefaultControllerTest.php

DefaultControllerTest.php

TEST ROSSI
There was 1 error:



1) PUGXBookBundleTestsControllerDefaultControllerTest::testIndex
InvalidArgumentException: The current node list is empty.


/home/eux/Documents/www/symfony2/pugx_book/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Cra
wler.php:468
/home/eux/Documents/www/symfony2/pugx_book/src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php:
16



FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
make it GREEN
//src/PUGX/BookBundle/Resources/views/Default/index.html.twig
<!DOCTYPE html>
<html>
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>PUGX Book</title>
 </head>
 <body>
   <div id="sidebar">
      <ul class="navbar">
         <li><a href="/">Home</a></li>
      </ul>
   </div>
   <div id="content">
      <h1>Welcome on PUGX Book</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ultrices, nisi quis porta
fermentum, magna ligula suscipit metus, quis blandit leo urna non diam. Sed non dui dui, quis porttitor
massa. Phasellus convallis porta leo, sed vehicula eros ultrices sit amet.</p>
   </div>
  </body>
</html>
DefaultControllerTest.php

DefaultControllerTest.php

src/PUGX/BookBundle/Tests/Controller/
     DefaultControllerTest.php



phpunit -c app/
DefaultControllerTest.php

DefaultControllerTest.php

TEST VERDI
PHPUnit 3.6.11 by Sebastian Bergmann.
Configuration read from /home/giorgio/Progetti/codemotion/pugx_book/app/phpunit.xml.dist


.


Time: 11 seconds, Memory: 17.50Mb


OK (1 test, 6 assertions)
tag cap3


git stash

git checkout cap3
DefaultControllerTest.php

un elenco di libri


Vogliamo aggiungere una pagina che contiene
una lista di libri, ognuno con informazioni
relative all'autore e alla data di pubblicazione.
DefaultControllerTest.php

Il test


Scriviamo innanzi tutto il test testBooks() in
src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.
php
DefaultControllerTest.php

l'entità Book


La struttura dati che rappresenta il nostro libro
è l'entità Book, definita in:
src/PUGX/BookBundle/Entity/Book.php
DefaultControllerTest.php

la nuova rotta


Aggiungiamo una nuova rotta che risponderà
all'url /books
DefaultControllerTest.php

la nuova action


Aggiungiamo un metodo booksAction al
DefaultController in cui ci limiteremo a creare
tre instanze di Book, passandole al twig
DefaultControllerTest.php

il nuovo template


Creiamo un nuovo twig in
src/PUGX/BookBundle/Resources/views/Default/books.html.twig
e stampiamo la lista di libri in una tabella

Ereditarietà dei template
tag cap4


git checkout cap4
Doctrine - ORM
     Object Relational Mapping




        class Book
        {
          public $title;
          public $author;
          public $publicationDate
        }
Doctrine DBAL
                Application

              Doctrine DBAL

                  PDO




 PostgreSQL       MySQL       SQLite
Book entity
/**
 * @ORMEntity
 * @ORMTable(name="book")
 */
class Book
{ [...] }


src/PUGX/BookBundle/Entity/Book.php

http://symfony.com/it/doc/2.1/book/doctrine.html#book-doctrine-field-types
parameters.yml
/app/config/parameters.yml

database_driver:  pdo_mysql
database_host:   127.0.0.1
database_port:    ~
database_name:    pugx_book
database_user:     root
database_password: ~
Doctrine commands
php app/console doctrine:database:create

php app/console doctrine:database:drop --force

php app/console doctrine:schema:create
Doctrine migrations
directory:
/app/DoctrineMigrations

table:
migration_versions

php app/console doctrine:migrations:diff
php app/console doctrine:migrations:migrate
php app/console doctrine:migrations:execute --up NNN
php app/console doctrine:migrations:execute --down NNN
Doctrine fixtures
src/PUGX/BookBundle/DataFixtures/ORM/LoadBookData.php


php app/console doctrine:fixtures:load
DefaultControllerTest.php
/src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php

Controlliamo che i libri siano in ordine alfabetico
Query con doctrine
/src/PUGX/BookBundle/Controller/DefaultController.php

public function booksAction()
{
  $em = $this->getDoctrine()->getManager();
  $books = $em->getRepository('PUGXBookBundle:Book')->findBy(
      array(),
      array('title' => 'ASC')
  );
  return $this->render('PUGXBookBundle:Default:books.html.twig',
     array('books' => $books)
  );
}
DefaultControllerTest.php
/src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php

Aggiungiamo il test per una pagina di dettaglio (o 404)
rotta - action - template
/src/PUGX/BookBundle/Resources/config/routing.yml

/src/PUGX/BookBundle/Controller/DefaultController.php

/src/PUGX/BookBundle/Resources/views/Default/bookDeta
il.html.twig
tag cap5


git checkout cap5
doctrine - approfondimenti
Author è un campo testuale
Un autore è associato a più libri
Spostiamo l'autore in una entità separata.


php app/console doctrine:generate:entity --
entity="PUGXBookBundle:Author" --fields="name:
string(255) surname:string(255) bio:text"
Author entity
/**
 * @ORMEntity
 * @ORMTable(name="author")
 */
class Author
{ [...] }


src/PUGX/BookBundle/Entity/Author.php

http://symfony.com/it/doc/2.1/book/doctrine.html#book-doctrine-field-types
doctrine - associazioni

Per definire l'associazione tra Book e Author
utilizziamo le annotazioni di Doctrine
OneToMany(lato Author) e ManyToOne(lato
Book)
doctrine - associazioni
in src/PUGX/BookBundle/Entity/Author.php
/**
* @ORMOneToMany(targetEntity="PUGXBookBundleEntityBook",
mappedBy="author")
*/
private $books;


aggiungendo i metodi addBook, getBooks,
setBooks e removeBook
doctrine - associazioni
in src/PUGX/BookBundle/Entity/Book.php
/**
* @ORMManyToOne(targetEntity="PUGXBookBundleEntityAuthor",
inversedBy="books")
**/
protected $author;


aggiungendo i metodi setAuthor e getAuthor
doctrine - associazioni
Osservazione

Doctrine nasconde la logica dell'associazione a
livello database, in cui l'associazione è definita
da un campo author_id della tabella book e una
foreign key.
La parte inversa dell'associazione è ricostruita
automaticamente da Doctrine.
doctrine - migrazione
Per poter allineare il database ai cambiamenti, è
necessario generare e applicare una nuova migrazione:

php app/console doctrine:migrations:diff
php app/console doctrine:migrations:migrate
doctrine - fixtures
/src/PUGX/BookBundle/DataFixtures/ORM/LoadAuthorData.php

elemento
$this->addReference('author-beck', $author);

riferimento
$this->getReference('author-beck')


public function getOrder() {
  return 1;
}
template
/src/PUGX/BookBundle/Resources/views/Default/books.html.twig

/src/PUGX/BookBundle/Resources/views/Default/bookDetail.html.twig


{{ book.author.name }} {{ book.author.surname }}
problema!!!
causa
profiler
$nbQuery =
 $client->getProfile()->getCollector('db')-
>getQueryCount();

$this->assertEquals(1, $nbQuery);
custom repository
/**
 *
 * @ORMEntity(repositoryClass="PUGXBookBundleRepositoryBookRepository")
 * @ORMTable(name="book")
 */
class Book


/src/PUGX/BookBundle/Repository/BookRepository.php

/src/PUGX/BookBundle/Tests/Repository/BookRepositoryTest.php

/src/PUGX/BookBundle/Controller/DefaultController.php
$books = $em->getRepository('PUGXBookBundle:Book')-
>findAllWithAuthors();
DQL
public function findAllWithAuthors()
{
  $query = $this->getEntityManager()
          ->createQuery('
             SELECT b, a
            FROM PUGXBookBundle:Book b
            INNER JOIN b.author a
            ORDER BY b.title ASC
  ');

    return $query->getResult();
}
tag cap6


git checkout cap6
DefaultControllerTest

metodo

testCreate
form type


/src/PUGX/BookBundle/Form/Type/BookType.php
routing problem
/src/PUGX/BookBundle/Resources/config/routing.yml

pugx_book_detail:
  pattern: /books/{bookId}
  defaults: { _controller: PUGXBookBundle:Default:bookDetail }



pugx_book_create:
  pattern: /books/create
  defaults: { _controller: PUGXBookBundle:Default:bookCreate }
solution
/src/PUGX/BookBundle/Resources/config/routing.yml

pugx_book_detail:
  pattern: /books/{bookId}
  defaults: { _controller: PUGXBookBundle:Default:bookDetail }
  requirements:
    bookId: d+

pugx_book_create:
  pattern: /books/create
  defaults: { _controller: PUGXBookBundle:Default:bookCreate }
form action
/src/PUGX/BookBundle/Controller/DefaultController.php



public function bookCreateAction(Request $request) {
 ...
}
twig form

/BookBundle/Resources/views/Default/bookCreate.html.
twig
flash messages

$this->get('session')->getFlashBag()->add('notice', 'Book successfully created');


{% for flashMessage in app.session.flashbag.get('notice') %}
 <div class="notice">
  {{ flashMessage }}
 </div>
{% endfor %}
tearDown

Eliminazione del record inserito con il test
tag cap7


git checkout cap7
security
tag extra1


git checkout extra1

More Related Content

What's hot

Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018
Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018
Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018Marco Chiesi
 
Closure Visto Da Vicino
Closure Visto Da VicinoClosure Visto Da Vicino
Closure Visto Da Vicinodavide ficano
 
Async navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 frameworkAsync navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 frameworksparkfabrik
 
Drupal 8 - dal download del core alla pubblicazione in produzione
Drupal 8 - dal download del core alla pubblicazione in produzioneDrupal 8 - dal download del core alla pubblicazione in produzione
Drupal 8 - dal download del core alla pubblicazione in produzionesparkfabrik
 
Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...
Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...
Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...KohaGruppoItaliano
 
Progettazione e sviluppo di applicazioni web 2.0 con PHP e Ajax
Progettazione e sviluppo di applicazioni web 2.0 con PHP e AjaxProgettazione e sviluppo di applicazioni web 2.0 con PHP e Ajax
Progettazione e sviluppo di applicazioni web 2.0 con PHP e AjaxGiovanni Cappellini
 
Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8Luca Lusso
 
Sviluppo web dall'antichità all'avanguardia e ritorno
Sviluppo web  dall'antichità all'avanguardia e ritornoSviluppo web  dall'antichità all'avanguardia e ritorno
Sviluppo web dall'antichità all'avanguardia e ritornolordarthas
 
Introduzione DevOps con Ansible
Introduzione DevOps con AnsibleIntroduzione DevOps con Ansible
Introduzione DevOps con AnsibleMatteo Magni
 

What's hot (20)

TYPO3 CMS 8.1 - Le novità
TYPO3 CMS 8.1 - Le novitàTYPO3 CMS 8.1 - Le novità
TYPO3 CMS 8.1 - Le novità
 
Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018
Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018
Sviluppare un plugin WordPress da zero - WordCamp Bologna 2018
 
Closure Visto Da Vicino
Closure Visto Da VicinoClosure Visto Da Vicino
Closure Visto Da Vicino
 
Async navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 frameworkAsync navigation with a lightweight ES6 framework
Async navigation with a lightweight ES6 framework
 
TYPO3 CMS 7.6 - Le novita
TYPO3 CMS 7.6 - Le novitaTYPO3 CMS 7.6 - Le novita
TYPO3 CMS 7.6 - Le novita
 
Drupal 8 - dal download del core alla pubblicazione in produzione
Drupal 8 - dal download del core alla pubblicazione in produzioneDrupal 8 - dal download del core alla pubblicazione in produzione
Drupal 8 - dal download del core alla pubblicazione in produzione
 
J huery
J hueryJ huery
J huery
 
Perl Template Toolkit
Perl Template ToolkitPerl Template Toolkit
Perl Template Toolkit
 
Battaglia Navale
Battaglia NavaleBattaglia Navale
Battaglia Navale
 
Laravel 7 REST API
Laravel 7 REST APILaravel 7 REST API
Laravel 7 REST API
 
Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...
Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...
Biblioteca Generale della Custodia di Terra Santa a Gerusalemme : Specifiche ...
 
Progettazione e sviluppo di applicazioni web 2.0 con PHP e Ajax
Progettazione e sviluppo di applicazioni web 2.0 con PHP e AjaxProgettazione e sviluppo di applicazioni web 2.0 con PHP e Ajax
Progettazione e sviluppo di applicazioni web 2.0 con PHP e Ajax
 
Java lezione 17
Java lezione 17Java lezione 17
Java lezione 17
 
Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8Come portare il profiler di symfony2 in drupal8
Come portare il profiler di symfony2 in drupal8
 
Sviluppo web dall'antichità all'avanguardia e ritorno
Sviluppo web  dall'antichità all'avanguardia e ritornoSviluppo web  dall'antichità all'avanguardia e ritorno
Sviluppo web dall'antichità all'avanguardia e ritorno
 
Introduzione DevOps con Ansible
Introduzione DevOps con AnsibleIntroduzione DevOps con Ansible
Introduzione DevOps con Ansible
 
local::lib
local::liblocal::lib
local::lib
 
Net core base
Net core baseNet core base
Net core base
 
Java lezione 18
Java lezione 18Java lezione 18
Java lezione 18
 
Php e database: php mysql
Php e database: php mysqlPhp e database: php mysql
Php e database: php mysql
 

Similar to High Performance Web Apps con PHP e Symfony 2

Linux Embedded per l'automazione
Linux Embedded per l'automazioneLinux Embedded per l'automazione
Linux Embedded per l'automazioneDaniele Costarella
 
Gestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerGestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerMassimiliano Arione
 
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...DrupalDay
 
Pacchi e pacchetti
Pacchi e pacchettiPacchi e pacchetti
Pacchi e pacchettigiallu
 
Drupal - per chi vuole iniziare
Drupal - per chi vuole iniziareDrupal - per chi vuole iniziare
Drupal - per chi vuole iniziareSalvatore Paone
 
PostgreSQL: Point in time recovery
PostgreSQL: Point in time recoveryPostgreSQL: Point in time recovery
PostgreSQL: Point in time recoveryEnrico Pirozzi
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacyTommaso Torti
 
Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019
Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019
Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019Marco Chiesi
 
Drupal Day 2015 - Drupal 8 dal download del core alla pubblicazione in prod...
Drupal Day 2015 -  Drupal 8  dal download del core alla pubblicazione in prod...Drupal Day 2015 -  Drupal 8  dal download del core alla pubblicazione in prod...
Drupal Day 2015 - Drupal 8 dal download del core alla pubblicazione in prod...Vincenzo Di Biaggio
 
PostgrSQL 9.3&9.4 - DjangoVillage
PostgrSQL 9.3&9.4 - DjangoVillagePostgrSQL 9.3&9.4 - DjangoVillage
PostgrSQL 9.3&9.4 - DjangoVillageMiriade Spa
 
Apache Maven - Gestione di progetti Java e build automation
Apache Maven - Gestione di progetti Java e build automationApache Maven - Gestione di progetti Java e build automation
Apache Maven - Gestione di progetti Java e build automationTiziano Serritella
 
Giovambattista Fazioli, 10 more things
Giovambattista Fazioli, 10 more thingsGiovambattista Fazioli, 10 more things
Giovambattista Fazioli, 10 more thingsKnowCamp
 
Qt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immaginiQt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immaginiPaolo Sereno
 

Similar to High Performance Web Apps con PHP e Symfony 2 (20)

Codemotion workshop
Codemotion workshopCodemotion workshop
Codemotion workshop
 
introduzione a symfony 2
introduzione a symfony 2 introduzione a symfony 2
introduzione a symfony 2
 
Linux Embedded per l'automazione
Linux Embedded per l'automazioneLinux Embedded per l'automazione
Linux Embedded per l'automazione
 
Gestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerGestione delle dipendenze con Composer
Gestione delle dipendenze con Composer
 
TuxIsAlive
TuxIsAliveTuxIsAlive
TuxIsAlive
 
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
Drupal 8: dal download del Core alla pubblicazione in produzione. Cos'è cambi...
 
Pacchi e pacchetti
Pacchi e pacchettiPacchi e pacchetti
Pacchi e pacchetti
 
Drupal - per chi vuole iniziare
Drupal - per chi vuole iniziareDrupal - per chi vuole iniziare
Drupal - per chi vuole iniziare
 
PostgreSQL: Point in time recovery
PostgreSQL: Point in time recoveryPostgreSQL: Point in time recovery
PostgreSQL: Point in time recovery
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacy
 
TYPO3 CMS 7.1 - Le novita
TYPO3 CMS 7.1 - Le novitaTYPO3 CMS 7.1 - Le novita
TYPO3 CMS 7.1 - Le novita
 
Idp, passo dopo passo!
Idp, passo dopo passo!Idp, passo dopo passo!
Idp, passo dopo passo!
 
Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019
Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019
Grunt: automazione per sviluppatori “pigri” - WordCamp Bari 2019
 
Drupal Day 2015 - Drupal 8 dal download del core alla pubblicazione in prod...
Drupal Day 2015 -  Drupal 8  dal download del core alla pubblicazione in prod...Drupal Day 2015 -  Drupal 8  dal download del core alla pubblicazione in prod...
Drupal Day 2015 - Drupal 8 dal download del core alla pubblicazione in prod...
 
PostgrSQL 9.3&9.4 - DjangoVillage
PostgrSQL 9.3&9.4 - DjangoVillagePostgrSQL 9.3&9.4 - DjangoVillage
PostgrSQL 9.3&9.4 - DjangoVillage
 
XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13XPages Tips & Tricks, #dd13
XPages Tips & Tricks, #dd13
 
App Engine + Python
App Engine + PythonApp Engine + Python
App Engine + Python
 
Apache Maven - Gestione di progetti Java e build automation
Apache Maven - Gestione di progetti Java e build automationApache Maven - Gestione di progetti Java e build automation
Apache Maven - Gestione di progetti Java e build automation
 
Giovambattista Fazioli, 10 more things
Giovambattista Fazioli, 10 more thingsGiovambattista Fazioli, 10 more things
Giovambattista Fazioli, 10 more things
 
Qt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immaginiQt Lezione3: un visualizzatore di immagini
Qt Lezione3: un visualizzatore di immagini
 

More from Giorgio Cefaro

Alexa, AWS lambda & wikidata (ITA)
Alexa, AWS lambda & wikidata (ITA)Alexa, AWS lambda & wikidata (ITA)
Alexa, AWS lambda & wikidata (ITA)Giorgio Cefaro
 
PHP object calisthenics
PHP object calisthenicsPHP object calisthenics
PHP object calisthenicsGiorgio Cefaro
 
Import golang; struct microservice - Codemotion Rome 2015
Import golang; struct microservice - Codemotion Rome 2015Import golang; struct microservice - Codemotion Rome 2015
Import golang; struct microservice - Codemotion Rome 2015Giorgio Cefaro
 
I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014
I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014
I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014Giorgio Cefaro
 
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)Giorgio Cefaro
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridGiorgio Cefaro
 
An introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersAn introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersGiorgio Cefaro
 

More from Giorgio Cefaro (10)

Alexa, AWS lambda & wikidata (ITA)
Alexa, AWS lambda & wikidata (ITA)Alexa, AWS lambda & wikidata (ITA)
Alexa, AWS lambda & wikidata (ITA)
 
PHP object calisthenics
PHP object calisthenicsPHP object calisthenics
PHP object calisthenics
 
Don't fear the rebase
Don't fear the rebaseDon't fear the rebase
Don't fear the rebase
 
jsDay 2016 recap
jsDay 2016 recapjsDay 2016 recap
jsDay 2016 recap
 
Import golang; struct microservice - Codemotion Rome 2015
Import golang; struct microservice - Codemotion Rome 2015Import golang; struct microservice - Codemotion Rome 2015
Import golang; struct microservice - Codemotion Rome 2015
 
I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014
I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014
I came, I saw, I GO! - Golangit meetup @ Codemotion Rome 2014
 
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 
From LAMP to LNNP
From LAMP to LNNPFrom LAMP to LNNP
From LAMP to LNNP
 
An introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersAn introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developers
 

High Performance Web Apps con PHP e Symfony 2