SlideShare a Scribd company logo
1 of 17
Download to read offline
http://andreiabohner.org
PHP micro-framework
SILEX
Cheat Sheet
Usage
Apache
// web/index.php
require_once __DIR__.'/../vendor/autoload.php';
= new ;
->get('/hello/{name}', function ($name) use ( ) {
return 'Hello ' . ->escape($name);
});
->run();
$app SilexApplication()
$app $app
$app
$app
Install
$ composer require silex/silex:~1.2
Web Server Configuration
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
#RewriteBase /path/to/app
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
If your site is not at the webroot level:
uncomment the statement and adjust the
path to point to your directory, relative from the webroot.
RewriteBase
For Apache 2.2.16+, you can use the FallbackResource
directive:
FallbackResource /index.php
server {
#site root is redirected to the app boot script
location = / {
try_files @site @site;
}
# all other locations try other files first and go to our
# front controller if none of them exists
location / {
try_files $uri $uri/ @site;
}
#return 404 for all php files as we do have a front controller
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;
#uncomment when running via https
#fastcgi_param HTTPS on;
}
}
nginx IIS
<?xml version="1.0"?>
<configuration>
<system.webServer>
<defaultDocument>
<files>
<clear />
<add value="index.php" />
</files>
</defaultDocument>
<rewrite>
<rules>
<rule name="Silex Front Controller"
stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}"
matchType="IsFile" ignoreCase="false"
negate="true" />
</conditions>
<action type="Rewrite" url="index.php"
appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
server.document-root = "/path/to/app"
url.rewrite-once = (
# configure some static files
"^/assets/.+" => "$0",
"^/favicon.ico$" => "$0",
"^(/[^?]*)(?.*)?" => "/index.php$1$2"
)
Lighttpd
web.config file:
simple-vhost:
configure your vhost to forward non-existent resources
to index.php:
Allows run silex without any configuration. However, in
order to serve static files, you'll have to make sure your
front controller returns false in that case ( ):web/index.php
$filename = __DIR__.preg_replace('#(?.*)$#', '',
$_SERVER['REQUEST_URI']);
if (php_sapi_name() === 'cli-server' && is_file($filename)) {
return false;
}
= require __DIR__.'/../src/app.php';
->run();
$app
$app
The application should be running at .http://localhost:8080
$ php -S localhost:8080 -t web web/index.php
To start the server from the command-line:
PHP 5.4 built-in webserver
only for
development!
App Configuration
false
80
443
‘UTF-8’
‘en’
null
$app
$app
$app
$app
$app
$app
['debug']
['request.http_port']
['request.https_port']
['charset']
['locale']
['logger']
// turn on the debug mode
$app['debug'] = true;
If your application is hosted behind a reverse proxy
at address $ip, and you want Silex to trust the
X-Forwarded-For* headers, you will need to run your
application like this:
use SymfonyComponentHttpFoundationRequest;
Request::setTrustedProxies(array($ip));
->run();$app
$app['asset_path'] = 'http://assets.examples.com';
Custom Configuration ( )Parameters
{{ .asset_path }}/css/styles.cssapp
$app['base_url'] = '/';
Default Configuration
Using in a template (Twig)
Configuration Default value
Set Get
$debug = ['debug'];$app
Global Configuration
To apply a controller setting to all controllers
(a converter, a middleware, a requirement, or a default value),
configure it on :$app['controllers']
$app['controllers']
->value('id', '1')
->assert('id', 'd+')
->requireHttps()
->method('get')
->convert('id', function () {/* ... */ })
->before(function () {/* ... */ });
Global configuration does not apply to controller providers
you might mount as they have their own global configuration
applied to already registered
controllers and become the
defaults for new controllers
Symfony2 Components
HttpFoundation
HttpKernel
Routing
EventDispatcher
Symfony2 components used by Silex:
For Request and Response.
Because we need a heart.
For matching defined routes.
For hooking into the HttpKernel
App Helper Methods
$app-> ('/account );redirect '
$subRequest = Request::create('/hi', 'GET');
-> ($subRequest, HttpKernelInterface::SUB_REQUEST);$app handle
Redirect
Forward
Generate the URI using :UrlGeneratorProvider
$r = Request::create($app['url_generator']->generate('hi’), 'GET');
Return JSON data and apply correct escape
JSON
$app
$app
-> ($error, 404);
-> ($user);
json
json
Streaming response (when you cannot buffer the data being sent)
Stream
$app-> ($stream, 200, array('Content-Type' => 'image/png'));stream
To send chunks, make sure to call ob_flush and flush after
every chunk:
$stream = function () {
$fh = fopen('http://www.example.com/', 'rb');
while (!feof($fh)) {
echo fread($fh, 1024);
ob_flush();
flush();
}
fclose($fh);
};
Sending a file
$app-> ('/base/path/' . $path)
->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'pic.jpg')
sendFile
HttpFoundation 2.2+
Create a BinaryFileResponse
$app-> ($name)escape
Escape
Escape user input, to prevent Cross-Site-Scripting attacks
Stop the request early. It actually throws an exception
$app-> (404, "Book $id does not exist.");abort
Abort
Set
$assetPath = ['asset_path'];$app
Get
EARLY_EVENT = 512;
LATE_EVENT = -512;
App Events
Routing
A route pattern consists of:
Pattern
-> ('/blog', function () use ($posts) {
$output = '';
foreach ($posts as $post) {
$output .= $post['title'];
$output .= '<br />';
}
return $output;
});
$app get
HTTP Methods
$app
$app
-> ('/books', function ($id) {
// ...
});
-> ('/books/{id}', function () {
// ...
});
post
get
For Symfony Components 2.2+:
explicitly enable method override
HTTP method override
(for PUT, DELETE, and PATCH)
The current App is
automatically injected
to the closure thanks
to the type hinting
Forms in most web browsers do not directly support
the use of other HTTP methods.
Use a special form field named ._method
<form action="/my/target/route/" method=" ">
<!-- ... -->
<input type="hidden" name=" " value=" " />
</form>
POST
_method PUT
use SymfonyComponentHttpFoundationRequest;
Request::enableHttpMethodParameterOverride();
->run();$app
Can be restricted
via the method
method
$app
$app
$app
-> ('/book’, function () {
// ...
});
-> ('/book', function () {
// ...
})
-> ('PATCH');
-> ('/book', function () {
// ...
})
-> ('PUT|POST');
match
match
match
method
method
The order of the routes is significant.
The first matching route will be used
(place more generic routes at the bottom)
variable part passed to the closure
$app SilexApplication $app
$app
->get('/blog/ ', function ( , ) use ($posts) {
if (!isset($posts[$id])) {
->abort(404, "Post $id does not exist.");
}
$post = $posts[$id];
return "<h1>{$post['title']}</h1>" .
“<p>{$post['body']}</p>";
});
{id} $id
patternmethod
Defines a path that points to a resource.
Can include variable parts and you are able
to set RegExp requirements for them
One of the HTTP methods:
GET, POST, PUT or DELETE.
Describes the interaction with the resource
Method
POST
GET
Dynamic Route (Route Variable)
$app
$app
-> ('/books/{id}', function ($id) {
// ...
});
-> ('/books/{id}', function ($id) {
// ...
});
put
delete
PUT
DELETE
$app-> ('/books/{id}', function ($id) {
// ...
});
patchPATCH
Matching all Methods
Default Values
This will allow matching /, in which
case the variable will have the
value
page
index
$app->get('/{page}', function ($page) {
// ...
})
-> (' ’, ' ');value page index
To define a default value for any
route variable call on the
object:
value
Controller
The form's method attribute must be set to
when using this field:
POST
Route Variables Converters
$app->get('/user/{id}', function ($id) {
// ...
})-> ('id', function ($id) {return (int) $id; });convert
Appling some converters before injecting route variables
into the controller:
Converting route variables to objects
$userProvider = function ($id) {
return new User($id);
};
->get('/user/{user}/edit', function (User $user) {
// ...
})-> ('user', $userProvider);
$app
convert
The converter callback also receives the as
its second argument:
Request
$callback = function ($post, Request $req) {
return new Post($req->attributes->get('slug'));
};
->get('/blog/{id}/{slug}', function (Post $post) {
// ...
})-> ('post', $callback);
$app
convert
Converter defined as a service
use DoctrineCommonPersistenceObjectManager;
use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
class UserConverter
{
private $om;
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
public function convert($id)
{
if (null === $user = $this->om->find('User', (int) $id)) {
throw new NotFoundHttpException(
sprintf('User %d does not exist', $id)
);
}
return $user;
}
}
The service will now be registered in the app, and
the convert method will be used as converter:
E.g.: user converter based on Doctrine ObjectManager:
$app
$app
['converter.user'] = $app->share(function () {
return new UserConverter();
});
->get('/user/{user}', function (User $user) {
// ...
})-> ('user', 'converter.user:convert');convert
Requirements
$app->get('/blog/{id}', function ($id) {
// ...
})
-> ('id', 'd+');assert
$app->get('/blog/{postId}/{commentId}', function ($postId, $commentId) {
// ...
})
-> ('postId', 'd+')
-> ('commentId', 'd+');
assert
assert
Chained requirements
$app
$app
->get('/', function () {
// ...
})
-> ('homepage');
->get('/blog/{id}', function ($id) {
// ...
})
-> ('blog_post');
bind
bind
Named Routes
It only makes sense to name routes if you use providers
that make use of the RouteCollection
$app->get('/', ' );
use SilexApplication;
use SymfonyComponentHttpFoundationRequest;
namespace Acme
{
class Foo
{
public function bar(Request $request, Application $app)
{
// ...
AcmeFoo::bar'
Controllers in Classes
For an even stronger separation between Silex and your
controllers, you can define your controllers as services
Group URLs (mount) mount() prefixes all routes with the given prefix
and merges them into the main Application
// define controllers for a blog
$blog = ['controllers_factory'];
$blog->get('/', function () {
return 'Blog home page';
});
$app
$app['controllers_factory']
ControllerCollection
is a factory that returns a new instance
of .
When mounting a route collection under /blog, it is not possible to define
a route for the /blog URL. The shortest possible URL is /blog/.
// define "global" controllers
->get('/', function () {
return 'Main home page';
});
-> ('/blog', $blog);
-> ('/forum', $forum);
// / map to the main home page
// /blog/ map to the blog home page
// /forum/ map to the forum home page
$app
$app
$app
mount
mount
// define controllers for a forum
$forum = ['controllers_factory'];
$forum->get('/', function () {
return 'Forum home page';
});
$app
version 1.2
(a:b notation)
Error Handlers
use SymfonyComponentHttpFoundationResponse;
-> (function (Exception $e, ) {
return new Response('Something went terribly wrong.');
});
$app error $code
use SymfonyComponentHttpFoundationResponse;
-> (function (Exception $e, ) {
switch ( ) {
case 404:
$message = 'Page not found.';
break;
default:
$message = 'Something went terribly wrong.';
}
return new Response($message);
});
$app error $code
$code
Check for specific errors (using ):$code
As Silex ensures that the status code
is set to the most appropriate one depending
on the exception, setting the status on the
response won't work.
To overwrite the status code (which should not
without a good reason), set the
header:
Response
X-Status-Code
return new Response('Error', 404 /* ignored */,
array('X-Status-Code' => 200));
To restrict an error handler to only handle some Exception
classes set a more specific type hint for the Closure argument:
$app-> (function (LogicException $e, $code) {
// this handler will only handle LogicException exceptions
// and exceptions that extends LogicException
});
error
Silex comes with a default error handler that displays a
detailed error message with the stack trace when debug
is true, and a simple error message otherwise.
-> (function (Exception $e, $code) use ( ) {
if ( ['debug']) {
return;
}
// ... logic to handle the error and return a Response
});
$app $app
$app
error
The error handlers are also called when you use abort to
abort a request early:
$app $app
$app
->get('/blog/{id}', function (SilexApplication , $id)
use ($posts) {
if (!isset($posts[$id])) {
-> (404, "Post $id does not exist.");
}
return new Response(...);
});
abort
Traits
Define shortcut methods.
PHP 5.4+
Almost all built-in service providers have some
corresponding PHP traits.
To use them, define your own class and
include the traits you want:
Application
use SilexApplication;
class MyApplication extends Application
{
use ApplicationTwigTrait;
use ApplicationSecurityTrait;
use ApplicationFormTrait;
use ApplicationUrlGeneratorTrait;
use ApplicationSwiftmailerTrait;
use ApplicationMonologTrait;
use ApplicationTranslationTrait;
}
To define your own Route class and use some traits:
use SilexRoute;
class MyRoute extends Route
{
use RouteSecurityTrait;
}
To use the newly defined route, override the
setting:$app['route_class']
$app['route_class'] = 'MyRoute';
Restricting Error Handler
Debug and Error Handler
Use a separate error handler for .
Make sure to register it before the response
error handlers, because once a response is returned,
the following handlers are ignored.
logging
Logging and Error Handler
Error handlers registered via method always
take precedence. To keep the nice error messages when
debug is on use this:
error()
To register an error handler, pass a closure to the
error method which takes an argument
and returns a response:
Exception
http://silex.sensiolabs.org/
Silex documentation, examples, and download:
Middlewares
Application Middlewares
$app $app-> (function (Request $req, Application ) {
// ...
});
before
Only run
for “master”
request
Run after the routing and security and before the controller.
Before
To run the middleware even if an exception is thrown
early on (on a 404 or 403 error for instance),
register it as an early event:
$app $app-> (function (Request $req, Application ) {
// ...
}, );
before
Application::EARLY_EVENT
$app-> (function (Request $req, Response $resp) {
// ...
});
after
After
Run before the Response is sent to the client.
$app-> (function (Request $req, Response $resp) {
// ...
// Warning: modifications to the Request or Response
// will be ignored
});
finish
Terminate
Event registered on the Symfony response event.
Event registered on the Symfony terminate event.
Event registered on the Symfony request event.
Run after the Response has been sent to the client
(like sending emails or logging).
Route Middlewares
Added to routes or route collections.
Only triggered when the corresponding route is matched.
You can also stack them:
$app->get('/somewhere', function () {
// ...
})
-> ($before1)
-> ($before2)
-> ($after1)
-> ($after2)
;
before
before
after
after
Fired before the route callback, but after the before
application middlewares:
Before
$before = function (Request $req, Application ) {
// ...
};
->get('/somewhere', function () {
// ...
})
-> ($before);
$app
$app
before
Fired after the route callback, but before the application
after application middlewares:
After
$after = function (Request $req,
Response $resp,
Application ) {
// ...
};
->get('/somewhere', function () {
// ...
})
-> ($after);
$app
$app
after
The middlewares are triggered in the same order they
are added.
To control the priority of the middleware
pass an additional argument to the registration methods:
$app-> (function (Request $req) {
// ...
}, );
before
32
Middlewares Priority
As a convenience, two constants allow you to register
an event as early as possible or as late as possible:
$app
$app
-> (function (Request $req) {
// ...
}, );
-> (function (Request $req) {
// ...
}, );
before
Application::EARLY_EVENT
before
Application::LATE_EVENT
If a before middleware returns a Response object,
the Request handling is short-circuited (the next
middlewares won't be run, nor the route callback),
and the Response is passed to the after middlewares
right away:
Short-circuiting the Controller
$app-> (function (Request $req) {
// redirect the user to the login screen if access
// to the Resource is protected
if (...) {
return new RedirectResponse('/login');
}
});
before
If a before middleware does not return a Response or null,
a is thrown.RuntimeException
Services
Silex use (extends)
Pimple for DI
Definition
closurearray
$app['some_service'] = function () {
return new Service();
};
Retrieve the service:
$service = ['some_service'];$app
Every time is called,
a new instance of the service is created.
$app['some_service']
Shared Services
Use the same instance of a service across all of your code.
Create the service on first invocation, and then return the
existing instance on any subsequent access.
$app $app['some_service'] = -> (function () {
return new Service();
});
share
Access Container from Closure
Access the service container from within a service
definition closure.
For example when fetching services the current service
depends on.
$app $app
$app
$app
['some_service'] = function ( ) {
return new Service( ['some_other_service'],
['some_service.config']);
};
also works for
shared services
some_service depends
on some_other_service
$app
$app $app $app
$app
['user.persist_path'] = '/tmp/users';
['user.persister'] = -> (function ( ) {
return new JsonUserPersister( ['user.persist_path']);
});
share
Protected Closures
The container sees closures as factories for services, so
it will always execute them when reading them.
In some cases you will however want to store a closure
as a parameter, so that you can fetch it and execute
it yourself -- with your own arguments.
This is why Pimple allows to protect closures from being
executed, by using the method:protect
$app $app
$app
['closure_parameter'] = -> (function ($a, $b) {
return $a + $b;
});
// will not execute the closure
$add = ['closure_parameter'];
// calling it now
echo $add(2, 3);
protect
protected closures
do not get access
to the container
Core Services
Current request object (instance of ).
It gives access to GET, POST parameters
and lots more! E.g.:
Only available when a request is being
served, you can only access it from within
a controller, an application before/after
middlewares, or an error handler.
that is used internally.
You can add, modify, and read routes.
that is used
internally.
that is used internally.
It is the core of the Symfony2 system
and is used quite a bit by Silex.
that is used internally.
It takes care of executing the controller
with the right arguments.
Request
$id = ['request']->get('id');
RouteCollection
SilexControllerCollection
EventDispatcher
ControllerResolver
$app
HttpKernel
Request
Response
UrlGenerator
error()
['exception_handler']->disable()
PsrLogLoggerInterface
MonologServiceProvider
SymfonyComponentHttpKernel
LogLoggerInterface
that is used internally. Is the
heart of Symfony2, it takes a
as input and returns a as output
Simplified representation of the
request that is used by the Router and
the
Default handler that is used when
you don't register one via the
method or if the handler does not return
a Response. Disable it with
.
instance.
By default, logging is disabled as the
value is set to null. To enable logging
either use the
or define your own logger service that
conforms to the PSR logger interface.
In versions of Silex before 1.1 this must
be a
.
$app
request_context
request
routes
controllers
dispatcher
resolver
are shared
$app $app['asset_path'] = -> (function () {
// logic to determine the asset path
return 'http://assets.examples.com';
});
share
Define the service:
kernel
exception_handler
logger
E.g. 2:
E.g. 3:
Providers
Service Providers
Allow to reuse parts of an application into another one
In order to load and use a service provider,
register it on the application:
Loading providers
Creating a provider
Providers must implement the :SilexServiceProviderInterface
interface ServiceProviderInterface
{
public function (Application );
public function (Application );
}
register
boot
$app
$app
define services on the application which
then may make use of other services and
parameters
register()
Just create a new class that implements the two methods:
configure the application, just before it
handles a request
boot()
namespace Acme;
use SilexApplication;
use SilexServiceProviderInterface;
class HelloServiceProvider implements ServiceProviderInterface
{
public function register(Application )
{
['hello'] = -> (function ($name) use ( ){
$default = ['hello.default_name'] ?
['hello.default_name'] : ‘';
$name = $name ?: $default;
return 'Hello ' . -> ($name);
});
}
public function boot(Application )
{
}
}
$app
$app $app $app
$app
$app
$app
$app
protect
escape
-> (new AcmeHelloServiceProvider(), array(
'hello.default_name' => 'Mary',
));
->get('/hello', function () use ( ) {
$name = ['request']->get('name');
return ['hello']($name);
});
$app
$app $app
$app
$app
register
Using the provider:
Controller Providers
To load and use a controller provider, "mount" its controllers
under a path:
$app-> ('/blog', new AcmeBlogControllerProvider());mount
All controllers defined by the provider will now be available
under the /blog path.
Loading providers
Creating a provider
Providers must implement the :SilexControllerProviderInterface
interface ControllerProviderInterface
{
public function (Application );
}
connect $app
namespace Acme;
use SilexApplication;
use SilexControllerProviderInterface;
class HelloControllerProvider implements ControllerProviderInterface
{
public function connect(Application )
{
// creates a new controller based on the default route
$controllers = ['controllers_factory'];
$controllers->get('/', function (Application ) {
return ->redirect('/hello');
});
return $controllers;
}
}
$app
$app
$app
$app
The connect method must return an instance of
ControllerCollection. ControllerCollection is the class
where all controller related methods are defined
(like get, post, match, ...).
Using:
$app-> ('/blog', new AcmeHelloControllerProvider());mount
$app-> (new AcmeDatabaseServiceProvider());register
$app-> (new AcmeDatabaseServiceProvider(), array(
'database.dsn' => 'mysql:host=localhost;dbname=mydb’,
'database.user' => 'root',
‘database.password' => 'secret_root_password',
));
register
It is possible to provide some parameters as a second
argument. These will be set after the provider is
registered, but before it is booted:
E.g.:
Doctrine Service Provider
Only Doctrine DBAL.
An ORM service
is not supplied
db.options
db
db.config
db.event_manager
Parameters
Services
$app-> (new ,
array(
'db.options' => array(
‘driver' => 'pdo_sqlite',
'path' => __DIR__.'/app.db',
),
));
register SilexProviderDoctrineServiceProvider()
Registering
$app $app
$app
->get('/blog/{id}', function ($id) use ( ) {
$sql = "SELECT * FROM posts WHERE id = ?";
$post = ['db']-> ($sql, array((int) $id));
return "<h1>{$post['title']}</h1>".
“<p>{$post['body']}</p>";
});
fetchAssoc
Usage
Using multiple databases
$app-> (new ,
array(
'dbs.options' => array (
'mysql_read' => array(
'driver' => 'pdo_mysql',
'host' => 'mysql_read.someplace.tld',
'dbname' => 'my_database',
'user' => 'my_username',
'password' => 'my_password',
'charset' => 'utf8',
),
'mysql_write' => array(
'driver' => 'pdo_mysql',
'host' => 'mysql_write.someplace.tld',
'dbname' => 'my_database',
'user' => 'my_username',
'password' => 'my_password',
'charset' => 'utf8',
),
),
));
register SilexProviderDoctrineServiceProvider()
$app
$app
['db']->fetchAll('SELECT * FROM table');
['dbs']['mysql_read']->fetchAll('SELECT * FROM table');
The first registered connection is the default, so the lines
below are equivalent:
$app $app
$app
$app
->get('/blog/{id}', function ($id) use ( ) {
$sql = "SELECT * FROM posts WHERE id = ?";
$post = ['dbs']['mysql_read']-> (
$sql,
array((int) $id)
);
$sql = "UPDATE posts SET value = ? WHERE id = ?";
['dbs']['mysql_write']-> (
$sql,
array('newValue', (int) $id)
);
return "<h1>{$post['title']}</h1>".
"<p>{$post['body']}</p>";
});
fetchAssoc
executeUpdate
Using multiple connections:
Included Providers
DoctrineServiceProvider
MonologServiceProvider
SessionServiceProvider
SerializerServiceProvider
SwiftmailerServiceProvider
TwigServiceProvider
TranslationServiceProvider
UrlGeneratorServiceProvider
ValidatorServiceProvider
HttpCacheServiceProvider
FormServiceProvider
SecurityServiceProvider
RememberMeServiceProvider
ServiceControllerServiceProvider
Providers available in the namespace
:
SilexProvider
(https://github.com/silexphp/Silex-Providers)
Array of Doctrine DBAL options.
These options are available:
The database driver to use.
Can be: pdo_mysql, pdo_sqlite,
pdo_pgsql, pdo_oci, oci8, ibm_db2,
pdo_ibm, pdo_sqlsrv
Name of the database
Host of the database.
(default: pdo_mysql)
(default: localhost)
driver
dbname
host
User of the database.
Password of the database
(default: root)
Only relevant for pdo_mysql, and
pdo_oci/oci8, specifies the charset used
when connecting to the database
Only relevant for pdo_sqlite, specifies
the path to the SQLite database
Specifies the port of the database.
Only relevant for pdo_mysql, pdo_pgsql,
and pdo_oci/oci8
user
password
charset
path
port
The database connection, instance of
Configuration object for Doctrine.
Event Manager for Doctrine
DoctrineDBALConnection
(default: empty DoctrineDBALConfiguration)
Integration with the Doctrine DBAL for easy database access
Monolog Service Provider
monolog.logfile
monolog.bubble
monolog.permission
monolog.level
monolog.name
Parameters
Services
Registering
monolog
monolog.listener
$app-> (new ,
array(
‘monolog.logfile' => __DIR__.'/dev.log',
));
register SilexProviderMonologServiceProvider()
->post('/user', function () use ($app) {
// ...
['monolog']-> (sprintf("User '%s' registered.",
$username));
return new Response('', 201);
});
$app
$app addInfo
Usage
It is possible to configure Monolog
(like adding or changing the handlers)
before using it by extending the monolog service:
$app $app $app
$app
['monolog'] = -> ( -> ('monolog',
function($monolog, ) {
$monolog-> (...);
return $monolog;
}));
share extend
pushHandler
Customization
Traits
log
$app-> (sprintf("User '%s' registered.", $username));log
File where logs are written to
Whether the messages that are handled
can bubble up the stack or not
File permissions default,
nothing change
Level of logging, defaults to DEBUG.
Must be one of:
(log everything),
(log everything except
DEBUG),
.
In addition to the constants,
it is also possible to supply the level
in string form, e.g.: “ ", " ",
“ ", " "
Name of the monolog
channel
Logger::DEBUG
Logger::INFO
Logger::WARNING,
Logger::ERROR
Logger::
DEBUG INFO
WARNING ERROR
- optional
*
*
*
*
*
The monolog logger instance
E.g.:
An event listener to log requests,
responses and errors
$app['monolog']-> ('Test’);addDebug
Logs a message
Session Service Provider
Parameters
session.storage.save_path
session.storage.options
Log requests and errors and allow to add logging to app
Path for the
.
An array of options that is
passed to the constructor of
the service
In case of the default
, the
most useful options are:
NativeFileSessionHandler
session.storage
NativeSessionStorage
name
id
cookie_lifetime
cookie_path
cookie_domain
cookie_secure
cookie_httponly
The cookie name.
The session id.
Cookie lifetime
Cookie path
Cookie domain
Cookie secure (HTTPS)
Whether the cookie is http only
(default: _SESS)
efault: null)(d
Whether to simulate sessions or not
(useful when writing functional tests).
session.test
All of these are optional. Default Sessions life time
is 1800 seconds (30 minutes). To override, set
the lifetime option.
*
Service for storing data persistently between requests
Services
Registering
session
session.storage
session.storage.handler
$app-> (new );register SilexProviderSessionServiceProvider()
Instance of Symfony2's Session
Service that is used for
persistence of the session data
Service that is used by the
for data accesssession.storage
Usage
['session']-> ('user', array('username' => $username));
$user = ['session']-> ('user'))
$app
$app
set
get
Custom Session Configurations
When using a custom session configuration is necessary
to disable the by setting
to null and configure the
ini setting yourself
NativeFileSessionHandler
session.storage.handler
session.save_path
$app['session.storage.handler'] = null;
(default: null)
(default: myapp)
(default:
NativeFileSessionHandler)
(default: value of
sys_get_temp_dir())
Swiftmailer Service Provider
Parameters
Services
Registering
Usage
swiftmailer.use_spool
swiftmailer.options
$app['swiftmailer.options'] = array(
'host' => 'host',
'port' => '25',
'username' => 'username',
'password' => 'password',
'encryption' => null,
‘auth_mode' => null
);
mailer
$app-> (
new
);
register
SilexProviderSwiftmailerServiceProvider()
$app $app
$app
$app
->post('/feedback', function () use ( ) {
$request = ['request'];
$message =
->setSubject('[YourSite] Feedback')
->setFrom(array('noreply@yoursite.com'))
->setTo(array('feedback@yoursite.com'))
->setBody($request->get('message'));
['mailer']-> ($message);
return new Response('Thank you!', 201);
});
Swift_Message::newInstance()
send
Traits
mail
$app-> (Swift_Message::newInstance()
->setSubject('[YourSite] Feedback')
->setFrom(array('noreply@yoursite.com'))
->setTo(array('feedback@yoursite.com'))
->setBody($request->get('message')));
mail
Translation Service Provider
Parameters
Services
Registering
translator.domains
locale
locale_fallbacks
translator
translator.loader
translator.message_selector
$app-> (new ,
array(
'locale_fallbacks' => array('en'),
));
register SilexProviderTranslationServiceProvider()
Service for sending email through the Swift Mailer library
A boolean to specify whether or not
to use the memory spool.
An array of options for the default
SMTP-based configuration.
The following options can be set:
host
port
username
password
encryption
auth_mode
SMTP hostname.
SMTP port.
SMTP username.
SMTP password.
SMTP encryption.
SMTP authentication
mode.
(default: 'localhost')
efault: 25)
efault: empty string)
efault: empty string)
efault: null)
efault: null)
(d
(d
(d
(d
(d
The mailer instance
$message = ;
// ...
['mailer']-> ($message);
Swift_Message::newInstance()
send$app
swiftmailer.transport
swiftmailer.transport.buffer
swiftmailer.transport.authhandler
swiftmailer.transport.eventdispatcher
Sends an email
Service for translating your app into different languages
Mapping of domains/locales/messages.
Contains the translation data for all
languages and domains
Locale for the translator. Generally set
this based on some request parameter
Fallback locales for the translator.
Used when the current locale has no
messages set
- optional*
*
*
*
(default: en)
(default: en)
(default: Swift_Transport_EsmtpTransport)
Transport used for e-mail
delivery.
used by the
transport
Authentication handler
used by the transport.
Try by default:
CRAM-MD5, login,
plaintext
Internal event dispatcher
used by Swiftmailer
StreamBuffer
(default: true)
Instance of , that is
used for translation
Instance of an implementation
of the translation
Instance of
Translator
LoaderInterface
MessageSelector
(default: ArrayLoader)
Usage
$app['translator.domains'] = array(
'messages' => array(
'en' => array(
'hello' => 'Hello %name%',
'goodbye' => 'Goodbye %name%',
),
Twig Service Provider
Traits
trans
transChoice
$app
$app
-> ('Hello World');
-> ('Hello World');
trans
transChoice
twig.path
twig.templates
twig.options
twig.form.templates
Services
Registering
Usage
Traits
twig
twig.loader
$app-> (new ,
array(
'twig.path' => __DIR__.'/views',
));
register SilexProviderTwigServiceProvider()
$app $app
$app
->get('/hello/{name}', function ($name) use ( ) {
return ['twig']-> ('hello.twig', array(
'name' => $name,
));
});
render
In any Twig template, the variable refers to the
object. So you can access any service
from within your view.
E.g.: to access ,
just put this in your template:
app
Application
$app['request']->getHost()
{{ .request.host }}app
A render function is also registered to help
render another controller from a template:
{{ ( .request.baseUrl ~ '/sidebar') }}
{# or if using the UrlGeneratorServiceProvider #}
{{ (url('sidebar')) }}
render
render
app
render
return -> ('index.html', ['name' => 'Fabien']);$app render
Customization
$app $app
$app $app
['twig'] = -> (
-> ('twig', function($twig, ) {
$twig-> ('pi', 3.14);
$twig-> ('levenshtein',
new Twig_Filter_Function('levenshtein'));
return $twig;
}));
share
extend
addGlobal
addFilter
You can configure the Twig environment before using it by
extending the twig service:
$app
$app
['twig.path'] = array(__DIR__.'/../templates');
['twig.options'] = array(
'cache' => __DIR__.'/../var/cache/twig'
);
The above example will result in following routes:
• /en/hello/igor will return Hello igor
• /de/hello/igor will return Hallo igor
• /fr/hello/igor will return Bonjour igor
• /it/hello/igor will return Hello igor (fallback)
'de' => array(
'hello' => 'Hallo %name%',
'goodbye' => 'Tschüss %name%',
),
'fr' => array(
'hello' => 'Bonjour %name%',
'goodbye' => 'Au revoir %name%',
),
),
'validators' => array(
'fr' => array(
'This value should be a valid number.' =>
‘Cette valeur doit être un nombre.',
),
),
);
->get('/{_locale}/{message}/{name}',
function ($message, $name) use ( ) {
return ['translator']-> (
$message,
array('%name%' => $name)
);
});
$app
$app
$app trans
Translates the given message
Translates the given choice message
by choosing a translation according
to a number
E.g.:
Parameters
Provide integration with the Twig template engine
Path to the directory containing twig
template files (it can also be an
array of paths)
Associative array of template names
to template contents. Use this if you
want to define your templates inline
Associative array of twig options
An array of templates used to render
forms (only available when the
is enabled)FormServiceProvider
- optional
*
*
*
*
Twig_Environment
twig.path twig.templates
instance. Main way
of interacting with Twig
The loader for Twig templates which uses the
and the options.
The loader can be replaced completely
Renders a view with the given parameters
and returns a object.Response
app variable
render function
*
Services
Service for generating URLs for named routes
Usage
$app
$app
$app
->get('/', function () {
return 'welcome to the homepage';
})
-> (' ');
->get('/navigation', function () use ($app) {
return '<a href="'.
['url_generator']-> (' ').
'">Home</a>';
});
bind
generate
home
home
When using Twig, the service can be used like this:
{{ .url_generator. (' ) }}app generate home'
if you have twig-bridge as a Composer dep,
you will have access to the path() and url() functions:
{{ ('home') }}
{{ ('home') }}
{# generates the absolute url http://example.org/ #}
path
url
Traits
path
url
$app
$app
-> ('home’);
-> ('home');
path
url
Registering
$app-> (
new
);
register
SilexProviderUrlGeneratorServiceProvider()
UrlGenerator Service Provider
url_generator An instance of , using the
that is provided through
the routes service. It has a generate method,
which takes the route name as an argument,
followed by an array of route parameters
UrlGenerator
RouteCollection
Generates a path
Generates an absolute URL
Service for validating data. It is most useful when used with
the , but can also be used standaloneFormServiceProvider
Validator Service Provider
Services
Registering
validator
validator.mapping.
class_metadata_factory
validator.validator_factory
$app-> (new );register SilexProviderValidatorServiceProvider()
Instance of
Factory for metadata loaders,
which can read validation
constraint information from
classes. Defaults to
.
This means you can define a static
method on
your data class, which takes a
ClassMetadata argument.
Then you can set constraints on
this ClassMetadata instance
Factory for .
Defaults to a standard
.
Mostly used internally by the
Validator
StaticMethodLoader--
ClassMetadataFactory
loadValidatorMetadata
ConstraintValidators
ConstraintValidatorFactory
Validator
Usage
use SymfonyComponentValidatorConstraints as ;
->get('/validate/{email}', function ($email) use ( ) {
$errors = ['validator']-> ($email,
new Email());
if (count($errors) > 0) {
return (string) $errors;
}
return 'The email is valid';
});
Assert
validateValue
Assert
$app $app
$app
use SymfonyComponentValidatorConstraints as Assert;
$author = new Author();
$author->first_name = 'Fabien';
$author->last_name = 'Potencier';
$book = new Book();
$book->title = 'My Book';
$book->author = $author;
$metadata = ['validator.mapping.class_metadata_factory']
-> ('Author');
$metadata-> ('first_name',
new AssertNotBlank());
$metadata-> ('first_name',
new AssertLength(array('min' => 10)));
$metadata-> ('last_name',
new AssertLength(array('min' => 10)));
$metadata = ['validator.mapping.class_metadata_factory']
-> ('Book');
$metadata-> ('title',
new AssertLength(array('min' => 10)));
$metadata-> ('author',
new AssertValid());
$errors = ['validator']-> ($book);
if (count($errors) > 0) {
foreach ($errors as $error) {
echo $error-> .' '.
$error-> ."n";
}
}else {
echo 'The author is valid';
}
$app
$app
$app
getMetadataFor
addPropertyConstraint
addPropertyConstraint
addPropertyConstraint
getMetadataFor
addPropertyConstraint
addPropertyConstraint
validate
getPropertyPath()
getMessage()
Validating Objects
Validating Values
Translation
$app['translator.domains'] = array(
'validators' => array(
'fr' => array(
'This value should be a valid number.' =>
'Cette valeur doit être un nombre.',
)
));
Usage
Traits
form.secret
Registering
$app-> (new );register FormServiceProvider()
$app $app
$app
->match('/form', function (Request $req) use ( ) {
// default data for when the form is displayed the first time
$data = array(
'name' => 'Your name',
'email' => 'Your email',
);
$form = ['form.factory']-> ('form', $data)
->add('name')
->add('email')
->add('gender', 'choice', array(
'choices' => array(1 => 'male', 2 => 'female'),
'expanded' => true,
))
->getForm();
createBuilder
form
$app-> ($data);form
HttpCache Service Provider
Parameters
Services
Registering
Usage
http_cache.cache_dir
http_cache.options
http_cache
http_cache.esi
http_cache.store
$app-> (new ,
array(
'http_cache.cache_dir' => __DIR__.'/cache/',
));
register SilexProviderHttpCacheServiceProvider()
->get('/', function() {
return new Response('Foo', 200, array(
' ' => 's-maxage=5',
));
});
$app
Cache-Control
Parameters
Service for building forms with the Symfony2 Form
component
Form Service Provider
This secret value is used for generating
and validating the CSRF token for a
specific page. It is very important to
set this value to a static randomly
generated value, to prevent hijacking
of your forms
(default:
md5(__DIR__))
Services
form.factory
form.csrf_provider
Instance of , that
is used for build a form
Instance of an
implementation of the
FormFactory
CsrfProviderInterface
(default:
DefaultCsrfProvider)
$form->handleRequest($req);
if ($form->isValid()) {
$data = $form->getData();
// do something with the data
// redirect somewhere
return ->redirect('...');
}
// display the form
return ['twig']->render('index.twig', array(
'form' => $form->
));
});
$app
$app
createView()
Creates a FormBuilder instance
Provides support for the Symfony2 Reverse Proxy
Cache directory to store the HTTP
cache data
An array of options for the
constructorHttpCache
- optional*
*
Instance of
Instance of , that implements the ESI
capabilities to and
instances
Instance of , that implements all
the logic for storing cache metadata
( and headers)
HttpCache
Esi
Request Response
Store
Request Response
If you want Silex to trust the
headers from your reverse proxy at address $ip,
you will need to whitelist it as documented in
Trusting Proxies. If you would be running Varnish in
front of your app on the same machine:
X-Forwarded-For*
Request::setTrustedProxies(array('127.0.0.1', '::1'));
->run();$app
Using Symfony2 reverse proxy natively
(with http_cache service)
Request::setTrustedProxies(array('127.0.0.1'));
[' ']->run();$app http_cache
The Symfony2 reverse proxy acts much like any other proxy
would, so whitelist it:
Disabling ESI
$app-> (new ,
array(
'http_cache.cache_dir' => __DIR__.'/cache/',
' ' => ,
));
register SilexProviderHttpCacheServiceProvider()
http_cache.esi null
HttpFragment Service Provider
Parameters
Services
Registering
Usage
Allows to embed fragments of HTML in a template
Symfony 2.4+
fragment.path
uri_signer.secret
fragment.renderers.
hinclude.global_template
fragment.handler
fragment.renderers
$app-> (new
);
register
SilexProviderHttpFragmentServiceProvider()
The main page content.
{{ ('/foo') }}
The main page content resumes here.
render
Using Twig for your templates:
Security Service Provider
Parameters
Services
Registering
Usage
security.hide_user_not_found
Manages authentication and authorization for apps
security
security.
authentication_manager
security.access_manager
security.session_strategy
security.user_checker
security.last_error
security.encoder_factory
security.encoder.digest
$app-> (new SilexProviderSecurityServiceProvider(),
array(
'security.firewalls' => // see below
));
register
The security features are only available after the
has been booted. So, to use it outside
of the handling of a request, call first:
Application
boot()
$app->boot();
// Current user
$token = ['security']-> ;
if (null !== $token) {
$user = $token-> ;
}
$app getToken()
getUser()
// Securing a Path with HTTP Authentication
// Find the encoder for a UserInterface instance
// Compute the encoded password for foo
// Checking User Roles
// Allowing Anonymous Users
['security.firewalls'] = array(
'admin' => array(
'pattern' => '^/admin',
'http' => true,
'users' => array(
// raw password is foo
'admin' => array('ROLE_ADMIN',
'5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsYQ8t+a8...'),
),
),
);
$encoder = ['security.encoder_factory']-> ($user);
$password = $encoder-> ('foo', $user-> ;
if ( ['security']-> ('ROLE_ADMIN')) {
// ...
}
['security.firewalls'] = array(
'unsecured' => array(
'anonymous' => true,
// ...
),
);
$app
$app
$app
$app
getEncoder
encodePassword getSalt())
isGranted
Path to use for the URL generated
for ESI and HInclude URLs
Secret to use for the URI signer
service (used for the HInclude
renderer)
Content or Twig template to use
for the default content when using
the HInclude renderer
(default:
/_fragment)
Instance of
Array of fragment renderers
(by default, the inline, ESI, and HInclude
renderers are pre-configured)
FragmentHandler
Defines whether to hide user
not found exception or not(default: true)
- optional*
*
Main entry point for the security
provider. Use it to get the current
user token
Instance of
,
responsible for authentication
Instance of
,
responsible for authorization
Define the session strategy used
for authentication (default to a
migration strategy)
Checks user flags after
authentication
Returns the last authentication
errors when given a object
Defines the encoding strategies
for user passwords (default to use
a digest algorithm for all users)
The encoder to use by default for
all users
AuthenticationProviderManager
AccessDecisionManager
Request
RememberMe Service Provider
Registering
Adds "Remember-Me" authentication to the
SecurityServiceProvider
$app
$app
$app
-> (new );
-> (new );
['security.firewalls'] = array(
'my-firewall' => array(
'pattern' => '^/secure$',
'form' => true,
'logout' => true,
'remember_me' => array(
'key' => 'Choose_A_Unique_Random_Key',
'always_remember_me' => true,
),
'users' => array( /* ... */ ),
),
);
register SilexProviderSecurityServiceProvider()
register SilexProviderRememberMeServiceProvider()
key
name
lifetime
path
domain
Options
Serializer Service Provider
Provides a serializer service
serializer
serializer.encoders
serializer.normalizers
Services
$app-> (new );register SilexProviderSerializerServiceProvider()
Registering
= new Application();
->register(new );
// only accept content types supported by the serializer
// via the assert method
->get("/pages/{id}.{_format}", function ($id) use ( ) {
// assume a page_repository service exists that returns Page
$app
$app
$app $app
SerializerServiceProvider()
// objects. Object returned has getters/setters exposing state
$page = ['page_repository']->find($id);$app
Usage
ServiceController Service Provider
Controllers can be created as services, providing the full
power of dependency injection and lazy loading
Registering
$app-> (
new );
register
SilexProviderServiceControllerServiceProvider()
use SilexApplication;
use DemoRepositoryPostRepository;
= new Application();
['posts.repository'] = -> (function() {
return new PostRepository;
});
->get('/posts.json', function() use ( ) {
return $app->json( ['posts.repository']->findAll());
});
$app
$app $app
$app $app
$app
share
Usage
Traits
user
encodePassword
secure
$user = -> ();
$encoded = -> ($user, 'foo');
->get('/', function () {
// do something but only for admins
})-> ('ROLE_ADMIN');
$app
$app
$app
user
encodePassword
secure
Returns the current user
Encode a given password
Secures a controller for the given roles
Secret key to generate tokens (you should
generate a random string)
Cookie name
Cookie lifetime
Cookie path
Cookie domain
(default: REMEMBERME)
(default: 31536000 ~ 1 year)
(default: /)
(default: null = request domain)
secure
httponly
always_remember_me
remember_me_parameter
(default: false)
(default: true)
(default: false)
(default: _remember_me)
Cookie is secure
Cookie is HTTP only
Enable remember me
Name of the request parameter
enabling remember_me on login.
/posts.json route will use a controller that is defined as a
service
$app $app $app
$app
$app
[' '] = -> (function() use ( ) {
return new PostController( ['posts.repository']);
});
->get('/posts.json', " ");
posts.controller share
posts.controller:indexJsonAction
Define the controller as a service:
$format = ['request']->getRequestFormat();
if (!$page instanceof Page) {
->abort("No page found for id: $id");
}
return new Response(
['serializer']-> ($page, $format), 200,
array(
"Content-Type" => ['request']->getMimeType($format)
));
})->assert("_format", "xml|json")
->assert("id", "d+");
$app
$app
$app
$app
serialize
and
and
SymfonyComponentSerializerSerializer
SymfonyComponentSerializer
EncoderJsonEncoder
SymfonyComponentSerializer
EncoderXmlEncoder
SymfonyComponentSerializer
NormalizerCustomNormalizer
SymfonyComponentSerializer
NormalizerGetSetMethodNormalizer

More Related Content

What's hot

Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stackPaul Bearne
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn Wilker
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkVance Lucas
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful CodeGreggPollack
 
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Caldera Labs
 
AngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro FrameworkAngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro FrameworkBackand Cohen
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCalderaLearn
 
Using the Features API
Using the Features APIUsing the Features API
Using the Features APIcgmonroe
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
How to develop modern web application framework
How to develop modern web application frameworkHow to develop modern web application framework
How to develop modern web application frameworktechmemo
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 

What's hot (20)

Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stack
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-Framework
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
 
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
 
AngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro FrameworkAngularJS with Slim PHP Micro Framework
AngularJS with Slim PHP Micro Framework
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW Workshop
 
Complex Sites with Silex
Complex Sites with SilexComplex Sites with Silex
Complex Sites with Silex
 
Using the Features API
Using the Features APIUsing the Features API
Using the Features API
 
Zend framework
Zend frameworkZend framework
Zend framework
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
How to develop modern web application framework
How to develop modern web application frameworkHow to develop modern web application framework
How to develop modern web application framework
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 

Similar to Silex Cheat Sheet

Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHPHari K T
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowVrann Tulika
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Quality Use Of Plugin
Quality Use Of PluginQuality Use Of Plugin
Quality Use Of PluginYasuo Harada
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門lestrrat
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Anatoly Sharifulin
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframeworkRadek Benkel
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPMichael Francis
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
Getting Started with Capistrano
Getting Started with CapistranoGetting Started with Capistrano
Getting Started with CapistranoLaunchAny
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 

Similar to Silex Cheat Sheet (20)

Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Quality Use Of Plugin
Quality Use Of PluginQuality Use Of Plugin
Quality Use Of Plugin
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTP
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Getting Started with Capistrano
Getting Started with CapistranoGetting Started with Capistrano
Getting Started with Capistrano
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 

Recently uploaded

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 

Recently uploaded (20)

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

Silex Cheat Sheet

  • 2. Usage Apache // web/index.php require_once __DIR__.'/../vendor/autoload.php'; = new ; ->get('/hello/{name}', function ($name) use ( ) { return 'Hello ' . ->escape($name); }); ->run(); $app SilexApplication() $app $app $app $app Install $ composer require silex/silex:~1.2 Web Server Configuration <IfModule mod_rewrite.c> Options -MultiViews RewriteEngine On #RewriteBase /path/to/app RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] </IfModule> If your site is not at the webroot level: uncomment the statement and adjust the path to point to your directory, relative from the webroot. RewriteBase For Apache 2.2.16+, you can use the FallbackResource directive: FallbackResource /index.php server { #site root is redirected to the app boot script location = / { try_files @site @site; } # all other locations try other files first and go to our # front controller if none of them exists location / { try_files $uri $uri/ @site; } #return 404 for all php files as we do have a front controller 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; #uncomment when running via https #fastcgi_param HTTPS on; } } nginx IIS <?xml version="1.0"?> <configuration> <system.webServer> <defaultDocument> <files> <clear /> <add value="index.php" /> </files> </defaultDocument> <rewrite> <rules> <rule name="Silex Front Controller" stopProcessing="true"> <match url="^(.*)$" ignoreCase="false" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" /> </conditions> <action type="Rewrite" url="index.php" appendQueryString="true" /> </rule> </rules> </rewrite> </system.webServer> </configuration> server.document-root = "/path/to/app" url.rewrite-once = ( # configure some static files "^/assets/.+" => "$0", "^/favicon.ico$" => "$0", "^(/[^?]*)(?.*)?" => "/index.php$1$2" ) Lighttpd web.config file: simple-vhost: configure your vhost to forward non-existent resources to index.php: Allows run silex without any configuration. However, in order to serve static files, you'll have to make sure your front controller returns false in that case ( ):web/index.php $filename = __DIR__.preg_replace('#(?.*)$#', '', $_SERVER['REQUEST_URI']); if (php_sapi_name() === 'cli-server' && is_file($filename)) { return false; } = require __DIR__.'/../src/app.php'; ->run(); $app $app The application should be running at .http://localhost:8080 $ php -S localhost:8080 -t web web/index.php To start the server from the command-line: PHP 5.4 built-in webserver only for development!
  • 3. App Configuration false 80 443 ‘UTF-8’ ‘en’ null $app $app $app $app $app $app ['debug'] ['request.http_port'] ['request.https_port'] ['charset'] ['locale'] ['logger'] // turn on the debug mode $app['debug'] = true; If your application is hosted behind a reverse proxy at address $ip, and you want Silex to trust the X-Forwarded-For* headers, you will need to run your application like this: use SymfonyComponentHttpFoundationRequest; Request::setTrustedProxies(array($ip)); ->run();$app $app['asset_path'] = 'http://assets.examples.com'; Custom Configuration ( )Parameters {{ .asset_path }}/css/styles.cssapp $app['base_url'] = '/'; Default Configuration Using in a template (Twig) Configuration Default value Set Get $debug = ['debug'];$app Global Configuration To apply a controller setting to all controllers (a converter, a middleware, a requirement, or a default value), configure it on :$app['controllers'] $app['controllers'] ->value('id', '1') ->assert('id', 'd+') ->requireHttps() ->method('get') ->convert('id', function () {/* ... */ }) ->before(function () {/* ... */ }); Global configuration does not apply to controller providers you might mount as they have their own global configuration applied to already registered controllers and become the defaults for new controllers Symfony2 Components HttpFoundation HttpKernel Routing EventDispatcher Symfony2 components used by Silex: For Request and Response. Because we need a heart. For matching defined routes. For hooking into the HttpKernel App Helper Methods $app-> ('/account );redirect ' $subRequest = Request::create('/hi', 'GET'); -> ($subRequest, HttpKernelInterface::SUB_REQUEST);$app handle Redirect Forward Generate the URI using :UrlGeneratorProvider $r = Request::create($app['url_generator']->generate('hi’), 'GET'); Return JSON data and apply correct escape JSON $app $app -> ($error, 404); -> ($user); json json Streaming response (when you cannot buffer the data being sent) Stream $app-> ($stream, 200, array('Content-Type' => 'image/png'));stream To send chunks, make sure to call ob_flush and flush after every chunk: $stream = function () { $fh = fopen('http://www.example.com/', 'rb'); while (!feof($fh)) { echo fread($fh, 1024); ob_flush(); flush(); } fclose($fh); }; Sending a file $app-> ('/base/path/' . $path) ->setContentDisposition( ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'pic.jpg') sendFile HttpFoundation 2.2+ Create a BinaryFileResponse $app-> ($name)escape Escape Escape user input, to prevent Cross-Site-Scripting attacks Stop the request early. It actually throws an exception $app-> (404, "Book $id does not exist.");abort Abort Set $assetPath = ['asset_path'];$app Get EARLY_EVENT = 512; LATE_EVENT = -512; App Events
  • 4. Routing A route pattern consists of: Pattern -> ('/blog', function () use ($posts) { $output = ''; foreach ($posts as $post) { $output .= $post['title']; $output .= '<br />'; } return $output; }); $app get HTTP Methods $app $app -> ('/books', function ($id) { // ... }); -> ('/books/{id}', function () { // ... }); post get For Symfony Components 2.2+: explicitly enable method override HTTP method override (for PUT, DELETE, and PATCH) The current App is automatically injected to the closure thanks to the type hinting Forms in most web browsers do not directly support the use of other HTTP methods. Use a special form field named ._method <form action="/my/target/route/" method=" "> <!-- ... --> <input type="hidden" name=" " value=" " /> </form> POST _method PUT use SymfonyComponentHttpFoundationRequest; Request::enableHttpMethodParameterOverride(); ->run();$app Can be restricted via the method method $app $app $app -> ('/book’, function () { // ... }); -> ('/book', function () { // ... }) -> ('PATCH'); -> ('/book', function () { // ... }) -> ('PUT|POST'); match match match method method The order of the routes is significant. The first matching route will be used (place more generic routes at the bottom) variable part passed to the closure $app SilexApplication $app $app ->get('/blog/ ', function ( , ) use ($posts) { if (!isset($posts[$id])) { ->abort(404, "Post $id does not exist."); } $post = $posts[$id]; return "<h1>{$post['title']}</h1>" . “<p>{$post['body']}</p>"; }); {id} $id patternmethod Defines a path that points to a resource. Can include variable parts and you are able to set RegExp requirements for them One of the HTTP methods: GET, POST, PUT or DELETE. Describes the interaction with the resource Method POST GET Dynamic Route (Route Variable) $app $app -> ('/books/{id}', function ($id) { // ... }); -> ('/books/{id}', function ($id) { // ... }); put delete PUT DELETE $app-> ('/books/{id}', function ($id) { // ... }); patchPATCH Matching all Methods Default Values This will allow matching /, in which case the variable will have the value page index $app->get('/{page}', function ($page) { // ... }) -> (' ’, ' ');value page index To define a default value for any route variable call on the object: value Controller The form's method attribute must be set to when using this field: POST
  • 5. Route Variables Converters $app->get('/user/{id}', function ($id) { // ... })-> ('id', function ($id) {return (int) $id; });convert Appling some converters before injecting route variables into the controller: Converting route variables to objects $userProvider = function ($id) { return new User($id); }; ->get('/user/{user}/edit', function (User $user) { // ... })-> ('user', $userProvider); $app convert The converter callback also receives the as its second argument: Request $callback = function ($post, Request $req) { return new Post($req->attributes->get('slug')); }; ->get('/blog/{id}/{slug}', function (Post $post) { // ... })-> ('post', $callback); $app convert Converter defined as a service use DoctrineCommonPersistenceObjectManager; use SymfonyComponentHttpKernelExceptionNotFoundHttpException; class UserConverter { private $om; public function __construct(ObjectManager $om) { $this->om = $om; } public function convert($id) { if (null === $user = $this->om->find('User', (int) $id)) { throw new NotFoundHttpException( sprintf('User %d does not exist', $id) ); } return $user; } } The service will now be registered in the app, and the convert method will be used as converter: E.g.: user converter based on Doctrine ObjectManager: $app $app ['converter.user'] = $app->share(function () { return new UserConverter(); }); ->get('/user/{user}', function (User $user) { // ... })-> ('user', 'converter.user:convert');convert Requirements $app->get('/blog/{id}', function ($id) { // ... }) -> ('id', 'd+');assert $app->get('/blog/{postId}/{commentId}', function ($postId, $commentId) { // ... }) -> ('postId', 'd+') -> ('commentId', 'd+'); assert assert Chained requirements $app $app ->get('/', function () { // ... }) -> ('homepage'); ->get('/blog/{id}', function ($id) { // ... }) -> ('blog_post'); bind bind Named Routes It only makes sense to name routes if you use providers that make use of the RouteCollection $app->get('/', ' ); use SilexApplication; use SymfonyComponentHttpFoundationRequest; namespace Acme { class Foo { public function bar(Request $request, Application $app) { // ... AcmeFoo::bar' Controllers in Classes For an even stronger separation between Silex and your controllers, you can define your controllers as services Group URLs (mount) mount() prefixes all routes with the given prefix and merges them into the main Application // define controllers for a blog $blog = ['controllers_factory']; $blog->get('/', function () { return 'Blog home page'; }); $app $app['controllers_factory'] ControllerCollection is a factory that returns a new instance of . When mounting a route collection under /blog, it is not possible to define a route for the /blog URL. The shortest possible URL is /blog/. // define "global" controllers ->get('/', function () { return 'Main home page'; }); -> ('/blog', $blog); -> ('/forum', $forum); // / map to the main home page // /blog/ map to the blog home page // /forum/ map to the forum home page $app $app $app mount mount // define controllers for a forum $forum = ['controllers_factory']; $forum->get('/', function () { return 'Forum home page'; }); $app version 1.2 (a:b notation)
  • 6. Error Handlers use SymfonyComponentHttpFoundationResponse; -> (function (Exception $e, ) { return new Response('Something went terribly wrong.'); }); $app error $code use SymfonyComponentHttpFoundationResponse; -> (function (Exception $e, ) { switch ( ) { case 404: $message = 'Page not found.'; break; default: $message = 'Something went terribly wrong.'; } return new Response($message); }); $app error $code $code Check for specific errors (using ):$code As Silex ensures that the status code is set to the most appropriate one depending on the exception, setting the status on the response won't work. To overwrite the status code (which should not without a good reason), set the header: Response X-Status-Code return new Response('Error', 404 /* ignored */, array('X-Status-Code' => 200)); To restrict an error handler to only handle some Exception classes set a more specific type hint for the Closure argument: $app-> (function (LogicException $e, $code) { // this handler will only handle LogicException exceptions // and exceptions that extends LogicException }); error Silex comes with a default error handler that displays a detailed error message with the stack trace when debug is true, and a simple error message otherwise. -> (function (Exception $e, $code) use ( ) { if ( ['debug']) { return; } // ... logic to handle the error and return a Response }); $app $app $app error The error handlers are also called when you use abort to abort a request early: $app $app $app ->get('/blog/{id}', function (SilexApplication , $id) use ($posts) { if (!isset($posts[$id])) { -> (404, "Post $id does not exist."); } return new Response(...); }); abort Traits Define shortcut methods. PHP 5.4+ Almost all built-in service providers have some corresponding PHP traits. To use them, define your own class and include the traits you want: Application use SilexApplication; class MyApplication extends Application { use ApplicationTwigTrait; use ApplicationSecurityTrait; use ApplicationFormTrait; use ApplicationUrlGeneratorTrait; use ApplicationSwiftmailerTrait; use ApplicationMonologTrait; use ApplicationTranslationTrait; } To define your own Route class and use some traits: use SilexRoute; class MyRoute extends Route { use RouteSecurityTrait; } To use the newly defined route, override the setting:$app['route_class'] $app['route_class'] = 'MyRoute'; Restricting Error Handler Debug and Error Handler Use a separate error handler for . Make sure to register it before the response error handlers, because once a response is returned, the following handlers are ignored. logging Logging and Error Handler Error handlers registered via method always take precedence. To keep the nice error messages when debug is on use this: error() To register an error handler, pass a closure to the error method which takes an argument and returns a response: Exception http://silex.sensiolabs.org/ Silex documentation, examples, and download:
  • 7. Middlewares Application Middlewares $app $app-> (function (Request $req, Application ) { // ... }); before Only run for “master” request Run after the routing and security and before the controller. Before To run the middleware even if an exception is thrown early on (on a 404 or 403 error for instance), register it as an early event: $app $app-> (function (Request $req, Application ) { // ... }, ); before Application::EARLY_EVENT $app-> (function (Request $req, Response $resp) { // ... }); after After Run before the Response is sent to the client. $app-> (function (Request $req, Response $resp) { // ... // Warning: modifications to the Request or Response // will be ignored }); finish Terminate Event registered on the Symfony response event. Event registered on the Symfony terminate event. Event registered on the Symfony request event. Run after the Response has been sent to the client (like sending emails or logging). Route Middlewares Added to routes or route collections. Only triggered when the corresponding route is matched. You can also stack them: $app->get('/somewhere', function () { // ... }) -> ($before1) -> ($before2) -> ($after1) -> ($after2) ; before before after after Fired before the route callback, but after the before application middlewares: Before $before = function (Request $req, Application ) { // ... }; ->get('/somewhere', function () { // ... }) -> ($before); $app $app before Fired after the route callback, but before the application after application middlewares: After $after = function (Request $req, Response $resp, Application ) { // ... }; ->get('/somewhere', function () { // ... }) -> ($after); $app $app after The middlewares are triggered in the same order they are added. To control the priority of the middleware pass an additional argument to the registration methods: $app-> (function (Request $req) { // ... }, ); before 32 Middlewares Priority As a convenience, two constants allow you to register an event as early as possible or as late as possible: $app $app -> (function (Request $req) { // ... }, ); -> (function (Request $req) { // ... }, ); before Application::EARLY_EVENT before Application::LATE_EVENT If a before middleware returns a Response object, the Request handling is short-circuited (the next middlewares won't be run, nor the route callback), and the Response is passed to the after middlewares right away: Short-circuiting the Controller $app-> (function (Request $req) { // redirect the user to the login screen if access // to the Resource is protected if (...) { return new RedirectResponse('/login'); } }); before If a before middleware does not return a Response or null, a is thrown.RuntimeException
  • 8. Services Silex use (extends) Pimple for DI Definition closurearray $app['some_service'] = function () { return new Service(); }; Retrieve the service: $service = ['some_service'];$app Every time is called, a new instance of the service is created. $app['some_service'] Shared Services Use the same instance of a service across all of your code. Create the service on first invocation, and then return the existing instance on any subsequent access. $app $app['some_service'] = -> (function () { return new Service(); }); share Access Container from Closure Access the service container from within a service definition closure. For example when fetching services the current service depends on. $app $app $app $app ['some_service'] = function ( ) { return new Service( ['some_other_service'], ['some_service.config']); }; also works for shared services some_service depends on some_other_service $app $app $app $app $app ['user.persist_path'] = '/tmp/users'; ['user.persister'] = -> (function ( ) { return new JsonUserPersister( ['user.persist_path']); }); share Protected Closures The container sees closures as factories for services, so it will always execute them when reading them. In some cases you will however want to store a closure as a parameter, so that you can fetch it and execute it yourself -- with your own arguments. This is why Pimple allows to protect closures from being executed, by using the method:protect $app $app $app ['closure_parameter'] = -> (function ($a, $b) { return $a + $b; }); // will not execute the closure $add = ['closure_parameter']; // calling it now echo $add(2, 3); protect protected closures do not get access to the container Core Services Current request object (instance of ). It gives access to GET, POST parameters and lots more! E.g.: Only available when a request is being served, you can only access it from within a controller, an application before/after middlewares, or an error handler. that is used internally. You can add, modify, and read routes. that is used internally. that is used internally. It is the core of the Symfony2 system and is used quite a bit by Silex. that is used internally. It takes care of executing the controller with the right arguments. Request $id = ['request']->get('id'); RouteCollection SilexControllerCollection EventDispatcher ControllerResolver $app HttpKernel Request Response UrlGenerator error() ['exception_handler']->disable() PsrLogLoggerInterface MonologServiceProvider SymfonyComponentHttpKernel LogLoggerInterface that is used internally. Is the heart of Symfony2, it takes a as input and returns a as output Simplified representation of the request that is used by the Router and the Default handler that is used when you don't register one via the method or if the handler does not return a Response. Disable it with . instance. By default, logging is disabled as the value is set to null. To enable logging either use the or define your own logger service that conforms to the PSR logger interface. In versions of Silex before 1.1 this must be a . $app request_context request routes controllers dispatcher resolver are shared $app $app['asset_path'] = -> (function () { // logic to determine the asset path return 'http://assets.examples.com'; }); share Define the service: kernel exception_handler logger E.g. 2: E.g. 3:
  • 9. Providers Service Providers Allow to reuse parts of an application into another one In order to load and use a service provider, register it on the application: Loading providers Creating a provider Providers must implement the :SilexServiceProviderInterface interface ServiceProviderInterface { public function (Application ); public function (Application ); } register boot $app $app define services on the application which then may make use of other services and parameters register() Just create a new class that implements the two methods: configure the application, just before it handles a request boot() namespace Acme; use SilexApplication; use SilexServiceProviderInterface; class HelloServiceProvider implements ServiceProviderInterface { public function register(Application ) { ['hello'] = -> (function ($name) use ( ){ $default = ['hello.default_name'] ? ['hello.default_name'] : ‘'; $name = $name ?: $default; return 'Hello ' . -> ($name); }); } public function boot(Application ) { } } $app $app $app $app $app $app $app $app protect escape -> (new AcmeHelloServiceProvider(), array( 'hello.default_name' => 'Mary', )); ->get('/hello', function () use ( ) { $name = ['request']->get('name'); return ['hello']($name); }); $app $app $app $app $app register Using the provider: Controller Providers To load and use a controller provider, "mount" its controllers under a path: $app-> ('/blog', new AcmeBlogControllerProvider());mount All controllers defined by the provider will now be available under the /blog path. Loading providers Creating a provider Providers must implement the :SilexControllerProviderInterface interface ControllerProviderInterface { public function (Application ); } connect $app namespace Acme; use SilexApplication; use SilexControllerProviderInterface; class HelloControllerProvider implements ControllerProviderInterface { public function connect(Application ) { // creates a new controller based on the default route $controllers = ['controllers_factory']; $controllers->get('/', function (Application ) { return ->redirect('/hello'); }); return $controllers; } } $app $app $app $app The connect method must return an instance of ControllerCollection. ControllerCollection is the class where all controller related methods are defined (like get, post, match, ...). Using: $app-> ('/blog', new AcmeHelloControllerProvider());mount $app-> (new AcmeDatabaseServiceProvider());register $app-> (new AcmeDatabaseServiceProvider(), array( 'database.dsn' => 'mysql:host=localhost;dbname=mydb’, 'database.user' => 'root', ‘database.password' => 'secret_root_password', )); register It is possible to provide some parameters as a second argument. These will be set after the provider is registered, but before it is booted: E.g.:
  • 10. Doctrine Service Provider Only Doctrine DBAL. An ORM service is not supplied db.options db db.config db.event_manager Parameters Services $app-> (new , array( 'db.options' => array( ‘driver' => 'pdo_sqlite', 'path' => __DIR__.'/app.db', ), )); register SilexProviderDoctrineServiceProvider() Registering $app $app $app ->get('/blog/{id}', function ($id) use ( ) { $sql = "SELECT * FROM posts WHERE id = ?"; $post = ['db']-> ($sql, array((int) $id)); return "<h1>{$post['title']}</h1>". “<p>{$post['body']}</p>"; }); fetchAssoc Usage Using multiple databases $app-> (new , array( 'dbs.options' => array ( 'mysql_read' => array( 'driver' => 'pdo_mysql', 'host' => 'mysql_read.someplace.tld', 'dbname' => 'my_database', 'user' => 'my_username', 'password' => 'my_password', 'charset' => 'utf8', ), 'mysql_write' => array( 'driver' => 'pdo_mysql', 'host' => 'mysql_write.someplace.tld', 'dbname' => 'my_database', 'user' => 'my_username', 'password' => 'my_password', 'charset' => 'utf8', ), ), )); register SilexProviderDoctrineServiceProvider() $app $app ['db']->fetchAll('SELECT * FROM table'); ['dbs']['mysql_read']->fetchAll('SELECT * FROM table'); The first registered connection is the default, so the lines below are equivalent: $app $app $app $app ->get('/blog/{id}', function ($id) use ( ) { $sql = "SELECT * FROM posts WHERE id = ?"; $post = ['dbs']['mysql_read']-> ( $sql, array((int) $id) ); $sql = "UPDATE posts SET value = ? WHERE id = ?"; ['dbs']['mysql_write']-> ( $sql, array('newValue', (int) $id) ); return "<h1>{$post['title']}</h1>". "<p>{$post['body']}</p>"; }); fetchAssoc executeUpdate Using multiple connections: Included Providers DoctrineServiceProvider MonologServiceProvider SessionServiceProvider SerializerServiceProvider SwiftmailerServiceProvider TwigServiceProvider TranslationServiceProvider UrlGeneratorServiceProvider ValidatorServiceProvider HttpCacheServiceProvider FormServiceProvider SecurityServiceProvider RememberMeServiceProvider ServiceControllerServiceProvider Providers available in the namespace : SilexProvider (https://github.com/silexphp/Silex-Providers) Array of Doctrine DBAL options. These options are available: The database driver to use. Can be: pdo_mysql, pdo_sqlite, pdo_pgsql, pdo_oci, oci8, ibm_db2, pdo_ibm, pdo_sqlsrv Name of the database Host of the database. (default: pdo_mysql) (default: localhost) driver dbname host User of the database. Password of the database (default: root) Only relevant for pdo_mysql, and pdo_oci/oci8, specifies the charset used when connecting to the database Only relevant for pdo_sqlite, specifies the path to the SQLite database Specifies the port of the database. Only relevant for pdo_mysql, pdo_pgsql, and pdo_oci/oci8 user password charset path port The database connection, instance of Configuration object for Doctrine. Event Manager for Doctrine DoctrineDBALConnection (default: empty DoctrineDBALConfiguration) Integration with the Doctrine DBAL for easy database access
  • 11. Monolog Service Provider monolog.logfile monolog.bubble monolog.permission monolog.level monolog.name Parameters Services Registering monolog monolog.listener $app-> (new , array( ‘monolog.logfile' => __DIR__.'/dev.log', )); register SilexProviderMonologServiceProvider() ->post('/user', function () use ($app) { // ... ['monolog']-> (sprintf("User '%s' registered.", $username)); return new Response('', 201); }); $app $app addInfo Usage It is possible to configure Monolog (like adding or changing the handlers) before using it by extending the monolog service: $app $app $app $app ['monolog'] = -> ( -> ('monolog', function($monolog, ) { $monolog-> (...); return $monolog; })); share extend pushHandler Customization Traits log $app-> (sprintf("User '%s' registered.", $username));log File where logs are written to Whether the messages that are handled can bubble up the stack or not File permissions default, nothing change Level of logging, defaults to DEBUG. Must be one of: (log everything), (log everything except DEBUG), . In addition to the constants, it is also possible to supply the level in string form, e.g.: “ ", " ", “ ", " " Name of the monolog channel Logger::DEBUG Logger::INFO Logger::WARNING, Logger::ERROR Logger:: DEBUG INFO WARNING ERROR - optional * * * * * The monolog logger instance E.g.: An event listener to log requests, responses and errors $app['monolog']-> ('Test’);addDebug Logs a message Session Service Provider Parameters session.storage.save_path session.storage.options Log requests and errors and allow to add logging to app Path for the . An array of options that is passed to the constructor of the service In case of the default , the most useful options are: NativeFileSessionHandler session.storage NativeSessionStorage name id cookie_lifetime cookie_path cookie_domain cookie_secure cookie_httponly The cookie name. The session id. Cookie lifetime Cookie path Cookie domain Cookie secure (HTTPS) Whether the cookie is http only (default: _SESS) efault: null)(d Whether to simulate sessions or not (useful when writing functional tests). session.test All of these are optional. Default Sessions life time is 1800 seconds (30 minutes). To override, set the lifetime option. * Service for storing data persistently between requests Services Registering session session.storage session.storage.handler $app-> (new );register SilexProviderSessionServiceProvider() Instance of Symfony2's Session Service that is used for persistence of the session data Service that is used by the for data accesssession.storage Usage ['session']-> ('user', array('username' => $username)); $user = ['session']-> ('user')) $app $app set get Custom Session Configurations When using a custom session configuration is necessary to disable the by setting to null and configure the ini setting yourself NativeFileSessionHandler session.storage.handler session.save_path $app['session.storage.handler'] = null; (default: null) (default: myapp) (default: NativeFileSessionHandler) (default: value of sys_get_temp_dir())
  • 12. Swiftmailer Service Provider Parameters Services Registering Usage swiftmailer.use_spool swiftmailer.options $app['swiftmailer.options'] = array( 'host' => 'host', 'port' => '25', 'username' => 'username', 'password' => 'password', 'encryption' => null, ‘auth_mode' => null ); mailer $app-> ( new ); register SilexProviderSwiftmailerServiceProvider() $app $app $app $app ->post('/feedback', function () use ( ) { $request = ['request']; $message = ->setSubject('[YourSite] Feedback') ->setFrom(array('noreply@yoursite.com')) ->setTo(array('feedback@yoursite.com')) ->setBody($request->get('message')); ['mailer']-> ($message); return new Response('Thank you!', 201); }); Swift_Message::newInstance() send Traits mail $app-> (Swift_Message::newInstance() ->setSubject('[YourSite] Feedback') ->setFrom(array('noreply@yoursite.com')) ->setTo(array('feedback@yoursite.com')) ->setBody($request->get('message'))); mail Translation Service Provider Parameters Services Registering translator.domains locale locale_fallbacks translator translator.loader translator.message_selector $app-> (new , array( 'locale_fallbacks' => array('en'), )); register SilexProviderTranslationServiceProvider() Service for sending email through the Swift Mailer library A boolean to specify whether or not to use the memory spool. An array of options for the default SMTP-based configuration. The following options can be set: host port username password encryption auth_mode SMTP hostname. SMTP port. SMTP username. SMTP password. SMTP encryption. SMTP authentication mode. (default: 'localhost') efault: 25) efault: empty string) efault: empty string) efault: null) efault: null) (d (d (d (d (d The mailer instance $message = ; // ... ['mailer']-> ($message); Swift_Message::newInstance() send$app swiftmailer.transport swiftmailer.transport.buffer swiftmailer.transport.authhandler swiftmailer.transport.eventdispatcher Sends an email Service for translating your app into different languages Mapping of domains/locales/messages. Contains the translation data for all languages and domains Locale for the translator. Generally set this based on some request parameter Fallback locales for the translator. Used when the current locale has no messages set - optional* * * * (default: en) (default: en) (default: Swift_Transport_EsmtpTransport) Transport used for e-mail delivery. used by the transport Authentication handler used by the transport. Try by default: CRAM-MD5, login, plaintext Internal event dispatcher used by Swiftmailer StreamBuffer (default: true) Instance of , that is used for translation Instance of an implementation of the translation Instance of Translator LoaderInterface MessageSelector (default: ArrayLoader) Usage $app['translator.domains'] = array( 'messages' => array( 'en' => array( 'hello' => 'Hello %name%', 'goodbye' => 'Goodbye %name%', ),
  • 13. Twig Service Provider Traits trans transChoice $app $app -> ('Hello World'); -> ('Hello World'); trans transChoice twig.path twig.templates twig.options twig.form.templates Services Registering Usage Traits twig twig.loader $app-> (new , array( 'twig.path' => __DIR__.'/views', )); register SilexProviderTwigServiceProvider() $app $app $app ->get('/hello/{name}', function ($name) use ( ) { return ['twig']-> ('hello.twig', array( 'name' => $name, )); }); render In any Twig template, the variable refers to the object. So you can access any service from within your view. E.g.: to access , just put this in your template: app Application $app['request']->getHost() {{ .request.host }}app A render function is also registered to help render another controller from a template: {{ ( .request.baseUrl ~ '/sidebar') }} {# or if using the UrlGeneratorServiceProvider #} {{ (url('sidebar')) }} render render app render return -> ('index.html', ['name' => 'Fabien']);$app render Customization $app $app $app $app ['twig'] = -> ( -> ('twig', function($twig, ) { $twig-> ('pi', 3.14); $twig-> ('levenshtein', new Twig_Filter_Function('levenshtein')); return $twig; })); share extend addGlobal addFilter You can configure the Twig environment before using it by extending the twig service: $app $app ['twig.path'] = array(__DIR__.'/../templates'); ['twig.options'] = array( 'cache' => __DIR__.'/../var/cache/twig' ); The above example will result in following routes: • /en/hello/igor will return Hello igor • /de/hello/igor will return Hallo igor • /fr/hello/igor will return Bonjour igor • /it/hello/igor will return Hello igor (fallback) 'de' => array( 'hello' => 'Hallo %name%', 'goodbye' => 'Tschüss %name%', ), 'fr' => array( 'hello' => 'Bonjour %name%', 'goodbye' => 'Au revoir %name%', ), ), 'validators' => array( 'fr' => array( 'This value should be a valid number.' => ‘Cette valeur doit être un nombre.', ), ), ); ->get('/{_locale}/{message}/{name}', function ($message, $name) use ( ) { return ['translator']-> ( $message, array('%name%' => $name) ); }); $app $app $app trans Translates the given message Translates the given choice message by choosing a translation according to a number E.g.: Parameters Provide integration with the Twig template engine Path to the directory containing twig template files (it can also be an array of paths) Associative array of template names to template contents. Use this if you want to define your templates inline Associative array of twig options An array of templates used to render forms (only available when the is enabled)FormServiceProvider - optional * * * * Twig_Environment twig.path twig.templates instance. Main way of interacting with Twig The loader for Twig templates which uses the and the options. The loader can be replaced completely Renders a view with the given parameters and returns a object.Response app variable render function *
  • 14. Services Service for generating URLs for named routes Usage $app $app $app ->get('/', function () { return 'welcome to the homepage'; }) -> (' '); ->get('/navigation', function () use ($app) { return '<a href="'. ['url_generator']-> (' '). '">Home</a>'; }); bind generate home home When using Twig, the service can be used like this: {{ .url_generator. (' ) }}app generate home' if you have twig-bridge as a Composer dep, you will have access to the path() and url() functions: {{ ('home') }} {{ ('home') }} {# generates the absolute url http://example.org/ #} path url Traits path url $app $app -> ('home’); -> ('home'); path url Registering $app-> ( new ); register SilexProviderUrlGeneratorServiceProvider() UrlGenerator Service Provider url_generator An instance of , using the that is provided through the routes service. It has a generate method, which takes the route name as an argument, followed by an array of route parameters UrlGenerator RouteCollection Generates a path Generates an absolute URL Service for validating data. It is most useful when used with the , but can also be used standaloneFormServiceProvider Validator Service Provider Services Registering validator validator.mapping. class_metadata_factory validator.validator_factory $app-> (new );register SilexProviderValidatorServiceProvider() Instance of Factory for metadata loaders, which can read validation constraint information from classes. Defaults to . This means you can define a static method on your data class, which takes a ClassMetadata argument. Then you can set constraints on this ClassMetadata instance Factory for . Defaults to a standard . Mostly used internally by the Validator StaticMethodLoader-- ClassMetadataFactory loadValidatorMetadata ConstraintValidators ConstraintValidatorFactory Validator Usage use SymfonyComponentValidatorConstraints as ; ->get('/validate/{email}', function ($email) use ( ) { $errors = ['validator']-> ($email, new Email()); if (count($errors) > 0) { return (string) $errors; } return 'The email is valid'; }); Assert validateValue Assert $app $app $app use SymfonyComponentValidatorConstraints as Assert; $author = new Author(); $author->first_name = 'Fabien'; $author->last_name = 'Potencier'; $book = new Book(); $book->title = 'My Book'; $book->author = $author; $metadata = ['validator.mapping.class_metadata_factory'] -> ('Author'); $metadata-> ('first_name', new AssertNotBlank()); $metadata-> ('first_name', new AssertLength(array('min' => 10))); $metadata-> ('last_name', new AssertLength(array('min' => 10))); $metadata = ['validator.mapping.class_metadata_factory'] -> ('Book'); $metadata-> ('title', new AssertLength(array('min' => 10))); $metadata-> ('author', new AssertValid()); $errors = ['validator']-> ($book); if (count($errors) > 0) { foreach ($errors as $error) { echo $error-> .' '. $error-> ."n"; } }else { echo 'The author is valid'; } $app $app $app getMetadataFor addPropertyConstraint addPropertyConstraint addPropertyConstraint getMetadataFor addPropertyConstraint addPropertyConstraint validate getPropertyPath() getMessage() Validating Objects Validating Values Translation $app['translator.domains'] = array( 'validators' => array( 'fr' => array( 'This value should be a valid number.' => 'Cette valeur doit être un nombre.', ) ));
  • 15. Usage Traits form.secret Registering $app-> (new );register FormServiceProvider() $app $app $app ->match('/form', function (Request $req) use ( ) { // default data for when the form is displayed the first time $data = array( 'name' => 'Your name', 'email' => 'Your email', ); $form = ['form.factory']-> ('form', $data) ->add('name') ->add('email') ->add('gender', 'choice', array( 'choices' => array(1 => 'male', 2 => 'female'), 'expanded' => true, )) ->getForm(); createBuilder form $app-> ($data);form HttpCache Service Provider Parameters Services Registering Usage http_cache.cache_dir http_cache.options http_cache http_cache.esi http_cache.store $app-> (new , array( 'http_cache.cache_dir' => __DIR__.'/cache/', )); register SilexProviderHttpCacheServiceProvider() ->get('/', function() { return new Response('Foo', 200, array( ' ' => 's-maxage=5', )); }); $app Cache-Control Parameters Service for building forms with the Symfony2 Form component Form Service Provider This secret value is used for generating and validating the CSRF token for a specific page. It is very important to set this value to a static randomly generated value, to prevent hijacking of your forms (default: md5(__DIR__)) Services form.factory form.csrf_provider Instance of , that is used for build a form Instance of an implementation of the FormFactory CsrfProviderInterface (default: DefaultCsrfProvider) $form->handleRequest($req); if ($form->isValid()) { $data = $form->getData(); // do something with the data // redirect somewhere return ->redirect('...'); } // display the form return ['twig']->render('index.twig', array( 'form' => $form-> )); }); $app $app createView() Creates a FormBuilder instance Provides support for the Symfony2 Reverse Proxy Cache directory to store the HTTP cache data An array of options for the constructorHttpCache - optional* * Instance of Instance of , that implements the ESI capabilities to and instances Instance of , that implements all the logic for storing cache metadata ( and headers) HttpCache Esi Request Response Store Request Response If you want Silex to trust the headers from your reverse proxy at address $ip, you will need to whitelist it as documented in Trusting Proxies. If you would be running Varnish in front of your app on the same machine: X-Forwarded-For* Request::setTrustedProxies(array('127.0.0.1', '::1')); ->run();$app Using Symfony2 reverse proxy natively (with http_cache service) Request::setTrustedProxies(array('127.0.0.1')); [' ']->run();$app http_cache The Symfony2 reverse proxy acts much like any other proxy would, so whitelist it: Disabling ESI $app-> (new , array( 'http_cache.cache_dir' => __DIR__.'/cache/', ' ' => , )); register SilexProviderHttpCacheServiceProvider() http_cache.esi null
  • 16. HttpFragment Service Provider Parameters Services Registering Usage Allows to embed fragments of HTML in a template Symfony 2.4+ fragment.path uri_signer.secret fragment.renderers. hinclude.global_template fragment.handler fragment.renderers $app-> (new ); register SilexProviderHttpFragmentServiceProvider() The main page content. {{ ('/foo') }} The main page content resumes here. render Using Twig for your templates: Security Service Provider Parameters Services Registering Usage security.hide_user_not_found Manages authentication and authorization for apps security security. authentication_manager security.access_manager security.session_strategy security.user_checker security.last_error security.encoder_factory security.encoder.digest $app-> (new SilexProviderSecurityServiceProvider(), array( 'security.firewalls' => // see below )); register The security features are only available after the has been booted. So, to use it outside of the handling of a request, call first: Application boot() $app->boot(); // Current user $token = ['security']-> ; if (null !== $token) { $user = $token-> ; } $app getToken() getUser() // Securing a Path with HTTP Authentication // Find the encoder for a UserInterface instance // Compute the encoded password for foo // Checking User Roles // Allowing Anonymous Users ['security.firewalls'] = array( 'admin' => array( 'pattern' => '^/admin', 'http' => true, 'users' => array( // raw password is foo 'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsYQ8t+a8...'), ), ), ); $encoder = ['security.encoder_factory']-> ($user); $password = $encoder-> ('foo', $user-> ; if ( ['security']-> ('ROLE_ADMIN')) { // ... } ['security.firewalls'] = array( 'unsecured' => array( 'anonymous' => true, // ... ), ); $app $app $app $app getEncoder encodePassword getSalt()) isGranted Path to use for the URL generated for ESI and HInclude URLs Secret to use for the URI signer service (used for the HInclude renderer) Content or Twig template to use for the default content when using the HInclude renderer (default: /_fragment) Instance of Array of fragment renderers (by default, the inline, ESI, and HInclude renderers are pre-configured) FragmentHandler Defines whether to hide user not found exception or not(default: true) - optional* * Main entry point for the security provider. Use it to get the current user token Instance of , responsible for authentication Instance of , responsible for authorization Define the session strategy used for authentication (default to a migration strategy) Checks user flags after authentication Returns the last authentication errors when given a object Defines the encoding strategies for user passwords (default to use a digest algorithm for all users) The encoder to use by default for all users AuthenticationProviderManager AccessDecisionManager Request
  • 17. RememberMe Service Provider Registering Adds "Remember-Me" authentication to the SecurityServiceProvider $app $app $app -> (new ); -> (new ); ['security.firewalls'] = array( 'my-firewall' => array( 'pattern' => '^/secure$', 'form' => true, 'logout' => true, 'remember_me' => array( 'key' => 'Choose_A_Unique_Random_Key', 'always_remember_me' => true, ), 'users' => array( /* ... */ ), ), ); register SilexProviderSecurityServiceProvider() register SilexProviderRememberMeServiceProvider() key name lifetime path domain Options Serializer Service Provider Provides a serializer service serializer serializer.encoders serializer.normalizers Services $app-> (new );register SilexProviderSerializerServiceProvider() Registering = new Application(); ->register(new ); // only accept content types supported by the serializer // via the assert method ->get("/pages/{id}.{_format}", function ($id) use ( ) { // assume a page_repository service exists that returns Page $app $app $app $app SerializerServiceProvider() // objects. Object returned has getters/setters exposing state $page = ['page_repository']->find($id);$app Usage ServiceController Service Provider Controllers can be created as services, providing the full power of dependency injection and lazy loading Registering $app-> ( new ); register SilexProviderServiceControllerServiceProvider() use SilexApplication; use DemoRepositoryPostRepository; = new Application(); ['posts.repository'] = -> (function() { return new PostRepository; }); ->get('/posts.json', function() use ( ) { return $app->json( ['posts.repository']->findAll()); }); $app $app $app $app $app $app share Usage Traits user encodePassword secure $user = -> (); $encoded = -> ($user, 'foo'); ->get('/', function () { // do something but only for admins })-> ('ROLE_ADMIN'); $app $app $app user encodePassword secure Returns the current user Encode a given password Secures a controller for the given roles Secret key to generate tokens (you should generate a random string) Cookie name Cookie lifetime Cookie path Cookie domain (default: REMEMBERME) (default: 31536000 ~ 1 year) (default: /) (default: null = request domain) secure httponly always_remember_me remember_me_parameter (default: false) (default: true) (default: false) (default: _remember_me) Cookie is secure Cookie is HTTP only Enable remember me Name of the request parameter enabling remember_me on login. /posts.json route will use a controller that is defined as a service $app $app $app $app $app [' '] = -> (function() use ( ) { return new PostController( ['posts.repository']); }); ->get('/posts.json', " "); posts.controller share posts.controller:indexJsonAction Define the controller as a service: $format = ['request']->getRequestFormat(); if (!$page instanceof Page) { ->abort("No page found for id: $id"); } return new Response( ['serializer']-> ($page, $format), 200, array( "Content-Type" => ['request']->getMimeType($format) )); })->assert("_format", "xml|json") ->assert("id", "d+"); $app $app $app $app serialize and and SymfonyComponentSerializerSerializer SymfonyComponentSerializer EncoderJsonEncoder SymfonyComponentSerializer EncoderXmlEncoder SymfonyComponentSerializer NormalizerCustomNormalizer SymfonyComponentSerializer NormalizerGetSetMethodNormalizer