This document provides information about Silex, a PHP micro-framework. It includes usage examples and configuration instructions for Silex on Apache, Nginx, IIS, and Lighttpd web servers. It also covers routing, controllers, middlewares, error handling, and other Silex features.
Everyone knows that Silex is a great microframework for APIs and small sites, but what do you do when you want to build a large site, or your little tiny site has grown up? Silex has many different ways to let you build larger, complex websites that might still be too small for Symfony, but have outgrown the single page app it once was. We’ll look at what Silex offers us, and different ways we can structure our site.
Go beyond the documentation and explore some of what's possible if you stretch symfony to its limits. We will look at a number of aspects of symfony 1.4 and Doctrine 1.2 and tease out some powerful functionality you may not have expected to find, but will doubtless be able to use. Topics covered will include routing, forms, the config cache and record listeners. If you're comfortable in symfony and wondering what's next, this session is for you.
Silex is a brand new PHP 5.3 micro framework built on top of the Symfony2 de decoupled components. In this session, we will discover how to build and deploy powerful REST web services with such a micro framework and its embedded tools.
The first part of this talk will introduce the basics of the REST architecture. We fill focus on the main concepts of REST like HTTP methods, URIs and open formats like XML and JSON.
Then, we will discover how to deploy REST services using most of interesting Silex tools like database abstraction layer, template engine and input validation. We will also look at unit and functional testing frameworks with PHPUnit and HTTP caching with Edge Side Includes and Varnish support to improve performances.
Everyone knows that Silex is a great microframework for APIs and small sites, but what do you do when you want to build a large site, or your little tiny site has grown up? Silex has many different ways to let you build larger, complex websites that might still be too small for Symfony, but have outgrown the single page app it once was. We’ll look at what Silex offers us, and different ways we can structure our site.
Go beyond the documentation and explore some of what's possible if you stretch symfony to its limits. We will look at a number of aspects of symfony 1.4 and Doctrine 1.2 and tease out some powerful functionality you may not have expected to find, but will doubtless be able to use. Topics covered will include routing, forms, the config cache and record listeners. If you're comfortable in symfony and wondering what's next, this session is for you.
Silex is a brand new PHP 5.3 micro framework built on top of the Symfony2 de decoupled components. In this session, we will discover how to build and deploy powerful REST web services with such a micro framework and its embedded tools.
The first part of this talk will introduce the basics of the REST architecture. We fill focus on the main concepts of REST like HTTP methods, URIs and open formats like XML and JSON.
Then, we will discover how to deploy REST services using most of interesting Silex tools like database abstraction layer, template engine and input validation. We will also look at unit and functional testing frameworks with PHPUnit and HTTP caching with Edge Side Includes and Varnish support to improve performances.
Laravel is a PHP MVC based framework. It is as easy as codeigniter, yet provides powerful tools needed for large robust application.It is built on top of symphony components and is inspired by many other frameworks including RoR, Asp .net, Sinatra.This session focuses on the basics things needed to start building application on it.
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
Codementor PHP expert mentor Ben Edmunds is the co-host of PHP Town Hall and author of Building Secure PHP Apps.
Ben is also the creator of Ion Auth, a simple, lightweight authentication library for CodeIgniter.
In an interactive format, Ben talked about:
Modern PHP
Latest PHP tools
SQL Injection
Password Hashing and Authentication
Other Common Hacks
https://www.codementor.io/benedmunds
https://www.codementor.io/php-tutorial/building-modern-secure-php-applications-codementor-office-hours-ben-edmunds
Like many others, WordPress has been my personal blogging tool for a long time. A powerful tool for easy publishing! That is what everyone wants.
Large sites like TechCrunch and TheNextWeb use it exactly for that reason. And more enterprises seem to discover it as good solution to their too-expensive publication tools. But keeping those WordPress instances running requires skills and knowledge.
Because of WordPress extendibility and its very active community, you can do this too. This tutorial will teach you how use Ansible, Composer, WP-CLI, WP REST API, and Elasticsearch can push WordPress from a personal blogging tool into an enterprise-worthy level application. Out with FTP based SCM ... in with automated deployment, dependency management, and utterly fast search.
The REST API is an awesome plugin to expose your data from the WordPress core. But … the standard implementation might not fit your specific case.
Just like the WordPress core, you'll be able to extend it to your specific needs. I'll show you how to handle authentication, introduce caching strategies, alter custom post types, or even change the default way of communication altogether.
Slides from my talk at the GTA-PHP Meetup Group about getting mixed HTML / PHP code into objects using SOLID principles.
Meetup page: http://www.meetup.com/GTA-PHP-User-Group-Toronto/events/230656470/
Code is on github: https://github.com/zymsys/solid
Introducing Assetic: Asset Management for PHP 5.3Kris Wallsmith
The performance of your application depends heavily on the number and size of assets on each page. Even your blazingly fastest Symfony2 application can be bogged down by bloated Javascript and CSS files. This session will give you a basic introduction to PHP's new asset management framework, Assetic, and explore how it integrates with Symfony2 for a pleasant, common sense developer experience.
The REST API is an awesome plugin to expose your data from the WordPress core. But … the standard implementation might not fit your specific case.
Just like the WordPress core, you'll be able to extend it to your specific needs. I'll show you how to handle authentication, introduce caching strategies, alter custom post types, or even change the default way of communication altogether.
Like many others, WordPress has been my personal blogging tool for a long time. A powerful tool for easy publishing! That is what everyone wants.
Large sites like TechCrunch and TheNextWeb use it exactly for that reason. And more enterprises seem to discover it as good solution to their too-expensive publication tools. But keeping those WordPress instances running requires skills and knowledge.
Because of WordPress extendibility and its very active community, you can do this too. This tutorial will teach you how use Ansible, Composer, WP-CLI, WP REST API, and Elasticsearch can push WordPress from a personal blogging tool into an enterprise-worthy level application. Out with FTP based SCM ... in with automated deployment, dependency management, and utterly fast search.
Laravel is a PHP MVC based framework. It is as easy as codeigniter, yet provides powerful tools needed for large robust application.It is built on top of symphony components and is inspired by many other frameworks including RoR, Asp .net, Sinatra.This session focuses on the basics things needed to start building application on it.
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
Codementor PHP expert mentor Ben Edmunds is the co-host of PHP Town Hall and author of Building Secure PHP Apps.
Ben is also the creator of Ion Auth, a simple, lightweight authentication library for CodeIgniter.
In an interactive format, Ben talked about:
Modern PHP
Latest PHP tools
SQL Injection
Password Hashing and Authentication
Other Common Hacks
https://www.codementor.io/benedmunds
https://www.codementor.io/php-tutorial/building-modern-secure-php-applications-codementor-office-hours-ben-edmunds
Like many others, WordPress has been my personal blogging tool for a long time. A powerful tool for easy publishing! That is what everyone wants.
Large sites like TechCrunch and TheNextWeb use it exactly for that reason. And more enterprises seem to discover it as good solution to their too-expensive publication tools. But keeping those WordPress instances running requires skills and knowledge.
Because of WordPress extendibility and its very active community, you can do this too. This tutorial will teach you how use Ansible, Composer, WP-CLI, WP REST API, and Elasticsearch can push WordPress from a personal blogging tool into an enterprise-worthy level application. Out with FTP based SCM ... in with automated deployment, dependency management, and utterly fast search.
The REST API is an awesome plugin to expose your data from the WordPress core. But … the standard implementation might not fit your specific case.
Just like the WordPress core, you'll be able to extend it to your specific needs. I'll show you how to handle authentication, introduce caching strategies, alter custom post types, or even change the default way of communication altogether.
Slides from my talk at the GTA-PHP Meetup Group about getting mixed HTML / PHP code into objects using SOLID principles.
Meetup page: http://www.meetup.com/GTA-PHP-User-Group-Toronto/events/230656470/
Code is on github: https://github.com/zymsys/solid
Introducing Assetic: Asset Management for PHP 5.3Kris Wallsmith
The performance of your application depends heavily on the number and size of assets on each page. Even your blazingly fastest Symfony2 application can be bogged down by bloated Javascript and CSS files. This session will give you a basic introduction to PHP's new asset management framework, Assetic, and explore how it integrates with Symfony2 for a pleasant, common sense developer experience.
The REST API is an awesome plugin to expose your data from the WordPress core. But … the standard implementation might not fit your specific case.
Just like the WordPress core, you'll be able to extend it to your specific needs. I'll show you how to handle authentication, introduce caching strategies, alter custom post types, or even change the default way of communication altogether.
Like many others, WordPress has been my personal blogging tool for a long time. A powerful tool for easy publishing! That is what everyone wants.
Large sites like TechCrunch and TheNextWeb use it exactly for that reason. And more enterprises seem to discover it as good solution to their too-expensive publication tools. But keeping those WordPress instances running requires skills and knowledge.
Because of WordPress extendibility and its very active community, you can do this too. This tutorial will teach you how use Ansible, Composer, WP-CLI, WP REST API, and Elasticsearch can push WordPress from a personal blogging tool into an enterprise-worthy level application. Out with FTP based SCM ... in with automated deployment, dependency management, and utterly fast search.
Standing on the shoulders of giants, Silex is a micro framework built on top of Symfony2 components. It provides an ideal environment for throwing together a simple, single file application. We’ll look at a real example of installing and setting up Silex and creating our first application with full dependency injection, templating and all the other features that you would expect of a modern day PHP framework. This session is recommended for anyone looking to break into the Symfony ecosystem with a simple introduction to a small framework build upon the core components of it’s bigger brother (Symfony2).
Talks by Carmelo Floridia, Senior Engineer (Data Processing) at BaxEnergy, at the Big Data for You event "Recommendation Systems: Talks & Workshop" (Catania, Feb. 25th, 2017).
Carmelo offers a panorama view of BaxEnergy activities, in particular about Solar power plants, on how they analyse power curves and on how they can provide a real-time monitoring service and forecasting.
Carmelo also describes the primary characteristics of Big Data and Machine Learning, and mention the Microsoft Azure Technology as the one currently used at Bax Energy.
Although one can't see this from the slides, Carmelo gave us a live demonstration of Human model learning (based on kinect)!
Dr Alan Hudd, Managing Director of Xennia, gave this talk at the 20th IMI Annual Inkjet Conference in Las Vegas, USA in Feb 2011. The talk discusses the challenges and opportunities for inkjet decoration in a number of applications, including ceramics, textiles and functional material printing for applications such as solar energy generation.
MEMS & Sensors challenges & opportunities for the next decade 2016 Presentati...Yole Developpement
MEMS & Sensors enable key functionalities…
Current battleground of the industry
MEMS is a semiconductor technology thus enabling miniaturization and lower cost manufacturing of existing products
Automotive is the historical MEMS high volume market
Transition started in 2003 towards consumer products…
After decreasing die size, improvements are now focused on packaging issues and use of through silicon vias (TSVs) for instance
Mems and sensors packaging technology and trends presentation held by Amandin...Yole Developpement
MEMS & sensors transitioning towards 3 main Hubs…
The inertial hub
Examples of MEMS companies with a «sensors integration» road (e.g., mCubewith iGyro, Spectral Engines with integrated spectrometer, Bosch with environmental combo sensors, AMS with optical combos, InvenSense with IMUs ….
Innovative MEMS technologies are spearheading the inkjet printing industry’s transformation.
From technology push to market pull, inkjet printing is entering a new era
Inkjet printing, which offers a flexible, cost-effective solution for printing personal documents, is still largely associated with home and small office printing. In parallel, large & wide format printing for CAD and graphic arts applications considers inkjet printing as its technology-of-choice for single prints and very small print runs. The democratization of digital applications in the early 2000s, spurred on by greater home internet usage and the appearance of digital cameras (which dramatically impacted the photo business), has influenced OEM printer manufacturers to develop high-quality, high-resolution printheads. MEMS technologies represent an attractive solution for creating a higher native density of nozzles-per-printheads at an acceptable manufacturing cost via mass production.
Office printing is one of the sectors that has recently benefited from MEMS printhead performance, competing with entry-level to mid-end laser printers. Moreover, the digital revolution is also gaining momentum in new sectors. For years, commercial and industrial applications have used analog printing solutions like flexography, offset printing, and screen-printing due to their high-volume production capacity and associated lower cost. However, these techniques are restrictive due to the use of a master, and not compatible with short runs < 4000m² printing surface. Today’s industrial and commercial applications require more diversity, as well as more instant service customization. Digital printing, specifically inkjet printing, is the solution to penetrating the three trillion square meters (m²) industrial market.
PHP 7 is the latest big release for PHP, in this session you’ll learn what’s new and what to expect in terms of upgrading your current code work to the new version of PHP.
iPhone applications can often benefit by talking to a web service to synchronize data or share information with a community. Ruby on Rails, with its RESTful conventions, is an ideal backend for iPhone applications. In this session you'll learn how to use ObjectiveResource in an iPhone application to interact with a RESTful web service implemented in Rails. This session isn't about how to build web applications that are served up on the iPhone. It's about how to build iPhone applications with a native look and feel that happen to talk to Rails applications under the hood. The upshot is a user experience that transcends the device.
Come to this talk prepared to learn about the Doctrine PHP open source project. The Doctrine project has been around for over a decade and has evolved from database abstraction software that dates back to the PEAR days. The packages provided by the Doctrine project have been downloaded almost 500 million times from packagist. In this talk we will take you through how to get started with Doctrine and how to take advantage of some of the more advanced features.
Magento Live Australia 2016: Request FlowVrann Tulika
As a web application, Magento 2’s web request processing flow is similar to all other web framework flows, but offers more extension points to third-party developers. In this session, we will walk through a web request path in the Magento 2 application, from index.php to browser JS application, and will look at extension points available on that path.
Learn how to use Capistrano to automate the deployment of your Ruby on Rails applications. Apply best practices and add-ons for customizing Capistrano.
Building Lithium Apps (Like a Boss) was a workshop presented on the structure and philosophy of the Lithium framework and its applications, and how best to take advantage of them.
Navigating the Metaverse: A Journey into Virtual Evolution"Donna Lenk
Join us for an exploration of the Metaverse's evolution, where innovation meets imagination. Discover new dimensions of virtual events, engage with thought-provoking discussions, and witness the transformative power of digital realms."
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
The European Union Agency for Law Enforcement Cooperation (Europol) has suffered an alleged data breach after a notorious threat actor claimed to have exfiltrated data from its systems. Infamous data leaker IntelBroker posted on the even more infamous BreachForums hacking forum, saying that Europol suffered a data breach this month.
The alleged breach affected Europol agencies CCSE, EC3, Europol Platform for Experts, Law Enforcement Forum, and SIRIUS. Infiltration of these entities can disrupt ongoing investigations and compromise sensitive intelligence shared among international law enforcement agencies.
However, this is neither the first nor the last activity of IntekBroker. We have compiled for you what happened in the last few days. To track such hacker activities on dark web sources like hacker forums, private Telegram channels, and other hidden platforms where cyber threats often originate, you can check SOCRadar’s Dark Web News.
Stay Informed on Threat Actors’ Activity on the Dark Web with SOCRadar!
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
CyanicLab, an offshore custom software development company based in Sweden,India, Finland, is your go-to partner for startup development and innovative web design solutions. Our expert team specializes in crafting cutting-edge software tailored to meet the unique needs of startups and established enterprises alike. From conceptualization to execution, we offer comprehensive services including web and mobile app development, UI/UX design, and ongoing software maintenance. Ready to elevate your business? Contact CyanicLab today and let us propel your vision to success with our top-notch IT solutions.
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
Les Buildpacks existent depuis plus de 10 ans ! D’abord, ils étaient utilisés pour détecter et construire une application avant de la déployer sur certains PaaS. Ensuite, nous avons pu créer des images Docker (OCI) avec leur dernière génération, les Cloud Native Buildpacks (CNCF en incubation). Sont-ils une bonne alternative au Dockerfile ? Que sont les buildpacks Paketo ? Quelles communautés les soutiennent et comment ?
Venez le découvrir lors de cette session ignite
We describe the deployment and use of Globus Compute for remote computation. This content is aimed at researchers who wish to compute on remote resources using a unified programming interface, as well as system administrators who will deploy and operate Globus Compute services on their research computing infrastructure.
Understanding Globus Data Transfers with NetSageGlobus
NetSage is an open privacy-aware network measurement, analysis, and visualization service designed to help end-users visualize and reason about large data transfers. NetSage traditionally has used a combination of passive measurements, including SNMP and flow data, as well as active measurements, mainly perfSONAR, to provide longitudinal network performance data visualization. It has been deployed by dozens of networks world wide, and is supported domestically by the Engagement and Performance Operations Center (EPOC), NSF #2328479. We have recently expanded the NetSage data sources to include logs for Globus data transfers, following the same privacy-preserving approach as for Flow data. Using the logs for the Texas Advanced Computing Center (TACC) as an example, this talk will walk through several different example use cases that NetSage can answer, including: Who is using Globus to share data with my institution, and what kind of performance are they able to achieve? How many transfers has Globus supported for us? Which sites are we sharing the most data with, and how is that changing over time? How is my site using Globus to move data internally, and what kind of performance do we see for those transfers? What percentage of data transfers at my institution used Globus, and how did the overall data transfer performance compare to the Globus users?
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteGoogle
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-pilot-review/
AI Pilot Review: Key Features
✅Deploy AI expert bots in Any Niche With Just A Click
✅With one keyword, generate complete funnels, websites, landing pages, and more.
✅More than 85 AI features are included in the AI pilot.
✅No setup or configuration; use your voice (like Siri) to do whatever you want.
✅You Can Use AI Pilot To Create your version of AI Pilot And Charge People For It…
✅ZERO Manual Work With AI Pilot. Never write, Design, Or Code Again.
✅ZERO Limits On Features Or Usages
✅Use Our AI-powered Traffic To Get Hundreds Of Customers
✅No Complicated Setup: Get Up And Running In 2 Minutes
✅99.99% Up-Time Guaranteed
✅30 Days Money-Back Guarantee
✅ZERO Upfront Cost
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
Unlocking Business Potential: Tailored Technology Solutions by Prosigns
Discover how Prosigns, a leading technology solutions provider, partners with businesses to drive innovation and success. Our presentation showcases our comprehensive range of services, including custom software development, web and mobile app development, AI & ML solutions, blockchain integration, DevOps services, and Microsoft Dynamics 365 support.
Custom Software Development: Prosigns specializes in creating bespoke software solutions that cater to your unique business needs. Our team of experts works closely with you to understand your requirements and deliver tailor-made software that enhances efficiency and drives growth.
Web and Mobile App Development: From responsive websites to intuitive mobile applications, Prosigns develops cutting-edge solutions that engage users and deliver seamless experiences across devices.
AI & ML Solutions: Harnessing the power of Artificial Intelligence and Machine Learning, Prosigns provides smart solutions that automate processes, provide valuable insights, and drive informed decision-making.
Blockchain Integration: Prosigns offers comprehensive blockchain solutions, including development, integration, and consulting services, enabling businesses to leverage blockchain technology for enhanced security, transparency, and efficiency.
DevOps Services: Prosigns' DevOps services streamline development and operations processes, ensuring faster and more reliable software delivery through automation and continuous integration.
Microsoft Dynamics 365 Support: Prosigns provides comprehensive support and maintenance services for Microsoft Dynamics 365, ensuring your system is always up-to-date, secure, and running smoothly.
Learn how our collaborative approach and dedication to excellence help businesses achieve their goals and stay ahead in today's digital landscape. From concept to deployment, Prosigns is your trusted partner for transforming ideas into reality and unlocking the full potential of your business.
Join us on a journey of innovation and growth. Let's partner for success with Prosigns.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
In this slide, we show the simulation example and the way to compile this solver.
In this solver, the Helmholtz equation can be solved by helmholtzFoam. Also, the Helmholtz equation with uniformly dispersed bubbles can be simulated by helmholtzBubbleFoam.
A Comprehensive Look at Generative AI in Retail App Testing.pdfkalichargn70th171
Traditional software testing methods are being challenged in retail, where customer expectations and technological advancements continually shape the landscape. Enter generative AI—a transformative subset of artificial intelligence technologies poised to revolutionize software testing.
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...Juraj Vysvader
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I didn't get rich from it but it did have 63K downloads (powered possible tens of thousands of websites).
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