complex sites with silex
DESCRIPTION
Everyone knows that Silex is a great microframework for APIs and small sites, but what do you do when you want to build a large site, or your little tiny site has grown up? Silex has many different ways to let you build larger, complex websites that might still be too small for Symfony, but have outgrown the single page app it once was. We’ll look at what Silex offers us, and different ways we can structure our site.TRANSCRIPT
![Page 1: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/1.jpg)
Complex Sites with Silex
Chris Tankersley
ZendCon 2014
![Page 2: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/2.jpg)
2
Who Am I?
● A PHP Developer for 10 Years● Lots of projects no one uses, and a few some do
● https://github.com/dragonmantank
![Page 3: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/3.jpg)
3
What is Silex?
![Page 4: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/4.jpg)
4
Microframework
● Built off of the Symfony2 Components
● Micro Service Container● Provides Routing● Provides Extensions
![Page 5: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/5.jpg)
5
Why to Not Use Silex
● You have to piece things together
● Not great for large projects
![Page 6: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/6.jpg)
6
Why use Silex?
● You can use the libraries you want
● Great for small/medium projects
● Prototypers best friend
![Page 7: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/7.jpg)
7
Sites Change over time
![Page 8: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/8.jpg)
8
Silex Allows Us To Adapt
![Page 9: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/9.jpg)
9
Basic Silex App
![Page 10: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/10.jpg)
10
Set up Silex
composer require “silex/silex”:”~1.2”
![Page 11: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/11.jpg)
11
Sample Silex App
<?phprequire_once __DIR__ . '/../vendor/autoload.php';$app = new Silex\Application();$app->get('/', function() use ($app) { return 'Hello World';});$app->run();
![Page 12: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/12.jpg)
12
Congrats!
![Page 13: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/13.jpg)
13
And you add more pages
<?phprequire_once __DIR__ . '/../vendor/autoload.php';$app = new Silex\Application();$app->get('/', function() use ($app) {/*...*/});$app->get('/about, function() use ($app) {/*...*/});$app->get('/contact', function() use ($app) {/*...*/});$app->get('/services', function() use ($app) {/*...*/});$app->run();
![Page 14: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/14.jpg)
14
Service Providers
![Page 15: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/15.jpg)
15
What do they do?
● Allows code reuse● For both services and controllers
![Page 16: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/16.jpg)
16
Service Providers
● Twig● URL Generator● Session● Validator● Form● HTTP Cache● HTTP Fragments● Security
● Remember Me● Switftmailer● Monolog● Translation● Serializer● Doctrine● Controllers as
Services
![Page 17: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/17.jpg)
17
And you add templating
<?phprequire_once __DIR__ . '/../vendor/autoload.php';$app = new Silex\Application();$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/../views',));$app->get('/', function() use ($app) { return $app['twig']->render('homepage.html.twig');});$app->get('/about, function() use ($app) {/*...*/});$app->get('/contact', function() use ($app) {/*...*/});$app->get('/services', function() use ($app) {/*...*/});$app->run();
![Page 18: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/18.jpg)
18
Adding a Form
● We need to generate the form● We need to accept the form● We need to e-mail the form
![Page 19: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/19.jpg)
19
Now we add a form<?phprequire_once __DIR__ . '/../vendor/autoload.php';use Symfony\Component\HttpFoundation\Request;$app = new Silex\Application();$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/views',));$app->register(new Silex\Provider\FormServiceProvider());$app->register(new Silex\Provider\TranslationServiceProvider());$app->get('/', function() use ($app) {/*...*/});$app->get('/about, function() use ($app) {/*...*/});$app->get('/contact', function(Request $request) use ($app) { $form = $app['form.factory']->createBuilder('form') ->add('name') ->add('email') ->getForm() ; $form->handleRequest($request); if($form->isValid()) { $data = $form->getData(); // Mail it } return $app['twig']->render('contact.html.twig', array('form' => $form->createView()));});$app->get('/services', function() use ($app) {/*..});$app->run();
![Page 20: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/20.jpg)
20
HTTP Method Routing
![Page 21: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/21.jpg)
21
Whoops
![Page 22: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/22.jpg)
22
Allow Both Methods<?phprequire_once __DIR__ . '/../vendor/autoload.php';use Symfony\Component\HttpFoundation\Request;$app = new Silex\Application();$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/views',));$app->register(new Silex\Provider\FormServiceProvider());$app->register(new Silex\Provider\TranslationServiceProvider());$app->get('/', function() use ($app) {/*...*/});$app->get('/about, function() use ($app) {/*...*/});$app->match('/contact', function(Request $request) use ($app) { $form = $app['form.factory']->createBuilder('form') ->add('name') ->add('email') ->getForm() ; $form->handleRequest($request); if($form->isValid()) { $data = $form->getData(); // Mail it } return $app['twig']->render('contact.html.twig', array('form' => $form->createView()));})->method('GET|POST');$app->get('/services', function() use ($app) {/*..});$app->run();
![Page 23: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/23.jpg)
23
We've silently introduced a problem into our code
![Page 24: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/24.jpg)
24
Code Quickly Turns to Spaghetti
http://commons.wikimedia.org/wiki/File:Spaghetti-prepared.jpg
![Page 25: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/25.jpg)
25
Pretend to be a big framework
![Page 26: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/26.jpg)
26
What do we need to do?
● Consistent File Layout● Separate out functionality● Make things more testable
![Page 27: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/27.jpg)
27
Clean up our file structure
![Page 28: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/28.jpg)
28
Break up that big file
● File for bootstrapping the app● File for routes● File for running the app
![Page 29: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/29.jpg)
29
web/index.php
require_once __DIR__ . '/../vendor/autoload.php';
$app = new Silex\Application();
require_once __DIR__ . '/../app/bootstrap.php';require_once __DIR__ . '/../app/routes.php';
$app->run();
![Page 30: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/30.jpg)
30
app/bootstrap.php
$config = include_once 'config/config.php';$app['config'] = $config;
$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => $app['config']['template_path'],));
$app->register(new Silex\Provider\FormServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider());
![Page 31: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/31.jpg)
31
app/routes.php
$app->get('/', function() use ($app) {/*...*/});$app->get('/about, function() use ($app) {/*...*/});$app->match('/contact', function(Request $request) use ($app) { $form = $app['form.factory']->createBuilder('form') ->add('name') ->add('email') ->getForm() ; $form->handleRequest($request); if($form->isValid()) { $data = $form->getData(); // Mail it } return $app['twig']->render('contact.html.twig', array('form' => $form->createView()));})->method('GET|POST');$app->get('/services', function() use ($app) {/*..});
![Page 32: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/32.jpg)
32
Service Providers
![Page 33: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/33.jpg)
33
For Services
● Implement Silex\ServiceProviderInterface
● Implement boot() and register()
![Page 34: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/34.jpg)
34
For Controllers
● Implement Silex\ControllerProviderInterface
● Implement connect()
![Page 35: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/35.jpg)
35
Sample Controller
use Silex\Application;use Silex\ControllerProviderInterface;
class BlogController implements ControllerProviderInterface { public function connect(Application $app) { $controllers = $app['controllers_factory']; $controllers->get('/', array($this, 'index')); $controllers->get('/inline', function() use ($app) { /* Logic Here */ }); }
protected function index(Application $app) { /* Logic Here */ }}
$app->mount('/blog', new BlogController());
![Page 36: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/36.jpg)
36
Controllers as Services
● Ships with Silex● Allows attaching objects to routes
● Favors dependency injection● Framework Agnostic
![Page 37: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/37.jpg)
37
Create our Object// src/MyApp/Controller/IndexController.phpnamespace MyApp\Controller;
use Silex\Application;use Symfony\Component\HttpFoundation\Request;
class IndexController{ public function indexAction(Application $app) { return $app['twig']->render('Index/index.html.twig'); }
public function aboutAction(Application $app) { /* … */ }
public function servicesAction(Application $app) { /* … */ }
public function contactAction(Application $app) { /* … */ }}
![Page 38: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/38.jpg)
38
Register Controllers as Services
$config = include_once 'config/config.php';$app['config'] = $config;
$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => $app['config']['template_path'],));
$app->register(new Silex\Provider\FormServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider());
$app['controller.index'] = $app->share(function() use ($app) {return new MyApp\Controller\IndexController();
});
![Page 39: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/39.jpg)
39
Register our routes
$app->get('/', 'controller.index:indexAction')->bind('homepage');$app->get('/about', 'controller.index:aboutAction')->bind('about');$app->get('/services', 'controller.index:servicesAction')->bind('services');$app->match('/contact', 'controller.index:contactAction')->bind('contact')->method('GET|POST');
![Page 40: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/40.jpg)
40
A Little Planning goes a Long Way
![Page 41: Complex Sites with Silex](https://reader034.vdocuments.us/reader034/viewer/2022052619/5564b0a5d8b42a98268b4e69/html5/thumbnails/41.jpg)
41
Questions?