silex: from nothing to an api
DESCRIPTION
TRANSCRIPT
Silex: From nothing, to an API
Sunday, 21 April 13
About me
I'm Chris Kemper
I work at Drummond Central, but I also freelance
I've been in the industry for around 5 years
I've written a book with a snake on the cover (It's on Version Control, if you didn't know)
I also own an elePHPant
Sunday, 21 April 13
About me
Pies
Cows
Sunday, 21 April 13
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 Wiedler
Sunday, 21 April 13
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
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 Silex\Application();
$app->get('/hello/{name}', function($name) use($app) { !return 'Hello '.$app->escape($name); });
$app->run();
Sunday, 21 April 13
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.php
Sunday, 21 April 13
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
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
Register the Twig Service provider
$app->register(new Silex\Provider\TwigServiceProvider(), 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
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
Tips: Extending the base application
<?phpnamespace Acme;
use Silex\Application as BaseApplication;
class Application extends BaseApplication {
}
This allows you to add, anything to the base application to make your own life easier.
First of all, you need a class
Sunday, 21 April 13
Tips: Extending the base application
{"require": { "silex/silex": "1.0.*@dev",
"twig/twig": ">=1.8,<2.0-dev", "symfony/twig-bridge": "~2.1"!
}, "autoload": {
"psr-0": {"Acme": "src/"} }}
Now time to autoload that class, psr-0 style.
Sunday, 21 April 13
Tips: Separate your config and routes
require_once __DIR__ . '/../vendor/autoload.php';
use ! Symfony\Component\HttpFoundation\Request,! Symfony\Component\HttpFoundation\Response;
use! Acme\Application;
$app = new Application;
$app->register(new Silex\Provider\TwigServiceProvider(), array(! 'twig.path' => __DIR__.'/views',));
return $app;
app/bootstrap.php
Sunday, 21 April 13
Tips: Separate your config and routes
<?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();
web/index.php
Sunday, 21 April 13
Let's make an API
Silex is great for API's, so let's 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 userView a user (/user/{id}) - This will use GET to view the users informationDelete a user (/user/{id}) - Yes you guessed it, this uses the DELETE method.
Sunday, 21 April 13
More dependencies!
If we want to use a database, we'll need to define one. Let's 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
More dependencies!
It'll just be MySQL so let's 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
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
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
Show me your endpoints: GET
Let's 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
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
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
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
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
Time for a demo
Sunday, 21 April 13
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.uk
Sunday, 21 April 13