Post on 10-May-2015
μ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
Ian Press Photography
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