Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Silex (phpday)
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Igor Wiedler
May 29, 2012
Programming
11
1.6k
Silex (phpday)
Igor Wiedler
May 29, 2012
Tweet
Share
More Decks by Igor Wiedler
See All by Igor Wiedler
Redis Bedtime Stories
igorw
1
320
Wide Event Analytics (LISA19)
igorw
4
930
a day in the life of a request
igorw
0
150
production: an owner's manual
igorw
0
170
The Power of 2
igorw
0
310
LISP 1.5 Programmer's Manual: A Dramatic Reading
igorw
0
450
The Moral Character of Software
igorw
1
290
interdisciplinary computing (domcode)
igorw
0
300
miniKanren (clojure berlin)
igorw
1
310
Other Decks in Programming
See All in Programming
AI & Enginnering
codelynx
0
110
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
Oxlint JS plugins
kazupon
1
840
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
6
1.8k
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
5
360
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
670
AI時代の認知負荷との向き合い方
optfit
0
150
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
380
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
510
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
120
CSC307 Lecture 08
javiergs
PRO
0
670
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
54
8k
Docker and Python
trallard
47
3.7k
Paper Plane
katiecoart
PRO
0
46k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
100
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
250
Claude Code のすすめ
schroneko
67
210k
Code Reviewing Like a Champion
maltzj
527
40k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.2k
Are puppies a ranking factor?
jonoalderson
1
2.7k
Designing for humans not robots
tammielis
254
26k
How to train your dragon (web standard)
notwaldorf
97
6.5k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.2k
Transcript
None
• phpBB • Symfony2 • Silex • Composer igorw @igorwesome
None
$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");
require __DIR__.'/c.php'; if (!is_callable($c = @$_GET['c'] ?: function() { echo
'Woah!'; })) throw new Exception('Error'); $c();
Silex Symfony2 μ-framework
Silex is not Symfony
Microframework
None
What? • Bare bones • Routes mapped to controllers •
The ‘C’ of ‘MVC’ • REST • Single file app (ish)
Why?
Sometimes a full-stack framework is too much for a simple
task.
simple
What makes silex special?
• concise • extensible • testable
• concise • extensible • testable
• concise • extensible • testable
• concise • extensible • testable
• concise • extensible • testable
Http Kernel Interface
Response handle(Request $request)
client
request client
reponse client request
clean
PSR-0
None
Silex is not Symfony
Silex is a user interface for Symfony
require_once __DIR__.'/silex.phar'; $app = new Silex\Application(); $app->get('/', function() { return
"Hello world!"; });
Phar require_once __DIR__.'/silex.phar'; $app = new Silex\Application(); $app->get('/', function() {
return "Hello world!"; });
Phar require_once __DIR__.'/silex.phar'; $app = new Silex\Application(); $app->get('/', function() {
return "Hello world!"; }); = FUBAR
Composer require_once 'vendor/autoload.php'; $app = new Silex\Application(); $app->get('/', function() {
return "Hello world!"; });
Application require_once 'vendor/autoload.php'; $app = new Silex\Application(); $app->get('/', function() {
return "Hello world!"; });
require_once 'vendor/autoload.php'; $app = new Silex\Application(); $app->get('/', function() { return
"Hello world!"; }); Controller
$app->run();
None
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /some/path RewriteCond %{REQUEST_FILENAME} !-f RewriteCond
%{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L] </IfModule>
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; } }
Wait a minute!
Lambdas λ
$(function () { $("a").on("click", function (event) { alert("Thanks for visiting!");
}); });
PHP 5.3
$f = function ($a, $b) { return $a + $b;
}; $f(1, 2);
lazy $f = function () { exit; };
nested $f = function () { return function () {
return true; }; }; $g = $f(); $value = $g();
scope $outer = 'world'; $f = function () use ($outer)
{ $inner = 'hello'; return "$inner $outer"; }; => "hello world"
scope $helloWorld = function () { $outer = 'world'; $f
= function () use ($outer) { $inner = 'hello'; return "$inner $outer"; }; return $f(); }
passing $output = function ($info) { echo $info."\n"; }; $doStuff
= function ($output) { $output('doing some magic'); doMagic(); $output('did some magic'); };
factory $userFactory = function ($name) { return new User($name); };
// ... $user = $userFactory($_POST['name']);
event listener $emitter = new EventEmitter(); $emitter->on('user.create', function (User $user)
{ $msg = sprintf("User %s created.", $user->name); log($msg); });
Usage
$app->get('/', function () { return "Hello world!"; });
Dynamic Routing
$app->get('/hello/{name}', function ($name) use ($app) { return "Hello ".$app->escape($name); });
$app->get('/hello/{name}', function ($name) use ($app) { return "Hello ".$app->escape($name); });
Controllers
assert $app->get('/blog/{id}', function ($id) { ... }) ->assert('id', '\d+');
value $app->get('/{page}', function ($page) { ... }) ->value('page', 'index');
bind $app->get('/', function () { ... }) ->bind('homepage'); $app['url_generator']->generate('homepage')
bind $app->get('/blog/{id}', function ($id) { ... }) ->bind('blog.post'); $app['url_generator'] ->generate('blog.post',
array('id' => $id))
convert $app->get('/blog/{post}', function (Post $post) { ... }) ->convert('post', function
($post) use ($app) { $id = (int) $post; return $app['posts']->find($id); });
Before & After
$app->before(function () { ... }); $app->get('/', function () { ...
}); $app->after(function () { ... });
$app->before(function (Request $request) { $loggedIn = $request ->getSession() ->get('logged_in'); if
(!$loggedIn) { return new RedirectResponse('/login'); } });
$app->after(function (Request $request, Response $response) { // tweak the Response
});
Methods
• get • post • put • delete • head
• options
$app->get('/posts/{id}', ...); $app->post('/posts', ...); $app->put('/posts/{id}', ...); $app->delete('/post/{id}', ...);
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; $app->post('/message', function (Request $request) { mail(
'
[email protected]
', 'New message', $request->get('body') ); return new Response('Email has been sent!', 201); });
Caching
Error Handling
use Symfony\Component\HttpFoundation\Response; $app->error(function (\Exception $e, $code) { return new Response('Whoops!',
$code); });
$app->abort(404, "Could not find the thing.");
$app['debug'] = true;
Redirecting
$app->get('/', function () use ($app) { return $app->redirect('/hello'); });
Pimple
~50 NCLOC
$container = new Pimple();
$app = new Silex\Application();
Parameters $app['some_parameter'] = 'value'; $app['asset.host'] = 'http://cdn.mysite.com/'; $app['database.dsn'] = 'mysql:dbname=myapp';
Services $app['some_service'] = function () { return new Service(); };
$service = $app['some_service'];
Dependencies $app['some_service'] = function ($app) { return new Service( $app['some_other_service'],
$app['some_service.config'] ); };
Shared $app['some_service'] = $app->share(function () { return new Service(); });
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);
Exposed Services • debug • request • autoloader • routes
• controllers • dispatcher • resolver • kernel
Service Providers
interface ServiceProviderInterface { function register(Application $app); }
Core Service Providers • doctrine • form • http cache
• monolog • session • swiftmailer • symfony bridges • translation • twig • url generator • validator
3rd Party • doctrine orm • propel • pomm (postgres)
• predis • mongo • KyotoTycoon • memcache • rest • markdown • gravatar • buzz • config • solr • profiler • ...
Redis
$app->register(new PredisServiceProvider());
$app->get('/{id}', function ($id) use ($app) { $key = 'pastes:'.$id; $paste
= $app['predis']->hgetall($key); ... });
None
• smallish sites • well-defined scope • prototyping • restful
apis When to use
and many more...
None
New feature: Streaming
$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') ); });
New feature: Middlewares
$mustBeLogged = function (Request $request) use ($app) { if (!$app['session']->has('userId'))
{ return $app->redirect('/user/login'); } }; $app->get('/user/my-profile', function () { ... }) ->middleware($mustBeLogged);
New feature: JSON helper
$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); });
New feature: Finish filter
$app->finish(function () { // send e-mails // very slow query
// some slow API calls });
New feature: Composer
None
{ "minimum-stability": "dev", "require": { "silex/silex": "1.0.*@dev" } } composer.json
$ php composer.phar install
require 'vendor/autoload.php';
on github fabpot/Silex fabpot/Pimple
silex.sensiolabs.org
Ω
Questions? joind.in/6391 @igorwesome speakerdeck.com /u/igorw