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: error@domain.com to_email: error@domain.com 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: error@domain.com to_email: error@domain.com 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: error@domain.com to_email: error@domain.com 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 }