silex - the symfony2 microframework

Post on 10-May-2015

22.010 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

μWednesday, March 2, 2011

• phpBB developer

• GH: igorw

• Twitter: @igorwesome

Who?

Wednesday, March 2, 2011

Microframeworks

Wednesday, March 2, 2011

What?

• Bare bones

• Routes mapped to actions

• The ‘C’ of ‘MVC’

• REST

• Single file app

Wednesday, March 2, 2011

Why?

• Frameworks are:

• heavy

• verbose

• complex

Wednesday, March 2, 2011

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

Wednesday, March 2, 2011

Wednesday, March 2, 2011

require 'sinatra'

get '/' do 'Hello world!'end

Wednesday, March 2, 2011

Silex

Wednesday, March 2, 2011

Silex(by fabpot)

Wednesday, March 2, 2011

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

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

Wednesday, March 2, 2011

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

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

Phar

Wednesday, March 2, 2011

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

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

Instance

Wednesday, March 2, 2011

require_once __DIR__.'/silex.phar';

use Silex\Framework;

$app = new Framework();

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

Closure

Wednesday, March 2, 2011

$app->run();

Wednesday, March 2, 2011

<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

Dynamic Routing

Wednesday, March 2, 2011

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

return "Hello $name!";});

Wednesday, March 2, 2011

Before & After

Wednesday, March 2, 2011

$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

$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

$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

$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

REST

Wednesday, March 2, 2011

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

$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

Errors(Exceptions)

Wednesday, March 2, 2011

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

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

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

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

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

How?

• Symfony2

• Extends HttpKernel

• Event Dispatcher

• Routing

• Request & Response

Wednesday, March 2, 2011

Experimental Fork

• String return value

• Syntactic sugar for routes

• Before & after hooks

• Error handling

• Integration tests

Wednesday, March 2, 2011

MicroKernelBundle

• Bulat Shakirzyanow (avalanche123)

• More routing flexibility

• Uses instance of Kernel

• Integrates with Symfony2

Wednesday, March 2, 2011

Recipes

Wednesday, March 2, 2011

#1 File structure

• app.php

• bootstrap.php

• index.php

Wednesday, March 2, 2011

app.php

require __DIR__.'/bootstrap.php';

use Silex\Framework;

$app = new Framework();

/* routes */

return $app;

Wednesday, March 2, 2011

bootstrap.php

require_once __DIR__.'/silex.phar';

// custom setup...

Wednesday, March 2, 2011

index.php

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

Wednesday, March 2, 2011

#2 Service Container

Wednesday, March 2, 2011

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

config.dev.yml

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

Wednesday, March 2, 2011

app.php

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

Wednesday, March 2, 2011

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

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

#3 Twig

Wednesday, March 2, 2011

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

app.php

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

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

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

Wednesday, March 2, 2011

Wednesday, March 2, 2011

#4 Testing

Wednesday, March 2, 2011

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

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

$ phpunit test.php

Wednesday, March 2, 2011

fork me on github

igorw/Silex

Wednesday, March 2, 2011

Ω

Wednesday, March 2, 2011

Questions?

Wednesday, March 2, 2011

top related