Silex: From nothing to an API

11,634 views

Published on

Published in: Technology

Silex: From nothing to an API

  1. 1. Silex: From nothing, to an APISunday, 21 April 13
  2. 2. About me Im Chris Kemper I work at Drummond Central, but I also freelance Ive been in the industry for around 5 years Ive written a book with a snake on the cover (Its on Version Control, if you didnt know) I also own an elePHPantSunday, 21 April 13
  3. 3. About me Pies CowsSunday, 21 April 13
  4. 4. What is Silex? "Silex is a PHP microframework for PHP 5.3. It is built on the shoulders of Symfony2 and Pimple and also inspired by sinatra." Created by Fabien Potencier and Igor WiedlerSunday, 21 April 13
  5. 5. Getting started You can download it from the site directly http://silex.sensiolabs.org/ Or, you can get with the times and use Composer { "require": { "silex/silex": "1.0.*@dev" ! } }Sunday, 21 April 13
  6. 6. Your first end point I’ve used Composer, so after it’s all installed, you can add the first end point! require_once __DIR__./../vendor/autoload.php; $app = new SilexApplication(); $app->get(/hello/{name}, function($name) use($app) { !return Hello .$app->escape($name); }); $app->run();Sunday, 21 April 13
  7. 7. Don’t forget about .htaccess Composer doesn’t pull it down, do don’t forget to put it in. <IfModule mod_rewrite.c> Options -MultiViews RewriteEngine On #RewriteBase /path/to/app RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule> If you’re using Apache 2.2.16+, then you can use: FallbackResource /index.phpSunday, 21 April 13
  8. 8. nginx works too! server { location = / { try_files @site @site; } location / { try_files $uri $uri/ @site; } location ~ .php$ { return 404; } location @site { fastcgi_pass unix:/var/run/php-fpm/www.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/index.php; #fastcgi_param HTTPS on; } }Sunday, 21 April 13
  9. 9. Using a templating language You don’t always want to output strings, so let’s use Twig, because it’s awesome. { "require": { "silex/silex": "1.0.*@dev", "twig/twig": ">=1.8,<2.0-dev", "symfony/twig-bridge": "~2.1" } }Sunday, 21 April 13
  10. 10. Register the Twig Service provider $app->register(new SilexProviderTwigServiceProvider(), array( ! twig.path => __DIR__./views, )); Now to use it $app->get(/hello/{name}, function ($name) use ($app) { !return $app[twig]->render(hello.twig, array( ! name => $name, )); });Sunday, 21 April 13
  11. 11. So many more Service providers Check the docs at http://silex.sensiolabs.org/documentation There are a boat load of Built-in Service Providers which you can take advantage of! Doctrine, Monolog, Form and Validation are just a couple of examples.Sunday, 21 April 13
  12. 12. Tips: Extending the base application This allows you to add, anything to the base application to make your own life easier. First of all, you need a class <?php namespace Acme; use SilexApplication as BaseApplication; class Application extends BaseApplication { }Sunday, 21 April 13
  13. 13. Tips: Extending the base application Now time to autoload that class, psr-0 style. { "require": { "silex/silex": "1.0.*@dev", "twig/twig": ">=1.8,<2.0-dev", "symfony/twig-bridge": "~2.1"! }, "autoload": { "psr-0": {"Acme": "src/"} } }Sunday, 21 April 13
  14. 14. Tips: Separate your config and routes app/bootstrap.php require_once __DIR__ . /../vendor/autoload.php; use ! SymfonyComponentHttpFoundationRequest, ! SymfonyComponentHttpFoundationResponse; use ! AcmeApplication; $app = new Application; $app->register(new SilexProviderTwigServiceProvider(), array( ! twig.path => __DIR__./views, )); return $app;Sunday, 21 April 13
  15. 15. Tips: Separate your config and routes web/index.php <?php $app = include __DIR__ . /../app/bootstrap.php; $app->get(/hello/{name}, function ($name) use ($app) { return $app[twig]->render(hello.twig, array( name => $name, )); }); $app->run();Sunday, 21 April 13
  16. 16. Lets make an API Silex is great for APIs, so lets make one. Here is the groundwork for a basic user-based API Some lovely endpoints: Create a user (/user) - This will use POST to create a new user in the DB. Update a user (/user/{id}) - This will use PUT to update the user View a user (/user/{id}) - This will use GET to view the users information Delete a user (/user/{id}) - Yes you guessed it, this uses the DELETE method.Sunday, 21 April 13
  17. 17. More dependencies! If we want to use a database, well need to define one. Lets get DBAL! { "require": { "silex/silex": "1.0.*@dev", "twig/twig": ">=1.8,<2.0-dev", "symfony/twig-bridge": "~2.1", "doctrine/dbal": "2.2.*" }, "autoload": { "psr-0": {"Acme": "src/"} } }Sunday, 21 April 13
  18. 18. More dependencies! Itll just be MySQL so lets configure that $app->register(new DoctrineServiceProvider(), array( ! db.options => array( ! ! dbname ! => acme, ! ! user ! ! => root, ! ! password ! => root, ! ! host ! ! => localhost, ! ! driver ! => pdo_mysql, ! ), ));Sunday, 21 April 13
  19. 19. Show me your endpoints: POST Before we can do anything, we need to create some users. $app->post(/user, function (Request $request) use ($app) { $user = array( email => $request->get(email), ! name => $request->get(name) ); $app[db]->insert(user, $user); return new Response("User " . $app[db]->lastInsertId() . " created", 201); });Sunday, 21 April 13
  20. 20. Show me your endpoints: PUT To update the users, we need to use PUT $app->put(/user/{id}, function (Request $request, $id) use ($app) { $sql = "UPDATE user SET email = ?, name = ? WHERE id = ?"; $app[db]->executeUpdate($sql, array( $request->get(email), $request->get(name), (int) $id) ); ! return new Response("User " . $id . " updated", 303); });Sunday, 21 April 13
  21. 21. Show me your endpoints: GET Lets get the API to output the user data as JSON $app->get(/user/{id}, function (Request $request, $id) use ($app) { $sql = "SELECT * FROM user WHERE id = ?"; $post = $app[db]->fetchAssoc($sql, array((int) $id)); return $app->json($post, 201); });Sunday, 21 April 13
  22. 22. Show me your endpoints: DELETE Lastly, we have DELETE $app->delete(/user/{id}, function (Request $request, $id) use ($app) { $sql = "DELETE FROM user WHERE id = ?"; $app[db]->executeUpdate($sql, array((int) $id)); return new Response("User " . $id . " deleted", 303); });Sunday, 21 April 13
  23. 23. A note about match() Using match, you can catch any method used on a route. Like so: $app->match(/user, function () use ($app) { ! ... }); You can also limit the method accepted by match by using the method method $app->match(/user, function () use ($app) { ! ... })->method(PUT|POST);Sunday, 21 April 13
  24. 24. Using before() and after() Each request, can be pre, or post processed. In this case, it could be used for auth. $before = function (Request $request) use ($app) { ... }; $after = function (Request $request) use ($app) { ... }; $app->match(/user, function () use ($app) { ... }) ->before($before) ->after($after);Sunday, 21 April 13
  25. 25. Using before() and after() This can also be used globally, like so: $app->before(function(Request $request) use ($app) { ... }); You can also make an event be as early as possible, or as late as possible by using Application::EARLY_EVENT and Application::LATE_EVENT, respectively. $app->before(function(Request $request) use ($app) { ... }, Application::EARLY_EVENT);Sunday, 21 April 13
  26. 26. Time for a demoSunday, 21 April 13
  27. 27. Summary This is just a small amount of what Silex is capable of, try it out. Thank You! http://silex.sensiolabs.org/ @chrisdkemper http://chrisdkemper.co.ukSunday, 21 April 13

×