Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Silex (phpday)

Silex (phpday)

Igor Wiedler

May 29, 2012
Tweet

More Decks by Igor Wiedler

Other Decks in Programming

Transcript

  1. None
  2. • phpBB • Symfony2 • Silex • Composer igorw @igorwesome

  3. None
  4. $s=stream_socket_server('tcp://127.0.0.1:81'); while($c=stream_socket_accept($s)) fwrite($c,"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nHi");

  5. require __DIR__.'/c.php'; if (!is_callable($c = @$_GET['c'] ?: function() { echo

    'Woah!'; })) throw new Exception('Error'); $c();
  6. Silex Symfony2 μ-framework

  7. Silex is not Symfony

  8. Microframework

  9. None
  10. What? • Bare bones • Routes mapped to controllers •

    The ‘C’ of ‘MVC’ • REST • Single file app (ish)
  11. Why?

  12. Sometimes a full-stack framework is too much for a simple

    task.
  13. simple

  14. What makes silex special?

  15. • concise • extensible • testable

  16. • concise • extensible • testable

  17. • concise • extensible • testable

  18. • concise • extensible • testable

  19. • concise • extensible • testable

  20. Http Kernel Interface

  21. Response handle(Request $request)

  22. client

  23. request client

  24. reponse client request

  25. clean

  26. PSR-0

  27. None
  28. Silex is not Symfony

  29. Silex is a user interface for Symfony

  30. require_once __DIR__.'/silex.phar'; $app = new Silex\Application(); $app->get('/', function() { return

    "Hello world!"; });
  31. Phar require_once __DIR__.'/silex.phar'; $app = new Silex\Application(); $app->get('/', function() {

    return "Hello world!"; });
  32. Phar require_once __DIR__.'/silex.phar'; $app = new Silex\Application(); $app->get('/', function() {

    return "Hello world!"; }); = FUBAR
  33. Composer require_once 'vendor/autoload.php'; $app = new Silex\Application(); $app->get('/', function() {

    return "Hello world!"; });
  34. Application require_once 'vendor/autoload.php'; $app = new Silex\Application(); $app->get('/', function() {

    return "Hello world!"; });
  35. require_once 'vendor/autoload.php'; $app = new Silex\Application(); $app->get('/', function() { return

    "Hello world!"; }); Controller
  36. $app->run();

  37. None
  38. <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /some/path RewriteCond %{REQUEST_FILENAME} !-f RewriteCond

    %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L] </IfModule>
  39. server { index index.php location / { try_files $uri $uri/

    /index.php; } location ~ index\.php$ { fastcgi_pass /var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; } }
  40. Wait a minute!

  41. Lambdas λ

  42. $(function () { $("a").on("click", function (event) { alert("Thanks for visiting!");

    }); });
  43. PHP 5.3

  44. $f = function ($a, $b) { return $a + $b;

    }; $f(1, 2);
  45. lazy $f = function () { exit; };

  46. nested $f = function () { return function () {

    return true; }; }; $g = $f(); $value = $g();
  47. scope $outer = 'world'; $f = function () use ($outer)

    { $inner = 'hello'; return "$inner $outer"; }; => "hello world"
  48. scope $helloWorld = function () { $outer = 'world'; $f

    = function () use ($outer) { $inner = 'hello'; return "$inner $outer"; }; return $f(); }
  49. passing $output = function ($info) { echo $info."\n"; }; $doStuff

    = function ($output) { $output('doing some magic'); doMagic(); $output('did some magic'); };
  50. factory $userFactory = function ($name) { return new User($name); };

    // ... $user = $userFactory($_POST['name']);
  51. event listener $emitter = new EventEmitter(); $emitter->on('user.create', function (User $user)

    { $msg = sprintf("User %s created.", $user->name); log($msg); });
  52. Usage

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

  54. Dynamic Routing

  55. $app->get('/hello/{name}', function ($name) use ($app) { return "Hello ".$app->escape($name); });

  56. $app->get('/hello/{name}', function ($name) use ($app) { return "Hello ".$app->escape($name); });

  57. Controllers

  58. assert $app->get('/blog/{id}', function ($id) { ... }) ->assert('id', '\d+');

  59. value $app->get('/{page}', function ($page) { ... }) ->value('page', 'index');

  60. bind $app->get('/', function () { ... }) ->bind('homepage'); $app['url_generator']->generate('homepage')

  61. bind $app->get('/blog/{id}', function ($id) { ... }) ->bind('blog.post'); $app['url_generator'] ->generate('blog.post',

    array('id' => $id))
  62. convert $app->get('/blog/{post}', function (Post $post) { ... }) ->convert('post', function

    ($post) use ($app) { $id = (int) $post; return $app['posts']->find($id); });
  63. Before & After

  64. $app->before(function () { ... }); $app->get('/', function () { ...

    }); $app->after(function () { ... });
  65. $app->before(function (Request $request) { $loggedIn = $request ->getSession() ->get('logged_in'); if

    (!$loggedIn) { return new RedirectResponse('/login'); } });
  66. $app->after(function (Request $request, Response $response) { // tweak the Response

    });
  67. Methods

  68. • get • post • put • delete • head

    • options
  69. $app->get('/posts/{id}', ...); $app->post('/posts', ...); $app->put('/posts/{id}', ...); $app->delete('/post/{id}', ...);

  70. use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; $app->post('/message', function (Request $request) { mail(

    'me@me.me', 'New message', $request->get('body') ); return new Response('Email has been sent!', 201); });
  71. Caching

  72. Error Handling

  73. use Symfony\Component\HttpFoundation\Response; $app->error(function (\Exception $e, $code) { return new Response('Whoops!',

    $code); });
  74. $app->abort(404, "Could not find the thing.");

  75. $app['debug'] = true;

  76. Redirecting

  77. $app->get('/', function () use ($app) { return $app->redirect('/hello'); });

  78. Pimple

  79. ~50 NCLOC

  80. $container = new Pimple();

  81. $app = new Silex\Application();

  82. Parameters $app['some_parameter'] = 'value'; $app['asset.host'] = 'http://cdn.mysite.com/'; $app['database.dsn'] = 'mysql:dbname=myapp';

  83. Services $app['some_service'] = function () { return new Service(); };

  84. $service = $app['some_service'];

  85. Dependencies $app['some_service'] = function ($app) { return new Service( $app['some_other_service'],

    $app['some_service.config'] ); };
  86. Shared $app['some_service'] = $app->share(function () { return new Service(); });

  87. Protected $app['lambda_parameter'] = $app->protect( function ($a, $b) { return $a

    + $b; }); // will not execute the lambda $add = $app['lambda_parameter']; // calling it now echo $add(2, 3);
  88. Exposed Services • debug • request • autoloader • routes

    • controllers • dispatcher • resolver • kernel
  89. Service Providers

  90. interface ServiceProviderInterface { function register(Application $app); }

  91. Core Service Providers • doctrine • form • http cache

    • monolog • session • swiftmailer • symfony bridges • translation • twig • url generator • validator
  92. 3rd Party • doctrine orm • propel • pomm (postgres)

    • predis • mongo • KyotoTycoon • memcache • rest • markdown • gravatar • buzz • config • solr • profiler • ...
  93. Redis

  94. $app->register(new PredisServiceProvider());

  95. $app->get('/{id}', function ($id) use ($app) { $key = 'pastes:'.$id; $paste

    = $app['predis']->hgetall($key); ... });
  96. None
  97. • smallish sites • well-defined scope • prototyping • restful

    apis When to use
  98. and many more...

  99. None
  100. New feature: Streaming

  101. $app->get('/some-video', function () use ($app) { $file = $app['app.video_filename']; $stream

    = function () use ($file) { readfile($file); }; return $app->stream( $stream, 200, array('Content-Type' => 'video/mpeg') ); });
  102. New feature: Middlewares

  103. $mustBeLogged = function (Request $request) use ($app) { if (!$app['session']->has('userId'))

    { return $app->redirect('/user/login'); } }; $app->get('/user/my-profile', function () { ... }) ->middleware($mustBeLogged);
  104. New feature: JSON helper

  105. $app->get('/users/{id}', function ($id) use ($app) { $user = getUser($id); if

    (!$user) { $message = 'The user was not found.'; $error = array('message' => $message); return $app->json($error, 404); } return $app->json($user); });
  106. New feature: Finish filter

  107. $app->finish(function () { // send e-mails // very slow query

    // some slow API calls });
  108. New feature: Composer

  109. None
  110. { "minimum-stability": "dev", "require": { "silex/silex": "1.0.*@dev" } } composer.json

  111. $ php composer.phar install

  112. require 'vendor/autoload.php';

  113. on github fabpot/Silex fabpot/Pimple

  114. silex.sensiolabs.org

  115. Ω

  116. Questions? joind.in/6391 @igorwesome speakerdeck.com /u/igorw