A collection of useful Symfony snippets.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
README.md

README.md

Awesome Symfony

A curated list of useful Symfony snippets.

Contributions are highly encouraged and very welcome :)

Table of Contents

Configuration

Assets

Assets Base URL

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']

[1]

Assets Base URL (Protocol-Relative)

# app/config/config.yml 
framework: 
    templating: 
        assets_base_urls: '//static.domain.com/images'

Assets Versioning

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'

[1]

Named Assets

# 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 %}

Context-Aware CDNs

# 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 #}

[1]

Packages (Different Base URLs)

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') }}" />

Directories, Paths

Get Root Project Directory

Use %kernel.root_dir%/../:

some_service:
    class: \path\to\class
    arguments: [%kernel.root_dir%/../]

Email Errors

Email Logs Related to 5xx Errors (action_level: critical)

# 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

Email Logs Related to 4xx Errors (action_level: error)

# 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

Do Not Email Logs for 404 Errors (excluded_404)

# 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

Import

Import Mixed Configuration Files

# app/config/config.yml
imports:
    - { resource: '../common/config.yml' }
    - { resource: 'dynamic-config.php' }
    - { resource: 'parameters.ini' }
    - { resource: 'security.xml' }
    # ...

Import All Resources From a Directory

# app/config/config.yml
imports:
    - { resource: '../common/' }
    - { resource: 'acme/' }
    # ...

Import Configuration Files Using Glob Patterns

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}" }
    # ...

[1]

Log

Enable the Monolog processor PsrLogMessageProcessor

# app/config/config_prod.yml
services:
    monolog_processor:
        class: Monolog\Processor\PsrLogMessageProcessor
        tags:
            - { name: monolog.processor }

Hide Event Logs

# app/config/dev.yml
monolog:
    handlers:
        main:
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            level: debug
            channels: "!event"

Organizing Log Files Using Channels (Log Messages to Different Files)

# 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"

[1]

Security

Impersonating Users

# app/config/security.yml
security:
    firewalls:
        main:
            # ...
            switch_user: true

Switching the user in the URL: http://domain.com/path?_switch_user=john

Session

Define Session Lifetime

# app/config/config.yml
framework:
    session:
        cookie_lifetime: 3600

Profiler

Enable the Profiler on Prod For Specific Users

# 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'); 
    }
}

Console

Parallel Asset Dump

Symfony 2.8

    $ php app/console --env=prod assetic:dump --forks=4

Symfony 3+

    $ php bin/console --env=prod assetic:dump --forks=4

Controller

Cookie

Set a Cookie

use Symfony\Component\HttpFoundation\Cookie;

$response->headers->setCookie(new Cookie('site', 'bar'));

Directories, Paths, and Filesystem

Root Directory of the Project

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')."/../")

Check If a Path is Absolute

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

[1]

Download

Download (Serve) a Static File

use Symfony\Component\HttpFoundation\BinaryFileResponse;

// ...

return new BinaryFileResponse('path/to/file');

Check If a File Exists

use Symfony\Component\Filesystem\Filesystem;

//...

$fs = new FileSystem();
if (!$fs->exists($filepath)) {
    throw $this->createNotFoundException();
}

[1]

Download a File Without Directly Expose it and Change the Filename

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;

Using X-Sendfile Header with BinaryFileResponse

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();

Flash Messages

Set Multiple Flash Messages

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');

[1]

Form

Get Errors for All Form Fields

Symfony 2.5+

$allErrors = $form->getErrors(true);

JSON

Avoiding XSSI JSON Hijacking (only GET requests are vulnerable)

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"}]

Create a JSON Response with JsonResponse Class

use Symfony\Component\HttpFoundation\JsonResponse;

$response = new JsonResponse();
$response->setData(array(
    'name' => 'John'
));

Create a JSON Response with Response Class

use Symfony\Component\HttpFoundation\Response;

$response = new Response();
$response->setContent(json_encode(array(
    'name' => 'John',
)));
$response->headers->set('Content-Type', 'application/json');

Set JSONP Callback Function

$response->setCallback('handleResponse');

Redirect

Redirect to Another URL

return $this->redirect('http://domain.com');

or

use Symfony\Component\HttpFoundation\RedirectResponse;

$response = new RedirectResponse('http://domain.com');

Request

Get the Request Object

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)
   {
       // ...
   }
}

[1]

Get the Request Raw Data Sent with the Request Body

$content = $request->getContent();

Fetch a GET Parameter

$request->query->get('site');

Fetch a GET Parameter in array format (data['name'])

$request->query->get('data')['name'];

Fetch a POST Parameter

$request->request->get('name');

Fetch a GET Parameter Specifying the Data Type

$isActive = $request->query->getBoolean('active');
$page     = $request->query->getInt('page'); 

Other methods are:

  • getAlpha('param');
  • getAlnum('param');
  • getDigits('param'); [1]

Response

Set a HTTP Status Code

use Symfony\Component\HttpFoundation\Response;

$response->setStatusCode(Response::HTTP_NOT_FOUND);

Routing

Generate Absolute URL

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);

Trailing Slash with an Optional Parameter

my_route:
    pattern:  /blog/{var}
    defaults: { _controller: TestBundle:Blog:index, var: ''}
    requirements:
        var: ".*"

Service

Retrieve a Service

$this->get('service.name');

or

$this->container->get('service.name'),

YAML

Parse YAML File

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());
}

[1]

Twig

Absolute URLs

Symfony 2.6

{{ asset('logo.png', absolute = true) }}

Symfony 2.7+

{{ absolute_url(asset('logo.png')) }}

Assets Versioning

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') }}

[1]

Get the Authenticated Username

{{ app.user.username }}

Localized Date String

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

Inject All GET Parameters in a Route

{{ path('home', app.request.query.all) }}

Make the form_rest() and form_end() not Display a Specific Field

Mark the field as rendered (setRendered)

{% do form.somefield.setRendered %}

Render a Template without a Specific Controller for a Static Page

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

Override the 404 Error Template

Create a new error404.html.twig template at:

app/Resources/TwigBundle/views/Exception/

[1]

Render a Controller Asynchronously

{{ render_hinclude(controller('AppBundle:Features:news', {
    'default': 'Loading...'
})) }}

[1]

Render Just the Close Form HTML Tag

{{ form_end(form, {'render_rest': false}) }}

Using Localized Data (Date, Currency, Number, ...)

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 }