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
160
production: an owner's manual
igorw
0
180
The Power of 2
igorw
0
320
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
310
miniKanren (clojure berlin)
igorw
1
310
Other Decks in Programming
See All in Programming
kintone + ローカルLLM = ?
akit37
0
120
Claude Codeセッション現状確認 2026福岡 / fukuoka-aicoding-00-beacon
monochromegane
3
320
AIとペアプロして処理時間を97%削減した話 #pyconshizu
kashewnuts
1
150
Go Conference mini in Sendai 2026 : Goに新機能を提案し実装されるまでのフロー徹底解説
yamatoya
0
420
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
1
370
CSC307 Lecture 11
javiergs
PRO
0
580
文字コードの話
qnighy
41
16k
「ブロックテーマでは再現できない」は本当か?
inc2734
0
1.1k
ぼくの開発環境2026
yuzneri
1
290
grapheme_strrev関数が採択されました(あと雑感)
youkidearitai
PRO
1
160
AIと一緒にレガシーに向き合ってみた
nyafunta9858
0
440
Python’s True Superpower
hynek
0
190
Featured
See All Featured
The SEO identity crisis: Don't let AI make you average
varn
0
400
Become a Pro
speakerdeck
PRO
31
5.8k
Unsuck your backbone
ammeep
671
58k
A Tale of Four Properties
chriscoyier
162
24k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
79
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.8k
YesSQL, Process and Tooling at Scale
rocio
174
15k
The Curse of the Amulet
leimatthew05
1
9.2k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
450
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
370
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
92
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