DX or Developer Experience is essential for Symfony project. We work very hard to improve DX in each Symfony release and the recent Symfony 2.8 version is no exception.
Filter Results in the Web Profiler
The search engine provided by the web profiler now allows to quickly filter results by method, IP or URL. Just click on the loupe icon displayed when you move the mouse over each row:
If you click on these icons repeatedly, the filters are chained, so you can perform a very granular filtering.
Allow to Check for Security Even in Pages not Covered by Firewalls
Before Symfony 2.8, when a page wasn't covered by a security firewall, you
couldn't use the is_granted()
helper because it resulted in an exception.
Therefore, it was common to use the following if app.user
check:
1 2 3
{% if app.user and is_granted('ROLE_ADMIN') %}
...
{% endif %}
In Symfony 2.8 this additional check is no longer necessary and no exception will
be thrown when using the is_granted()
helper in any page:
1 2 3
{% if is_granted('ROLE_ADMIN') %}
...
{% endif %}
Added a Logout Shortcut in the Toolbar
The security panel of the Web Debug Toolbar now displays a Logout shortcut to quickly logout from the current firewall, which is a common need while developing your application:
Added New Methods to the BrowserKit's Client
The BrowserKit's client used in functional tests allows to disable and/or limit the number of redirections. The two new methods added to the client allow you to check for this values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class SomeTest extends WebTestCase
{
public function testSomething()
{
$client = static::createClient();
// ...
if ($client->isFollowingRedirects()) {
// ...
}
if ($client->getMaxRedirects() < 3) {
// ...
}
}
}
Easier Custom Authentication Errors
Currently, to display a custom authentication error message, you need to create
a new subclass of AuthenticationException
. In Symfony 2.8, you just need to
use any of these new methods:
1 2 3 4 5 6 7 8 9
throw new CustomUserMessageAuthenticationException(
'That was a ridiculous username'
);
// another way of doing the same
$e = new CustomAuthenticationException();
$e->setSafeMessage('That was a ridiculous username');
throw $e;
The methods are called "safe" because they are meant to be displayed to the end user, so they don't contain sensitive information and they can be safely exposed.
Show Priorities When Debugging Events
Before Symfony 2.8, the output of the debug:event-dispatcher
command didn't
include one of the most important informations about the listeners: their priority.
In Symfony 2.8 this information has been added both to the command and to the
web profiler panel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
$ php app/console debug:event-dispatcher
"kernel.request" event
----------------------
------- -------------------------------------------------------------------------------------- ----------
Order Callable Priority
------- -------------------------------------------------------------------------------------- ----------
#1 Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure() 2048
#2 Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest() 1024
#3 Symfony\Component\HttpKernel\EventListener\DumpListener::configure() 1024
#4 Symfony\Bundle\FrameworkBundle\EventListener\SessionListener::onKernelRequest() 128
#5 Symfony\Component\HttpKernel\EventListener\FragmentListener::onKernelRequest() 48
#6 Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest() 32
#7 Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest() 16
#8 Symfony\Component\HttpKernel\EventListener\TranslatorListener::onKernelRequest() 10
#9 Symfony\Component\Security\Http\Firewall::onKernelRequest() 8
#10 AppBundle\EventListener\RedirectToPreferredLocaleListener::onKernelRequest() 0
#11 Symfony\Bundle\AsseticBundle\EventListener\RequestListener::onKernelRequest() 0
#12 Knp\Bundle\PaginatorBundle\Subscriber\SlidingPaginationSubscriber::onKernelRequest() 0
------- -------------------------------------------------------------------------------------- ----------
# ...
Added a Stream-Aware Version of PHP's tempnam()
The Filesystem component now includes a new tempnam()
method which allows to
create temporary files on any PHP supported stream, even in custom streams:
1 2 3 4 5 6
$tmpFile = $fs->tempnam('ftp://example.com/tmp', '...');
$tmpFile = $fs->tempnam('compress.zlib://example.zip', '...');
// using a custom stream
stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream');
$tmpFile = $fs->tempnam('mock://file', '...');
Recursive Directory Loading for Configuration and Routing
Configuration files can now import all the files contained in a given directory, even when they use different formats (YAML, PHP, XML, etc.), instead of having to import each file separately:
1 2 3 4 5 6 7 8 9
# Before Symfony 2.8
imports:
- { resource: acme/parameters.yml }
- { resource: acme/security.yml }
- { resource: acme/services.yml }
# In Symfony 2.8
imports:
- { resource: acme/ }
The same behavior is now possible when importing routes thanks to the new
directory
resource type:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Before Symfony 2.8
_blog_public:
resource: "routing/blog/public.yml"
_blog_private:
resource: "routing/blog/private.yml"
# In Symfony 2.8
# implicit: add a trailing slash in the directory name
_blog:
resource: "routing/blog/"
# explicit: set the type to 'directory'
_blog:
resource: "routing/blog"
type: directory
Thank you all very much for showing this!
Is there a place where all these small tips are gathered?
The best place to learn about these new tricks is to follow the "Living on the Edge" category of this blog: http://symfony.com/blog/category/living-on-the-edge
Although this is probably a shameless self promotion, you can also check these presentations about "Symfony Tips & Tricks": 2014 edition (http://www.slideshare.net/javier.eguiluz/symfony-tips-and-tricks) 2015 edition (http://www.slideshare.net/javier.eguiluz/new-symfony-tips-tricks-symfonycon-paris-2015).
This is some great stuff, thanks for posting Javier!
WOW, routing & config directory import is AWESOME !
Thanks a lot for all these tips !
I think it is worth to note that 'directory' type is auto-detected with '/' at the end and type not set
https://github.com/nicolas-grekas/symfony/blob/master/src/Symfony/Component/DependencyInjection/Loader/DirectoryLoader.php#L54
@Pavel I didn't know that trick. I've updated the original blog post. Thanks!
Finally directory import, so awesome! Nice features, thanks guys
This helps us a lot! :) Thank you!!!
Lot of very useful improvements for me! Sounds great! Bravo!
The new Logout link is ignoring dev environment (i.e. is pointing to something like "/logout" instead of "app_dev.php/logout"), so it's currently useless.
@Massimiliano perhaps you are using a hardcoded path in the logout firewall option instead of a route. See https://github.com/symfony/symfony/issues/17029 for details.
The exemple for "Easier Custom Authentication Errors" is not correct. It should be : throw new CustomUserMessageAuthenticationException('That was a ridiculous username'); (Class name has been changed, and there is no static constructor anymore)
@Grandjean thanks for the heads up. I've just updated the blog post.
Great work !
@Javier You forgot the "new" keyword ;)
throw CustomUserMessageAuthenticationException('That was a ridiculous username');
@Thierry thanks for the heads up. It's fixed now.