silex - the symfony2 microframework

58
μ Wednesday, March 2, 2011

Upload: igor-wiedler

Post on 10-May-2015

22.010 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Silex - The Symfony2 Microframework

μWednesday, March 2, 2011

Page 2: Silex - The Symfony2 Microframework

• phpBB developer

• GH: igorw

• Twitter: @igorwesome

Who?

Wednesday, March 2, 2011

Page 3: Silex - The Symfony2 Microframework

Microframeworks

Wednesday, March 2, 2011

Page 4: Silex - The Symfony2 Microframework

What?

• Bare bones

• Routes mapped to actions

• The ‘C’ of ‘MVC’

• REST

• Single file app

Wednesday, March 2, 2011

Page 5: Silex - The Symfony2 Microframework

Why?

• Frameworks are:

• heavy

• verbose

• complex

Wednesday, March 2, 2011

Page 6: Silex - The Symfony2 Microframework

Sometimes a full-stack framework istoo much for a simple task.

Wednesday, March 2, 2011

Page 7: Silex - The Symfony2 Microframework

Wednesday, March 2, 2011

Page 8: Silex - The Symfony2 Microframework

require 'sinatra'

get '/' do 'Hello world!'end

Wednesday, March 2, 2011

Page 10: Silex - The Symfony2 Microframework

Silex

Wednesday, March 2, 2011

Page 11: Silex - The Symfony2 Microframework

Silex(by fabpot)

Wednesday, March 2, 2011

Page 12: Silex - The Symfony2 Microframework

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

$app->get('/', function() { return "Hello world!";});

Wednesday, March 2, 2011

Page 13: Silex - The Symfony2 Microframework

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

$app->get('/', function() { return "Hello world!";});

Phar

Wednesday, March 2, 2011

Page 14: Silex - The Symfony2 Microframework

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

$app->get('/', function() { return "Hello world!";});

Instance

Wednesday, March 2, 2011

Page 15: Silex - The Symfony2 Microframework

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

$app->get('/', function() { return "Hello world!";});

Closure

Wednesday, March 2, 2011

Page 16: Silex - The Symfony2 Microframework

$app->run();

Wednesday, March 2, 2011

Page 17: Silex - The Symfony2 Microframework

<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /some/path RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L]</IfModule>

Wednesday, March 2, 2011

Page 18: Silex - The Symfony2 Microframework

Dynamic Routing

Wednesday, March 2, 2011

Page 19: Silex - The Symfony2 Microframework

$app->get('/hello/{name}', function($name) {

return "Hello $name!";});

Wednesday, March 2, 2011

Page 20: Silex - The Symfony2 Microframework

Before & After

Wednesday, March 2, 2011

Page 21: Silex - The Symfony2 Microframework

$app->before(function() use ($conn) { $conn = new PDO('mysql:dbname=myapp');});

$app->get('/', function() use ($conn) { $usernames = array(); $sql = 'SELECT * FROM user ORDER BY email'; foreach ($conn->query($sql) as $row) { $usernames[] = $row['username']; } return implode('<br />', $usernames);});

$app->after(function() use ($conn) { $conn = null;});

Wednesday, March 2, 2011

Page 22: Silex - The Symfony2 Microframework

$app->before(function() use ($conn) { $conn = new PDO('mysql:dbname=myapp');});

$app->get('/', function() use ($conn) { $usernames = array(); $sql = 'SELECT * FROM user ORDER BY email'; foreach ($conn->query($sql) as $row) { $usernames[] = $row['username']; } return implode('<br />', $usernames);});

$app->after(function() use ($conn) { $conn = null;});

Wednesday, March 2, 2011

Page 23: Silex - The Symfony2 Microframework

$app->before(function() use ($conn) { $conn = new PDO('mysql:dbname=myapp');});

$app->get('/', function() use ($conn) { $usernames = array(); $sql = 'SELECT * FROM user ORDER BY email'; foreach ($conn->query($sql) as $row) { $usernames[] = $row['username']; } return implode('<br />', $usernames);});

$app->after(function() use ($conn) { $conn = null;});

Wednesday, March 2, 2011

Page 24: Silex - The Symfony2 Microframework

$app->before(function() use ($conn) { $conn = new PDO('mysql:dbname=myapp');});

$app->get('/', function() use ($conn) { $usernames = array(); $sql = 'SELECT * FROM user ORDER BY email'; foreach ($conn->query($sql) as $row) { $usernames[] = $row['username']; } return implode('<br />', $usernames);});

$app->after(function() use ($conn) { $conn = null;});

Wednesday, March 2, 2011

