What’s new in Symfony 4.3 ? (part 1)

The new version of Symfony framework 4.3 is in the pipeline with a lot of improvements and a new components (Mime & Mailer), here I try to resume those new things. Let go !

ChangeLog is here


1- Better inflector

Inflector component is no longer considered internal.

use Symfony\Component\Inflector\Inflector;
$result = Inflector::singularize(‘teeth’); // tooth
$result = Inflector::singularize(‘radii’); // radius
$result = Inflector::pluralize('bacterium');  // bacteria
$result = Inflector::pluralize('alumnus'); // alumni
$result = Inflector::pluralize('news'); // news
$result = Inflector::pluralize('GrandChild'); // GrandChildren
/** When it's not possible to determine a unique singular/plural
* form for the given word, the methods return an array with
* all the possible forms
*/
Inflector::singularize('leaves');  // ['leaf', 'leave', 'leaff']

2- Automatic Search Engine Protection

Disallowing the search engine indexing for development applications: How does it work? If the app kernel runs in debug mode (by default this happens when the Symfony environment is not prod) Symfony adds a X-Robots-Tag: noindex HTTP header to all the responses.

# config/packages/framework.yaml
framework:
# …
disallow_search_engine_index: false

3- Simpler event dispatching

in Symfony 4.3 the signature of the EventDispatcherInterface::dispatch() method:

// …
$order = new Order();
$newOrderEvent = new OrderPlacedEvent($order);
// Before
$dispatcher->dispatch(OrderEvents::NEW_ORDER, $newOrderEvent);
// After
$dispatcher->dispatch($newOrderEvent, OrderEvents::NEW_ORDER);
// You can subscribe to events using the FQCN of the event:
class StoreSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
// Before
return [
OrderEvents::NEW_ORDER => 'onStoreOrder',
];

// After
return [
OrderPlacedEvent::class => 'onStoreOrder',
];
}

// ...
}
// Moreover, the event name is now optional in the dispatch() method, so you can pass just the event object:
// Before
$dispatcher->dispatch(OrderEvents::NEW_ORDER, $newOrderEvent);

// After
$dispatcher->dispatch($newOrderEvent);

Supporting both dispatchers:

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
class SomeService
{
public function __construct(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
}
public function someMethod()
{
// …
// use the new way of dispatching events (with or without the event name)
// even if the provided dispatcher still implements the legacy way
$this->dispatcher->dispatch($newOrderEvent);
$this->dispatcher->dispatch($newOrderEvent, OrderEvents::NEW_ORDER);
}
}

4- Routing improvements

Boolean Container Parameters in Routes:

/**
* @Route(“/test”, condition=”%kernel.debug%”)
*/
class TestController extends AbstractController
{
// …
}

Deprecated Some Router Options:

  • generator_base_class
  • generator_cache_class
  • matcher_base_class
  • matcher_cache_class

Displayed the Route Conditions When Debugging:

$ php bin/console debug:router some_route_name

+--------------+--------------------------------------------------+
| Property | Value |
+--------------+--------------------------------------------------+
| Route Name | |
| Path | /name/add |
| Host | localhost |
| Scheme | http|https |
| Method | PUT|POST |
| ... |
| Condition | context.getMethod() in ['GET', 'HEAD', 'POST'] |
+--------------+---------------------------------------------------+

5- URL Helper

New class called Symfony\Component\HttpFoundation\UrlHelper that you can inject as a service anywhere in your application. This class provides two public methods called getAbsoluteUrl() and getRelativePath().

use Symfony\Component\HttpFoundation\UrlHelper;
class UserApiNormalizer
{
private $urlHelper;
public function __construct(UrlHelper $urlHelper)
{
$this->urlHelper = $urlHelper;
}
public function normalize(
$user,
$format = null,
array $context = []
)
{
return [
‘avatar’ => $this->urlHelper->getAbsoluteUrl($user->avatar()->path()),
// …
];
}
// …
}

To be continued …