A curated list of useful Symfony snippets.
Contributions are highly encouraged and very welcome :)
- Configuration
- Console
- Controller
- Environment Variables
- Routing
- Twig
- Absolute URLs
- Assets Versioning
- Get the Authenticated Username
- Get the Base URL
- Localized Date String
- Inject All GET Parameters in a Route
- Make the
form_rest()
andform_end()
not Display a Specific Field - Override the 404 Error Template
- Render a Controller Asynchronously
- Render Just the Close Form HTML Tag
- Render a Template without a Specific Controller for a Static Page
- Using Localized Data (Date, Currency, Number, ...)
Symfony 2.6
# app/config/config.yml
framework:
templating:
assets_base_urls:
http: ['http://cdn.domain.com']
ssl: ['https://secure.domain.com']
packages:
# ...
Symfony 2.7+
# app/config/config.yml
framework:
assets:
base_path: ~
base_urls: ['http://cdn.domain.com', 'https://secure.domain.com']
# app/config/config.yml
framework:
templating:
assets_base_urls: '//static.domain.com/images'
Symfony 2.6
# app/config/config.yml
framework:
templating:
assets_version: 'v5'
assets_version_format: '%%s?version=%%s'
Symfony 2.7+
# app/config/config.yml
framework:
assets:
version: 'v5'
version_format: '%%s?version=%%s'
# app/config/config.yml
assetic:
assets:
bootstrap_js:
inputs:
- '@AppBundle/Resources/public/js/jquery.js'
- '@AppBundle/Resources/public/js/bootstrap.js'
Using in Twig templates:
{% javascripts
'@bootstrap_js'
'@AppBundle/Resources/public/js/*' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
# app/config/config.yml
framework:
assets:
base_urls:
- 'http://static1.domain.com/images/'
- 'https://static2.domain.com/images/'
Using in Twig templates:
{{ asset('logo.png') }}
{# in a regular page: http://static1.domain.com/images/logo.png #}
{# in a secure page: https://static2.domain.com/images/logo.png #}
To specify different base URLs for assets, group them into packages:
# app/config/config.yml
framework:
# ...
assets:
packages:
avatars:
base_urls: 'http://static_cdn.domain.com/avatars'
Using the avatars
package in a Twig template:
<img src="{{ asset('...', 'avatars') }}" />
Use the config parameter %kernel.root_dir%/../
:
some_service:
class: \path\to\class
arguments: [%kernel.root_dir%/../]
Symfony 2
In a Controller:
$projectRoot = $this->container->getParameter('kernel.root_dir');
Symfony 3.3
In a Controller:
$projectRoot = $this->get('kernel')->getProjectDir();
Symfony 4+
Using autowiring (argument binding):
# config/services.yaml
services:
_defaults:
bind:
string $projectDir: '%kernel.project_dir%'
Then in your class:
class YourClass
{
private $projectDir;
public function __construct(string $projectDir)
{
$this->$projectDir = $projectDir;
}
// ...
# app/config/config_prod.yml
monolog:
handlers:
mail:
type: fingers_crossed
action_level: critical
handler: buffered
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: [email protected]
to_email: [email protected]
subject: An Error Occurred!
level: debug
# app/config/config_prod.yml
monolog:
handlers:
mail:
type: fingers_crossed
action_level: error
handler: buffered
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: [email protected]
to_email: [email protected]
subject: An Error Occurred!
level: debug
# app/config/config_prod.yml
monolog:
handlers:
mail:
type: fingers_crossed
action_level: error
excluded_404:
- ^/
handler: buffered
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: [email protected]
to_email: [email protected]
subject: An Error Occurred!
level: debug
# app/config/config.yml
imports:
- { resource: '../common/config.yml' }
- { resource: 'dynamic-config.php' }
- { resource: 'parameters.ini' }
- { resource: 'security.xml' }
# ...
# app/config/config.yml
imports:
- { resource: '../common/' }
- { resource: 'acme/' }
# ...
Symfony 3.3
# app/config/config.yml
imports:
- { resource: "*.yml" }
- { resource: "common/**/*.xml" }
- { resource: "/etc/myapp/*.{yml,xml}" }
- { resource: "bundles/*/{xml,yaml}/services.{yml,xml}" }
# ...
# app/config/config_prod.yml
services:
monolog_processor:
class: Monolog\Processor\PsrLogMessageProcessor
tags:
- { name: monolog.processor }
# app/config/dev.yml
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: "!event"
# app/config/config_prod.yml
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
security:
type: stream
path: "%kernel.logs_dir%/security-%kernel.environment%.log"
level: debug
channels: "security"
# app/config/security.yml
security:
firewalls:
main:
# ...
switch_user: true
Switching the user in the URL:
http://domain.com/path?_switch_user=john
# app/config/config.yml
framework:
session:
cookie_lifetime: 3600
# app/config/config.yml
framework:
# ...
profiler:
matcher:
service: app.profiler_matcher
services:
app.profiler_matcher:
class: AppBundle\Profiler\Matcher
arguments: ["@security.context"]
namespace AppBundle\Profiler;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
class Matcher implements RequestMatcherInterface
{
protected $securityContext;
public function __construct(SecurityContext $securityContext)
{
$this->securityContext = $securityContext;
}
public function matches(Request $request)
{
return $this->securityContext->isGranted('ROLE_ADMIN');
}
}
Symfony 2.8
$ php app/console --env=prod assetic:dump --forks=4
Symfony 3+
$ php bin/console --env=prod assetic:dump --forks=4
use Symfony\Component\HttpFoundation\Cookie;
$response->headers->setCookie(new Cookie('site', 'bar'));
The parameter kernel.root_dir
points to the app
directory. To get to the root project directory, use kernel.root_dir/../
realpath($this->getParameter('kernel.root_dir')."/../")
use Symfony\Component\Filesystem\Filesystem;
//...
$fs = new FileSystem();
$fs->isAbsolutePath('/tmp'); // return true
$fs->isAbsolutePath('c:\\Windows'); // return true
$fs->isAbsolutePath('tmp'); // return false
$fs->isAbsolutePath('../dir'); // return false
use Symfony\Component\HttpFoundation\BinaryFileResponse;
// ...
return new BinaryFileResponse('path/to/file');
use Symfony\Component\Filesystem\Filesystem;
//...
$fs = new FileSystem();
if (!$fs->exists($filepath)) {
throw $this->createNotFoundException();
}
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\Filesystem\Filesystem;
$filename = // define your filename
$basePath = $this->getParameter('kernel.root_dir').'/../uploads';
$filePath = $basePath.'/'.$filename;
$fs = new FileSystem();
if (!$fs->exists($filepath)) {
throw $this->createNotFoundException();
}
$response = new BinaryFileResponse($filePath);
$response->trustXSendfileTypeHeader();
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_INLINE,
$filename,
iconv('UTF-8', 'ASCII//TRANSLIT', $filename)
);
return $response;
BinaryFileResponse supports X-Sendfile
(Nginx and Apache). To use of it,
you need to determine whether or not the X-Sendfile-Type
header should be
trusted and call trustXSendfileTypeHeader()
if it should:
BinaryFileResponse::trustXSendfileTypeHeader();
or
$response = new BinaryFileResponse($filePath);
$response->trustXSendfileTypeHeader();
use Symfony\Component\HttpFoundation\Session\Session;
$session = new Session();
$session->start();
$session->getFlashBag()->add(
'warning',
'Your config file is writable, it should be set read-only'
);
$session->getFlashBag()->add('error', 'Failed to update name');
$session->getFlashBag()->add('error', 'Invalid email');
Symfony 2.5+
$allErrors = $form->getErrors(true);
Pass an associative array as the outer-most array to JsonResponse
and not an indexed array so that the final result is an object:
{"object": "not inside an array"}
instead of an array:
[{"object": "inside an array"}]
use Symfony\Component\HttpFoundation\JsonResponse;
$response = new JsonResponse();
$response->setData(array(
'name' => 'John'
));
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent(json_encode(array(
'name' => 'John',
)));
$response->headers->set('Content-Type', 'application/json');
$response->setCallback('handleResponse');
return $this->redirect('http://domain.com');
or
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse('http://domain.com');
Symfony 2
namespace Acme\FooBundle\Controller;
class DemoController
{
public function showAction()
{
$request = $this->getRequest();
// ...
}
}
Symfony 3
namespace Acme\FooBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
class DemoController
{
public function showAction(Request $request)
{
// ...
}
}
$content = $request->getContent();
$request->query->get('site');
$request->query->get('data')['name'];
$request->request->get('name');
$isActive = $request->query->getBoolean('active');
$page = $request->query->getInt('page');
Other methods are:
- getAlpha('param');
- getAlnum('param');
- getDigits('param'); [1]
use Symfony\Component\HttpFoundation\Response;
$response->setStatusCode(Response::HTTP_NOT_FOUND);
google_search:
path: /search
host: www.google.com
<a href="{{ url('google_search', {q: 'Jules Verne'}) }}">Jules Verne</a>
framework:
assets:
packages:
symfony_site:
version: ~
base_urls: 'https://symfony.com/images'
Add images from the URL above into your views, using the "symfony_site" key in the second argument of asset():
<img src="{{ asset('logos/header-logo.svg', 'symfony_site') }}">
Symfony 2
$this->generateUrl('blog_show', array('slug' => 'my-blog-post'), true);
Symfony 3
$this->generateUrl('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
my_route:
pattern: /blog/{var}
defaults: { _controller: TestBundle:Blog:index, var: ''}
requirements:
var: ".*"
$this->get('service.name');
or
$this->container->get('service.name'),
Symfony 4+
Using autowiring, just type-hint the desired service. E.g. getting the routing service:
use Symfony\Component\Routing\RouterInterface;
class SomeClass
{
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function doSomething($id)
{
$url = $this->router->generate('route_name', ['id' => $id]);
// ...
}
// ...
use Symfony\Component\Yaml\Exception\ParseException;
try {
$value = Yaml::parse(file_get_contents('/path/to/file.yml'));
} catch (ParseException $e) {
printf("Unable to parse the YAML string: %s", $e->getMessage());
}
Symfony 4.4
# config/services.yaml
bind:
string $name: '%env(name)%'
Implement the EnvVarLoaderInterface
in a service:
namespace App\Env;
use Symfony\Component\DependencyInjection\EnvVarLoaderInterface;
class ConsulEnvVarLoader implements EnvVarLoaderInterface
{
public function loadEnvVars(): array
{
$response = file_get_contents('http://127.0.0.1:8500/v1/kv/website-config');
$consulValue = json_decode($response, true)[0]['Value'];
$decoded = json_decode(base64_decode($consulValue), true);
// e.g.:
// array:1 [
// "name" => "my super website"
// ]
return $decoded;
}
}
Update the consul KV:
./consul kv put website-config '{"name": "Symfony read this var from consul"}'
Symfony 2.6
{{ asset('logo.png', absolute = true) }}
Symfony 2.7+
{{ absolute_url(asset('logo.png')) }}
Symfony 2.6
{{ asset('logo.png', version = 'v5') }}
Symfony 2.7+
Version is automatically appended.
{{ asset('logo.png') }}
{# use the asset_version() function if you need to output it manually #}
{{ asset_version('logo.png') }}
{{ app.user.username }}
In your Twig template, you can use pre-defined or custom date formats with the localizeddate
:
{{ blog.created|localizeddate('none', 'none', 'pt_BR', null, "cccc, d MMMM Y 'às' hh:mm aaa")}}
The pattern "cccc, d MMMM Y 'às' hh:mm aaa"
will show the date in this format:
domingo, 5 janeiro 2014 às 03:00 am
{{ app.request.getSchemeAndHttpHost() }}
{{ path('home', app.request.query.all) }}
Mark the field as rendered (setRendered
)
{% do form.somefield.setRendered %}
Use the special controller FrameworkBundle:Template:template in the route definition:
# AppBundle/Resources/config/routing.yml
static_page:
path: /about
defaults:
_controller: FrameworkBundle:Template:template
template: AppBundle:default:about.html.twig
Create a new error404.html.twig
template at:
app/Resources/TwigBundle/views/Exception/
{{ render_hinclude(controller('AppBundle:Features:news', {
'default': 'Loading...'
})) }}
{{ form_end(form, {'render_rest': false}) }}
Enable the intl
twig extension in config.yml
or services.yml
file:
services:
twig.extension.intl:
class: Twig_Extensions_Extension_Intl
tags:
- { name: twig.extension }