Page 25: Silex - The Symfony2 Microframework

REST

Wednesday, March 2, 2011

Page 26: Silex - The Symfony2 Microframework

use Symfony\Component\HttpFoundation\Response;

$app->post('/blog/post/{id}', function($id) use ($app) { $request = $app->getRequest(); $id = (int) $id; $filename = __DIR__."/data/$id.json"; if (file_exists($filename)) { return new Response('', 409); } file_put_contents($filename, json_encode(array( 'id' => $id, 'title' => $request->get('title'), 'body' => $request->get('body'), ))); return new Response('', 201);});

Wednesday, March 2, 2011

Page 27: Silex - The Symfony2 Microframework

$app->delete('/blog/post/{id}', function($id) { $id = (int) $id; $filename = __DIR__."/data/$id.json"; if (!file_exists($filename)) { return new Response('', 404); } unlink($filename); return new Response('', 200);});

Wednesday, March 2, 2011

Page 28: Silex - The Symfony2 Microframework

Errors(Exceptions)

Wednesday, March 2, 2011

Page 29: Silex - The Symfony2 Microframework

use Monolog\Logger;use Monolog\Handler\FileHandler;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

$log = new Logger('myapp');$log->pushHandler(new FileHandler(__DIR__.'log/error.log', Logger::ERROR));

$app->error(function(Exception $e) use ($log) { if ($e instanceof NotFoundHttpException) { return new Response( 'What you are looking for does not exist.', 404); }

$log->addError(json_encode(array( 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'trace' => $e->getTrace(), )));

return new Response('Something very bad happened.', 500);});

Wednesday, March 2, 2011

Page 30: Silex - The Symfony2 Microframework

use Monolog\Logger;use Monolog\Handler\FileHandler;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

$log = new Logger('myapp');$log->pushHandler(new FileHandler(__DIR__.'log/error.log', Logger::ERROR));

$app->error(function(Exception $e) use ($log) { if ($e instanceof NotFoundHttpException) { return new Response( 'What you are looking for does not exist.', 404); }

$log->addError(json_encode(array( 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'trace' => $e->getTrace(), )));

return new Response('Something very bad happened.', 500);});

Wednesday, March 2, 2011

Page 31: Silex - The Symfony2 Microframework

use Monolog\Logger;use Monolog\Handler\FileHandler;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

$log = new Logger('myapp');$log->pushHandler(new FileHandler(__DIR__.'log/error.log', Logger::ERROR));

$app->error(function(Exception $e) use ($log) { if ($e instanceof NotFoundHttpException) { return new Response( 'What you are looking for does not exist.', 404); }

$log->addError(json_encode(array( 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'trace' => $e->getTrace(), )));

return new Response('Something very bad happened.', 500);});

Wednesday, March 2, 2011

Page 32: Silex - The Symfony2 Microframework

use Monolog\Logger;use Monolog\Handler\FileHandler;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

$log = new Logger('myapp');$log->pushHandler(new FileHandler(__DIR__.'log/error.log', Logger::ERROR));

$app->error(function(Exception $e) use ($log) { if ($e instanceof NotFoundHttpException) { return new Response( 'What you are looking for does not exist.', 404); }

$log->addError(json_encode(array( 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'trace' => $e->getTrace(), )));

return new Response('Something very bad happened.', 500);});

Wednesday, March 2, 2011

Page 33: Silex - The Symfony2 Microframework

use Monolog\Logger;use Monolog\Handler\FileHandler;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

$log = new Logger('myapp');$log->pushHandler(new FileHandler(__DIR__.'log/error.log', Logger::ERROR));

$app->error(function(Exception $e) use ($log) { if ($e instanceof NotFoundHttpException) { return new Response( 'What you are looking for does not exist.', 404); }

$log->addError(json_encode(array( 'class' => get_class($e), 'message' => $e->getMessage(), 'code' => $e->getCode(), 'trace' => $e->getTrace(), )));

return new Response('Something very bad happened.', 500);});

Wednesday, March 2, 2011

Page 34: Silex - The Symfony2 Microframework

How?

• Symfony2

• Extends HttpKernel

• Event Dispatcher

• Routing

• Request & Response

Wednesday, March 2, 2011

Page 35: Silex - The Symfony2 Microframework

Experimental Fork

• String return value

• Syntactic sugar for routes

• Before & after hooks

• Error handling

• Integration tests

Wednesday, March 2, 2011

Page 36: Silex - The Symfony2 Microframework

MicroKernelBundle

• Bulat Shakirzyanow (avalanche123)

• More routing flexibility

