Your SlideShare is downloading. ×
0
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
High Performance Web Apps con PHP  e Symfony 2
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

High Performance Web Apps con PHP e Symfony 2

2,236

Published on

Slides del workshop tenuto da Giorgio Cefaro e Eugenio Pombi al Codemotion 2013

Slides del workshop tenuto da Giorgio Cefaro e Eugenio Pombi al Codemotion 2013

Published in: Technology
3 Comments
2 Likes
Statistics
Notes
No Downloads
Views
Total Views
2,236
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
11
Comments
3
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. High Performance WebApps con PHPe Symfony 2di Giorgio Cefaro ed Eugenio Pombi
  • 2. Giorgio Cefaro@giorrrgiogiorgiocefaro.com
  • 3. Eugenio Pombi@euxpomnerd2business.net
  • 4. Symfony 2First, Symfony2 is a reusable set of standalone,decoupled, and cohesive PHP components that solvecommon web development problems. Then, based onthese components, Symfony2 is also a full-stack webframework. Fabien Potencier
  • 5. Request > Response
  • 6. http://symfony.com/download
  • 7. get the git repogit clone git@bitbucket.org:eux/pugx_book.gitgit tag -lgit checkout {nomeTag}git stash nerd2business.net
  • 8. http://pugx-book.localhost/config.php
  • 9. tag cap1git checkout cap1
  • 10. parameters-dist.ymlparameters: 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
  • 11. composercurl -s https://getcomposer.org/installer | phpcomposer.jsoncomposer.lock./composer.phar update./composer.phar installminimum-stability
  • 12. 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
  • 13. /etc/hosts127.0.0.1 pugx-book.localhost
  • 14. struttura
  • 15. bundle
  • 16. tag cap2git checkout cap2
  • 17. il nostro bundle php app/console generate:bundle --namespace=PUGX/BookBundle --format=ymlBundle 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
  • 18. DefaultControllerTest.phpDefaultControllerTest.phpsrc/PUGX/BookBundle/Tests/Controller/ DefaultControllerTest.phpphpunit -c app/
  • 19. 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
  • 20. routing/app/config/routing.ymlpugx_book: resource: "@PUGXBookBundle/Resources/config/routing.yml" prefix: //src/PUGX/BookBundle/Resources/config/routing.ymlpugx_book_homepage: pattern: / defaults: { _controller: PUGXBookBundle:Default:index }
  • 21. controllerIn genere costituito da una classe che raggruppa una seriedi azioni definite attraverso metodi pubblici.Il nostro primo controller:src/PUGX/BookBundle/Controller/DefaultController.php
  • 22. twigreturn $this->render(PUGXBookBundle:Default:index.html.twig);PUGXBookBundle: <NomeVendor><NomeBundle>Default: <NomeController>index.html.twig: <NomeTemplate>//src/PUGX/BookBundle/Resources/views/Default/index.html.twigHello world!http://symfony.com/it/doc/2.1/book/templating.html
  • 23. 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());
  • 24. PHPUnit assertsverifichiamo 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 è unistanza del componente DomCrawler di Sf2, permette di manipolaredocumenti XML e HTML attraverso xpath e css selector:http://symfony.com/doc/2.1/components/dom_crawler.html
  • 25. PHPUnit assertsci 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());
  • 26. DefaultControllerTest.phpDefaultControllerTest.phpsrc/PUGX/BookBundle/Tests/Controller/ DefaultControllerTest.phpphpunit -c app/
  • 27. DefaultControllerTest.phpDefaultControllerTest.phpTEST ROSSIThere was 1 error:1) PUGXBookBundleTestsControllerDefaultControllerTest::testIndexInvalidArgumentException: The current node list is empty./home/eux/Documents/www/symfony2/pugx_book/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php:468/home/eux/Documents/www/symfony2/pugx_book/src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php:16FAILURES!Tests: 1, Assertions: 1, Failures: 1.
  • 28. 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 portafermentum, magna ligula suscipit metus, quis blandit leo urna non diam. Sed non dui dui, quis porttitormassa. Phasellus convallis porta leo, sed vehicula eros ultrices sit amet.</p> </div> </body></html>
  • 29. DefaultControllerTest.phpDefaultControllerTest.phpsrc/PUGX/BookBundle/Tests/Controller/ DefaultControllerTest.phpphpunit -c app/
  • 30. DefaultControllerTest.phpDefaultControllerTest.phpTEST VERDIPHPUnit 3.6.11 by Sebastian Bergmann.Configuration read from /home/giorgio/Progetti/codemotion/pugx_book/app/phpunit.xml.dist.Time: 11 seconds, Memory: 17.50MbOK (1 test, 6 assertions)
  • 31. tag cap3git stashgit checkout cap3
  • 32. DefaultControllerTest.phpun elenco di libriVogliamo aggiungere una pagina che contieneuna lista di libri, ognuno con informazionirelative allautore e alla data di pubblicazione.
  • 33. DefaultControllerTest.phpIl testScriviamo innanzi tutto il test testBooks() insrc/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php
  • 34. DefaultControllerTest.phplentità BookLa struttura dati che rappresenta il nostro libroè lentità Book, definita in:src/PUGX/BookBundle/Entity/Book.php
  • 35. DefaultControllerTest.phpla nuova rottaAggiungiamo una nuova rotta che risponderàallurl /books
  • 36. DefaultControllerTest.phpla nuova actionAggiungiamo un metodo booksAction alDefaultController in cui ci limiteremo a crearetre instanze di Book, passandole al twig
  • 37. DefaultControllerTest.phpil nuovo templateCreiamo un nuovo twig insrc/PUGX/BookBundle/Resources/views/Default/books.html.twige stampiamo la lista di libri in una tabellaEreditarietà dei template
  • 38. tag cap4git checkout cap4
  • 39. Doctrine - ORM Object Relational Mapping class Book { public $title; public $author; public $publicationDate }
  • 40. Doctrine DBAL Application Doctrine DBAL PDO PostgreSQL MySQL SQLite
  • 41. Book entity/** * @ORMEntity * @ORMTable(name="book") */class Book{ [...] }src/PUGX/BookBundle/Entity/Book.phphttp://symfony.com/it/doc/2.1/book/doctrine.html#book-doctrine-field-types
  • 42. parameters.yml/app/config/parameters.ymldatabase_driver: pdo_mysqldatabase_host: 127.0.0.1database_port: ~database_name: pugx_bookdatabase_user: rootdatabase_password: ~
  • 43. Doctrine commandsphp app/console doctrine:database:createphp app/console doctrine:database:drop --forcephp app/console doctrine:schema:create
  • 44. Doctrine migrationsdirectory:/app/DoctrineMigrationstable:migration_versionsphp app/console doctrine:migrations:diffphp app/console doctrine:migrations:migratephp app/console doctrine:migrations:execute --up NNNphp app/console doctrine:migrations:execute --down NNN
  • 45. Doctrine fixturessrc/PUGX/BookBundle/DataFixtures/ORM/LoadBookData.phpphp app/console doctrine:fixtures:load
  • 46. DefaultControllerTest.php/src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.phpControlliamo che i libri siano in ordine alfabetico
  • 47. Query con doctrine/src/PUGX/BookBundle/Controller/DefaultController.phppublic 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) );}
  • 48. DefaultControllerTest.php/src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.phpAggiungiamo il test per una pagina di dettaglio (o 404)
  • 49. rotta - action - template/src/PUGX/BookBundle/Resources/config/routing.yml/src/PUGX/BookBundle/Controller/DefaultController.php/src/PUGX/BookBundle/Resources/views/Default/bookDetail.html.twig
  • 50. tag cap5git checkout cap5
  • 51. doctrine - approfondimentiAuthor è un campo testualeUn autore è associato a più libriSpostiamo lautore in una entità separata.php app/console doctrine:generate:entity --entity="PUGXBookBundle:Author" --fields="name:string(255) surname:string(255) bio:text"
  • 52. Author entity/** * @ORMEntity * @ORMTable(name="author") */class Author{ [...] }src/PUGX/BookBundle/Entity/Author.phphttp://symfony.com/it/doc/2.1/book/doctrine.html#book-doctrine-field-types
  • 53. doctrine - associazioniPer definire lassociazione tra Book e Authorutilizziamo le annotazioni di DoctrineOneToMany(lato Author) e ManyToOne(latoBook)
  • 54. doctrine - associazioniin src/PUGX/BookBundle/Entity/Author.php/*** @ORMOneToMany(targetEntity="PUGXBookBundleEntityBook",mappedBy="author")*/private $books;aggiungendo i metodi addBook, getBooks,setBooks e removeBook
  • 55. doctrine - associazioniin src/PUGX/BookBundle/Entity/Book.php/*** @ORMManyToOne(targetEntity="PUGXBookBundleEntityAuthor",inversedBy="books")**/protected $author;aggiungendo i metodi setAuthor e getAuthor
  • 56. doctrine - associazioniOsservazioneDoctrine nasconde la logica dellassociazione alivello database, in cui lassociazione è definitada un campo author_id della tabella book e unaforeign key.La parte inversa dellassociazione è ricostruitaautomaticamente da Doctrine.
  • 57. doctrine - migrazionePer poter allineare il database ai cambiamenti, ènecessario generare e applicare una nuova migrazione:php app/console doctrine:migrations:diffphp app/console doctrine:migrations:migrate
  • 58. doctrine - fixtures/src/PUGX/BookBundle/DataFixtures/ORM/LoadAuthorData.phpelemento$this->addReference(author-beck, $author);riferimento$this->getReference(author-beck)public function getOrder() { return 1;}
  • 59. 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 }}
  • 60. problema!!!
  • 61. causa
  • 62. profiler$nbQuery = $client->getProfile()->getCollector(db)->getQueryCount();$this->assertEquals(1, $nbQuery);
  • 63. 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();
  • 64. DQLpublic 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();}
  • 65. tag cap6git checkout cap6
  • 66. DefaultControllerTestmetodotestCreate
  • 67. form type/src/PUGX/BookBundle/Form/Type/BookType.php
  • 68. routing problem/src/PUGX/BookBundle/Resources/config/routing.ymlpugx_book_detail: pattern: /books/{bookId} defaults: { _controller: PUGXBookBundle:Default:bookDetail }pugx_book_create: pattern: /books/create defaults: { _controller: PUGXBookBundle:Default:bookCreate }
  • 69. solution/src/PUGX/BookBundle/Resources/config/routing.ymlpugx_book_detail: pattern: /books/{bookId} defaults: { _controller: PUGXBookBundle:Default:bookDetail } requirements: bookId: d+pugx_book_create: pattern: /books/create defaults: { _controller: PUGXBookBundle:Default:bookCreate }
  • 70. form action/src/PUGX/BookBundle/Controller/DefaultController.phppublic function bookCreateAction(Request $request) { ...}
  • 71. twig form/BookBundle/Resources/views/Default/bookCreate.html.twig
  • 72. 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 %}
  • 73. tearDownEliminazione del record inserito con il test
  • 74. tag cap7git checkout cap7
  • 75. security
  • 76. tag extra1git checkout extra1

×