1+ .. index ::
2+ single: Symfony versus Flat PHP
3+
14.. _symfony2-versus-flat-php :
25
36Symfony versus Flat PHP
47=======================
58
69**Why is Symfony better than just opening up a file and writing flat PHP? **
710
8- If you've never used a PHP framework, aren't familiar with the MVC philosophy,
9- or just wonder what all the *hype * is around Symfony, this chapter is for
10- you. Instead of *telling * you that Symfony allows you to develop faster and
11- better software than with flat PHP, you'll see for yourself.
11+ If you've never used a PHP framework, aren't familiar with the
12+ `Model-View-Controller `_ (MVC) philosophy, or just wonder what all the *hype *
13+ is around Symfony, this chapter is for you. Instead of *telling * you that
14+ Symfony allows you to develop faster and better software than with flat PHP,
15+ you'll see for yourself.
1216
1317In this chapter, you'll write a simple application in flat PHP, and then
1418refactor it to be more organized. You'll travel through time, seeing the
@@ -98,11 +102,12 @@ the code that prepares the HTML "presentation"::
98102 require 'templates/list.php';
99103
100104
101- The HTML code is now stored in a separate file ( ``templates/list.php ``) , which
105+ The HTML code is now stored in a separate file ``templates/list.php ``, which
102106is primarily an HTML file that uses a template-like PHP syntax:
103107
104108.. code-block :: html+php
105109
110+ <!-- templates/list.php -->
106111 <!DOCTYPE html>
107112 <html>
108113 <head>
@@ -179,6 +184,7 @@ of the application are isolated in a new file called ``model.php``::
179184
180185The controller (``index.php ``) is now very simple::
181186
187+ // index.php
182188 require_once 'model.php';
183189
184190 $posts = get_all_posts();
@@ -197,7 +203,7 @@ offering various advantages and the opportunity to reuse almost everything
197203on different pages.
198204
199205The only part of the code that *can't * be reused is the page layout. Fix
200- that by creating a new ``layout.php `` file:
206+ that by creating a new ``templates/ layout.php `` file:
201207
202208.. code-block :: html+php
203209
@@ -212,11 +218,12 @@ that by creating a new ``layout.php`` file:
212218 </body>
213219 </html>
214220
215- The template ( ``templates/list.php ``) can now be simplified to "extend"
216- the layout:
221+ The template ``templates/list.php `` can now be simplified to "extend"
222+ the `` templates/ layout.php `` :
217223
218224.. code-block :: html+php
219225
226+ <!-- templates/list.php -->
220227 <?php $title = 'List of Posts' ?>
221228
222229 <?php ob_start() ?>
@@ -237,8 +244,9 @@ the layout:
237244You now have a setup that will allow you to reuse the layout.
238245Unfortunately, to accomplish this, you're forced to use a few ugly
239246PHP functions (``ob_start() ``, ``ob_get_clean() ``) in the template. Symfony
240- uses a Templating component that allows this to be accomplished cleanly
241- and easily. You'll see it in action shortly.
247+ uses a :doc: `Templating </components/templating/introduction >` component
248+ that allows this to be accomplished cleanly and easily. You'll see it in
249+ action shortly.
242250
243251Adding a Blog "show" Page
244252-------------------------
@@ -270,6 +278,7 @@ an individual blog result based on a given id::
270278Next, create a new file called ``show.php `` - the controller for this new
271279page::
272280
281+ // show.php
273282 require_once 'model.php';
274283
275284 $post = get_post_by_id($_GET['id']);
@@ -281,6 +290,7 @@ the individual blog post:
281290
282291.. code-block :: html+php
283292
293+ <!-- templates/show.php -->
284294 <?php $title = $post['title'] ?>
285295
286296 <?php ob_start() ?>
@@ -327,9 +337,9 @@ application change slightly, but start to become more flexible:
327337 /index.php/show => Blog post show page (index.php executed)
328338
329339 .. tip ::
330- The `` index.php `` portion of the URI can be removed if using Apache
331- rewrite rules (or equivalent). In that case, the resulting URI of the
332- blog show page would be simply ``/show ``.
340+
341+ By using rewrite rules in your :doc: ` web server configuration < /cookbook/configuration/web_server_configuration >`,
342+ the `` index.php `` won't be needed and you will have beautiful, clean URLs (e.g. ``/show ``) .
333343
334344When using a front controller, a single PHP file (``index.php `` in this case)
335345renders *every * request. For the blog post show page, ``/index.php/show `` will
@@ -364,8 +374,9 @@ on the requested URI::
364374 }
365375
366376For organization, both controllers (formerly ``index.php `` and ``show.php ``)
367- are now PHP functions and each has been moved into a separate file, ``controllers.php ``::
377+ are now PHP functions and each has been moved into a separate file named ``controllers.php ``::
368378
379+ // controllers.php
369380 function list_action()
370381 {
371382 $posts = get_all_posts();
@@ -382,7 +393,11 @@ As a front controller, ``index.php`` has taken on an entirely new role, one
382393that includes loading the core libraries and routing the application so that
383394one of the two controllers (the ``list_action() `` and ``show_action() ``
384395functions) is called. In reality, the front controller is beginning to look and
385- act a lot like Symfony's mechanism for handling and routing requests.
396+ act a lot like how Symfony handles and routes requests.
397+
398+ But but careful not to confuse the terms *front controller * and *controller *. Your
399+ app will usually have just *one * front controller, which boots your code. You will
400+ have *many * controller functions: one for each page.
386401
387402.. tip ::
388403
@@ -393,8 +408,8 @@ act a lot like Symfony's mechanism for handling and routing requests.
393408
394409By now, the application has evolved from a single PHP file into a structure
395410that is organized and allows for code reuse. You should be happier, but far
396- from satisfied. For example, the " routing" system is fickle, and wouldn't
397- recognize that the list page ( ``/index.php ``) should be accessible also via ``/ ``
411+ from satisfied. For example, the routing system is fickle, and wouldn't
412+ recognize that the list page - ``/index.php `` - should be accessible also via ``/ ``
398413(if Apache rewrite rules were added). Also, instead of developing the blog,
399414a lot of time is being spent working on the "architecture" of the code (e.g.
400415routing, calling controllers, templates, etc.). More time will need to be
@@ -407,7 +422,7 @@ Add a Touch of Symfony
407422~~~~~~~~~~~~~~~~~~~~~~
408423
409424Symfony to the rescue. Before actually using Symfony, you need to download
410- it. This can be done by using Composer, which takes care of downloading the
425+ it. This can be done by using ` Composer `_ , which takes care of downloading the
411426correct version and all its dependencies and provides an autoloader. An
412427autoloader is a tool that makes it possible to start using PHP classes
413428without explicitly including the file containing the class.
@@ -427,7 +442,7 @@ content:
427442 }
428443
429444 Next, `download Composer `_ and then run the following command, which will download Symfony
430- into a vendor/ directory:
445+ into a `` vendor/ `` directory:
431446
432447.. code-block :: bash
433448
@@ -501,7 +516,8 @@ incidentally, acts quite a bit like the Symfony templating engine::
501516
502517By bringing in a small part of Symfony, the application is more flexible and
503518reliable. The ``Request `` provides a dependable way to access information
504- about the HTTP request. Specifically, the ``getPathInfo() `` method returns
519+ about the HTTP request. Specifically, the
520+ :method: `Symfony\\ Component\\ HttpFoundation\\ Request::getPathInfo ` method returns
505521a cleaned URI (always returning ``/show `` and never ``/index.php/show ``).
506522So, even if the user goes to ``/index.php/show ``, the application is intelligent
507523enough to route the request through ``show_action() ``.
@@ -520,8 +536,10 @@ The blog has come a *long* way, but it still contains a lot of code for such
520536a simple application. Along the way, you've made a simple routing
521537system and a method using ``ob_start() `` and ``ob_get_clean() `` to render
522538templates. If, for some reason, you needed to continue building this "framework"
523- from scratch, you could at least use Symfony's standalone `Routing `_ and
524- `Templating `_ components, which already solve these problems.
539+ from scratch, you could at least use Symfony's standalone
540+ :doc: `Routing </components/routing/introduction >` and
541+ :doc: `Templating </components/templating/introduction >` components, which already
542+ solve these problems.
525543
526544Instead of re-solving common problems, you can let Symfony take care of
527545them for you. Here's the same sample application, now built in Symfony::
@@ -559,10 +577,14 @@ them for you. Here's the same sample application, now built in Symfony::
559577 }
560578 }
561579
562- The two controllers are still lightweight. Each uses the
580+ Notice, both controller functions now live inside a "controller class". This is a
581+ nice way to group related pages. The controller functions are also sometimes called
582+ *actions *.
583+
584+ The two controllers (or actions) are still lightweight. Each uses the
563585:doc: `Doctrine ORM library </book/doctrine >` to retrieve objects from the
564586database and the Templating component to render a template and return a
565- ``Response `` object. The list template is now quite a bit simpler:
587+ ``Response `` object. The list `` list.php `` template is now quite a bit simpler:
566588
567589.. code-block :: html+php
568590
@@ -585,7 +607,7 @@ database and the Templating component to render a template and return a
585607 <?php endforeach ?>
586608 </ul>
587609
588- The layout is nearly identical:
610+ The `` layout.php `` file is nearly identical:
589611
590612.. code-block :: html+php
591613
@@ -605,12 +627,13 @@ The layout is nearly identical:
605627
606628.. note ::
607629
608- The show template is left as an exercise, as it should be trivial to
609- create based on the list template.
630+ The show `` show.php `` template is left as an exercise: updating it should be
631+ really similar to updating the `` list.php `` template.
610632
611- When Symfony's engine (called the `` Kernel `` ) boots up, it needs a map so
633+ When Symfony's engine (called the Kernel) boots up, it needs a map so
612634that it knows which controllers to execute based on the request information.
613- A routing configuration map provides this information in a readable format:
635+ A routing configuration map - ``app/config/routing.yml `` - provides this information
636+ in a readable format:
614637
615638.. code-block :: yaml
616639
@@ -624,9 +647,8 @@ A routing configuration map provides this information in a readable format:
624647 defaults : { _controller: AppBundle:Blog:show }
625648
626649 Now that Symfony is handling all the mundane tasks, the front controller
627- is dead simple. And since it does so little, you'll never have to touch
628- it once it's created (and if you use a `Symfony distribution `_, you won't
629- even need to create it!)::
650+ ``web/app.php `` is dead simple. And since it does so little, you'll never
651+ have to touch it::
630652
631653 // web/app.php
632654 require_once __DIR__.'/../app/bootstrap.php';
@@ -637,55 +659,29 @@ even need to create it!)::
637659 $kernel = new AppKernel('prod', false);
638660 $kernel->handle(Request::createFromGlobals())->send();
639661
640- The front controller's only job is to initialize Symfony's engine (``Kernel ``)
641- and pass it a ``Request `` object to handle. Symfony's core then uses the
642- routing map to determine which controller to call. Just like before, the
643- controller method is responsible for returning the final ``Response `` object.
644- There's really not much else to it.
645-
646- For a visual representation of how Symfony handles each request, see the
647- :ref: `request flow diagram <request-flow-figure >`.
648-
649- .. _where-symfony2-delivers :
662+ The front controller's only job is to initialize Symfony's engine (called the
663+ Kernel) and pass it a ``Request `` object to handle. The Symfony core
664+ asks the router to inspect the request. The router matches the incoming URL
665+ to a specific route and returns information about the route, including the
666+ controller that should be executed. The correct controller from the matched
667+ route is executed and your code inside the controller creates and returns the
668+ appropriate ``Response `` object. The HTTP headers and content of the ``Response ``
669+ object are sent back to the client.
650670
651- Where Symfony Delivers
652- ~~~~~~~~~~~~~~~~~~~~~~
653-
654- In the upcoming chapters, you'll learn more about how each piece of Symfony
655- works and the recommended organization of a project. For now, have a look
656- at how migrating the blog from flat PHP to Symfony has improved life:
671+ It's a beautiful thing.
657672
658- * Your application now has **clear and consistently organized code ** (though
659- Symfony doesn't force you into this). This promotes **reusability ** and
660- allows for new developers to be productive in your project more quickly;
661-
662- * 100% of the code you write is for *your * application. You **don't need
663- to develop or maintain low-level utilities ** such as autoloading,
664- :doc: `routing </book/routing >`, or rendering :doc: `controllers </book/controller >`;
665-
666- * Symfony gives you **access to open source tools ** such as Doctrine and the
667- Templating, Security, Form, Validation and Translation components (to name
668- a few);
669-
670- * The application now enjoys **fully-flexible URLs ** thanks to the Routing
671- component;
672-
673- * Symfony's HTTP-centric architecture gives you access to powerful tools
674- such as **HTTP caching ** powered by **Symfony's internal HTTP cache ** or
675- more powerful tools such as `Varnish `_. This is covered in a later chapter
676- all about :doc: `caching </book/http_cache >`.
677-
678- And perhaps best of all, by using Symfony, you now have access to a whole
679- set of **high-quality open source tools developed by the Symfony community **!
680- A good selection of Symfony community tools can be found on `KnpBundles.com `_.
673+ .. figure :: /images/request-flow.png
674+ :align: center
675+ :alt: Symfony request flow
681676
682677Better Templates
683- ----------------
678+ ~~~~~~~~~~~~~~~~
684679
685680If you choose to use it, Symfony comes standard with a templating engine
686681called `Twig `_ that makes templates faster to write and easier to read.
687682It means that the sample application could contain even less code! Take,
688- for example, the list template written in Twig:
683+ for example, rewriting ``list.html.php `` template in Twig would look like
684+ this:
689685
690686.. code-block :: html+twig
691687
@@ -707,7 +703,7 @@ for example, the list template written in Twig:
707703 </ul>
708704 {% endblock %}
709705
710- The corresponding ``layout.html.twig `` template is also easier to write :
706+ And rewriting ``layout.html.php `` template in Twig would look like this :
711707
712708.. code-block :: html+twig
713709
@@ -726,18 +722,52 @@ Twig is well-supported in Symfony. And while PHP templates will always
726722be supported in Symfony, the many advantages of Twig will continue to
727723be discussed. For more information, see the :doc: `templating chapter </book/templating >`.
728724
725+ Where Symfony Delivers
726+ ----------------------
727+
728+ In the upcoming chapters, you'll learn more about how each piece of Symfony
729+ works and how you can organize your project. For now, celebrate at how migrating
730+ the blog from flat PHP to Symfony has improved life:
731+
732+ * Your application now has **clear and consistently organized code ** (though
733+ Symfony doesn't force you into this). This promotes **reusability ** and
734+ allows for new developers to be productive in your project more quickly;
735+
736+ * 100% of the code you write is for *your * application. You **don't need
737+ to develop or maintain low-level utilities ** such as autoloading,
738+ :doc: `routing </book/routing >`, or rendering :doc: `controllers </book/controller >`;
739+
740+ * Symfony gives you **access to open source tools ** such as `Doctrine `_ and the
741+ :doc: `Templating </components/templating/introduction >`,
742+ :doc: `Security </components/security/introduction >`,
743+ :doc: `Form </components/form/introduction >`, `Validator `_ and
744+ :doc: `Translation </components/translation/introduction >` components (to name
745+ a few);
746+
747+ * The application now enjoys **fully-flexible URLs ** thanks to the Routing
748+ component;
749+
750+ * Symfony's HTTP-centric architecture gives you access to powerful tools
751+ such as **HTTP caching ** powered by **Symfony's internal HTTP cache ** or
752+ more powerful tools such as `Varnish `_. This is covered in a later chapter
753+ all about :doc: `caching </book/http_cache >`.
754+
755+ And perhaps best of all, by using Symfony, you now have access to a whole
756+ set of **high-quality open source tools developed by the Symfony community **!
757+ A good selection of Symfony community tools can be found on `KnpBundles.com `_.
758+
729759Learn more from the Cookbook
730760----------------------------
731761
732762* :doc: `/cookbook/templating/PHP `
733763* :doc: `/cookbook/controller/service `
734764
765+ .. _`Model-View-Controller` : https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
735766.. _`Doctrine` : http://www.doctrine-project.org
767+ .. _`SQL injection attack` : https://en.wikipedia.org/wiki/SQL_injection
768+ .. _`Composer` : https://getcomposer.org
736769.. _`download Composer` : https://getcomposer.org/download/
737- .. _`Routing` : https://github.com/symfony/routing
738- .. _`Templating` : https://github.com/symfony/templating
739- .. _`KnpBundles.com` : http://knpbundles.com/
740- .. _`Twig` : http://twig.sensiolabs.org
770+ .. _`Validator` : https://github.com/symfony/validator
741771.. _`Varnish` : https://www.varnish-cache.org/
742- .. _`PHPUnit ` : http://www.phpunit.de
743- .. _`Symfony distribution ` : https ://github.com/symfony/symfony-standard
772+ .. _`KnpBundles.com ` : http://knpbundles.com/
773+ .. _`Twig ` : http ://twig.sensiolabs.org
0 commit comments