• Uses instance of Kernel

• Integrates with Symfony2

Wednesday, March 2, 2011

Page 37: Silex - The Symfony2 Microframework

Recipes

Wednesday, March 2, 2011

Page 38: Silex - The Symfony2 Microframework

#1 File structure

• app.php

• bootstrap.php

• index.php

Wednesday, March 2, 2011

Page 39: Silex - The Symfony2 Microframework

app.php

require __DIR__.'/bootstrap.php';

use Silex\Framework;

$app = new Framework();

/* routes */

return $app;

Wednesday, March 2, 2011

Page 40: Silex - The Symfony2 Microframework

bootstrap.php

require_once __DIR__.'/silex.phar';

// custom setup...

Wednesday, March 2, 2011

Page 41: Silex - The Symfony2 Microframework

index.php

$app = require __DIR__.'/app.php';$app->run();

Wednesday, March 2, 2011

Page 42: Silex - The Symfony2 Microframework

#2 Service Container

Wednesday, March 2, 2011

Page 43: Silex - The Symfony2 Microframework

bootstrap.php

use ...\DependencyInjection\ContainerBuilder;use ...\DependencyInjection\Loader\YamlFileLoader;use ...\Config\FileLocator;

$container = new ContainerBuilder();

$env = getenv('APP_ENV') ?: 'dev';

$loader = new YamlFileLoader($container,new FileLocator(__DIR__));

$loader->load("config.$env.yml");

Wednesday, March 2, 2011

Page 44: Silex - The Symfony2 Microframework

config.dev.yml

services: silex: @silex.framework silex.framework: class: Silex\Framework

Wednesday, March 2, 2011

Page 45: Silex - The Symfony2 Microframework

app.php

$app = $container->get('silex');

Wednesday, March 2, 2011

Page 46: Silex - The Symfony2 Microframework

config.dev.ymlparameters: mongo.dbname: myapp

services: mongo.users: class: MongoCollection arguments: [@mongo.db, 'user'] mongo.db: class: MongoDB arguments: [@mongo, %mongo.dbname%] mongo: class: Mongo

Wednesday, March 2, 2011

Page 47: Silex - The Symfony2 Microframework

app.php

$app->get('/user/{id}', function($id) use ($container) { $users = $container->get('mongo.users'); $user = $user->findOne(array("_id" => $id));

return new Response( json_encode($user), 200, array('Content-Type' => 'application/json') );});

Wednesday, March 2, 2011

Page 48: Silex - The Symfony2 Microframework

#3 Twig

Wednesday, March 2, 2011

Page 49: Silex - The Symfony2 Microframework

bootstrap.phpuse Symfony\Component\ClassLoader\UniversalClassLoader;

$loader = new UniversalClassLoader();$loader->registerPrefixes(array( 'Twig_' => __DIR__ . '/vendor/Twig/lib',));$loader->register();

$twigLoader = new Twig_Loader_Filesystem('/views');$twig = new Twig_Environment($twigLoader, array( 'cache' => '/cache/twig', 'debug' => true,));

Wednesday, March 2, 2011

Page 50: Silex - The Symfony2 Microframework

app.php

$app->get('/about', function() use ($twig) { $template =

$twig->loadTemplate('about.html');

return $template->render(array());});

Wednesday, March 2, 2011

Page 51: Silex - The Symfony2 Microframework

Wednesday, March 2, 2011

Page 52: Silex - The Symfony2 Microframework

#4 Testing

Wednesday, March 2, 2011

Page 53: Silex - The Symfony2 Microframework

use Silex\WebTestCase;

require_once __DIR__.'/silex.phar';

class test extends WebTestCase{ public function createApp() { return require __DIR__.'/app.php'; } // tests...}

Wednesday, March 2, 2011

Page 54: Silex - The Symfony2 Microframework

public function testAbout(){ $client = $this->createClient();

$client->request('GET', '/about'); $response = $client->getResponse(); $this->assertTrue($response->isOk()); $this->assertContains('trashbin', $response->getContent()); $this->assertContains('github', $response->getContent()); $this->assertContains('igorw', $response->getContent());}

Wednesday, March 2, 2011

Page 55: Silex - The Symfony2 Microframework

$ phpunit test.php

Wednesday, March 2, 2011

Page 56: Silex - The Symfony2 Microframework

fork me on github

igorw/Silex

Wednesday, March 2, 2011

Page 57: Silex - The Symfony2 Microframework

Ω

Wednesday, March 2, 2011

Page 58: Silex - The Symfony2 Microframework

Questions?

Wednesday, March 2, 2011