08/01/2019 7 Minutes read Tech 

Symfony Con by William Jehanne, PHP Engineer at ekino

The ekino team was present at the Lisbon Marriott Hotel on December 6th and 7th to follow the international Symfony conference.

Sensiolabs organised the sixth edition of the SymfonyCon in Lisbon, the international Symfony conference. This year was marked by the 4.2 version of the PHP framework. It is more than 900 enthusiasts developers from 50 different nationalities gathered to follow these two days of conferences.

Day 1

Opening Keynote by Fabien Potencier

Fabien Potencier, founder of the Symfony framework, opened the SymfonyCon conferences with a keynote recounting the features of the 4.2 version of the framework and a presentation about the Symfony Cloud feature. His presentation began with a state of local web servers with Symfony and a comparison with Vagrant which is inconvenient and Docker who can be slow when used on OS X. He said that PHP built-in server is almost perfect but it has too many limitations: one connection at a time, no HTTP-2 support, no SSL, does not re-read env vars if they change, need some tweaks to make it works with Symfony, …

To meet these needs, he presented us Symfony Cloud via a new Symfony binary introduced last week.

It is composed of several features:
-uses PHP-FPM whenever possible
-HTTP-2 support out of the box
-manage multiple local versions of PHP with the command : symfony local:php:list
-tail all the logs of your application with the symfony server:log command.
-TLS support locally, which is more similar to production. To init this you can use the symfony:ca:install command which creates a local Certificate Authority, registers it on your system trust store and creates a default certificate for localhost.
-manages local domain name with symfony proxy:start command and edits a proxy configuration with a proxy.json file.
-connects the remote services with symfony:tunnel:open and debugs with production data in a safe isolated environment.

Finally, you can use the local web server to connect with SymfonyCloud services.

I found this presentation very marketing-oriented to promote SymfonyCloud but the basic idea of being able to lower production data with a tunnel and managing TLS certificates locally is very interesting.

Knowing your state machines by Tobias Nyholm

In this conference, Tobias Nyholm explained us why he uses state machines which separate business logic from the model and make the code more reusable, maintainable and readable.

  • He started with some state machines example, in real life:
  • Traffic light (green, yellow, red)
  • Job advert (Draft, Review, Trash, Published and Archived)
  • Pull Request (Start, Travis, Coding, Review, Merged, Closed)
  • Elevator doors (Opened, Closing, Opening, Closed)
  • Multi step form

Two implementations exist:

  • State Pattern: Moore machine is a finite-state machine whose output values are determined only by its current state
  • Mealy State Machine: Mealy machine is a finite-state machine whose output values are determined both by its current state and the current inputs

Workflow component with job app and multi-form step, manage events, guards and security voters.

In an e-commerce context, we can list the following states:

  • An order is created
  • Items are added to order
  • Users sets delivery address
  • User goes to checkout and enters their payment
  • Delivery people gets a notification
  • The talk was ended with an interesting quote: “When using Symfony Workflow component you will write fewer bugs”.

Going crazy with Varnish: Caching pages of logged in users by David Buchmann

David Buchmann explained us HTTP Caching and what is a reverse proxy with Varnish. David shared some tips for caching content that are not the same for all users :
-avoid session, remove cookie when no longer needed
-build information in the frontend: “Cheating” with Javascript (render varying parts in JS, user state is communicated in cookie)
-cache despite cookies / cache per user (Cache-Control, Vary in headers)
-user context: cache by relevant group and geolocal. You can make Symfony keep the cache headers:

use SymfonyComponentHttpKernelEventListenerAbstractSessionListener;
...
$response->headers->set(
AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');

David’s conference also provided many tips on Edge Side Includes (ESI):
-content embeds URLs to sub-parts of the content
-varnish fetches and caches elements separately
-individual caching rules per fragment (vary on cookie, different TTL)
-Symfony has built-in support for ESI.

We can benefit from the following advantages:
separate caching for fragments,
server side,
makes search engines happy, simple to use in the application with Symfony.

Finally, managing cache could be global or individual with the Context Hash. We can group with permission and cache by session ID.

With the help of FOSHttpCacheBundle we can cache tags, invalidation service for active invalidation, use annotations for caching headers and invalidation, use request matcher for caching headers and manage user context with listener.

Using Symfony Forms with Rich Domain Models by Christopher Hertel and Christian Flothmann

The festivities continued with Christopher Hertel and Christian Flothmann who presented us a comparison between Anemic Domain Model and Rich Domain Model, with a solution similar to Mappers or Data Transfer Objects. Anemic Domain Model is an anti-pattern, focused on data, structured, easy to implement and to maintain, contains little or no logic, no guarantee to be valid or consistent. Rich Domain Model is the opposite: it combines data and logic, is valid by design, easy to test, and defines state transitions.

A DTO solution enables us to use Rich Domain Models, it is easy to implement but not to maintain, adds glue code and has redundant validation rules.

A DataMapper solution enables us to use rich domain models, it requires advanced knowledge about forms, adds glue code and has hard to test.

To respond at these problematics there is a new bundle: https://github.com/sensiolabs-de/rich-model-forms-bundle The Rich Model Forms Bundle enhances the Symfony Form component with useful options, it is released to help maintain and test DataMappers and avoid redundant DTO with additional form config options. Warning this bundle is still in development and experimental.

You can install it with:
composer require sensiolas-de/rich-model-forms-bundle:dev-master

It includes some features like different read/write property paths, exception handling, mandatory constructor arguments, immutable value object and it is very easy to implement.

Building global web apps with multi-region hosting by Jordi Boggiano

This conference explored various configurations and case studies of my attempts to host sites used by international audiences.

The presentation was complicated to understand as are subject, but we can take lessons from it with some feedback about https://teamup.com (shared calendar for group) and multi-region hosting.

The three case-by-case to ask you before starting multi-region are:

  • what audience location are your targetting
  • what is the maximum latency that you accept
  • what is your team size.

The patterns behind Doctrine by Denis Brumann

Denis Brumann presented us the UnitOfWork pattern of Doctrine. The UnitOfWork manages a list of objects affected by a business transaction (change sets, states, insertions, updates, deletions). The UnitOfWork is a property of Doctrine’s EntityManager. UnitOfWork will take care of ordering correctly each commit, you can persist your entities in any order.

Doctrine stores previously loaded entities in an IdentityMap.

Each new find() call returns the current entity.Entity States is composed of:

  • NEW (entity instance has no persistent identity, and is not yet associated with EntityManager).
  • MANAGED (entity instance is an instance with a persistent identity that is associated with an EntityManager).
  • DETACHED (entity instance with a persistent identity that is not associated with and EntityManager and a UnitOfWork.
  • REMOVED (entity instance with a persistent identity, associated with EntityManager, that will be removed from the database upon transaction commit).

UnitOfWork use spl_function_hash($entity) to get a unique identifier for the object and used as a hash key for storing objects, or identifying an object, as long as the object is not destroyed.

One of the most important differences between Doctrine 1 vs Doctrine 2 is Doctrine 1 implements ActiveRecord design while D2 implements DataMapper design.

Data Mapper vs Active Record
Data Mapper:

  • Logic and data is split up into multiple classes (EntityManager, UnitOfWork, Repository)
  • Explicit configuration
  • More code to write
  • Model can be independent from ORM

Active Record:

  • Carries both data and persistence logic
  • Implicit configuration
  • Less code to write
  • Place restrictions on model (no private properties, inherit __construct)

JeoPHPardy (game activity) by Jeremy Mikola

A social event took place for one hour, it was a serious game about Symfony, PHP 7.3, EleFont (guess fonts with elephant), Lisbon and guessing packages composer with composer.json.

It was very epic, funny and well animated!

Social event
The Symfony staff booked the Ministerium club at the Praça do Comércio, it was a great opportunity to networked with community and meet passionate people.

Day 2

Microservices gone wrong by Anthony Ferrara

Day 2 started with Anthony Ferrara, and he explained why he’s avoiding micro-services when possible.

He gave a tip to start with big services and split them into smaller ones. To do that, we should automate everything: spin-up, deployment, migration, backup, state restoration.

He said a phrase that I like it a lot: “Don’t plan for failure, live it”.

The microservices are difficult to debug with cascading failures and when the events changed, they are some backward compatibility with old events.

Webpack Encore: Tips, Tricks, Questions & Best Practices by Ryan Weaver

Ryan Weaver is a Symfony Cast contributor and he talked about Webpack Encore to present us the last release of Webpack Encore 0.21.0.

A new bundle has been created: WebpackEncoreBundle.

To download the package you could use composer:
composer require symfony/webpack-encore-bundle
It contains a new feature to simplify the script and link tags that are included for an entry:
{{ encore_entry_scripts_tags(‘checkout’) }}
{{ encore_entry_link_tags(‘checkout’) }}

An innovation in Webpack 4 is SplitChuncksPlugin to solve the duplicated code in multiple compiled entry files.

It provides solutions:
Use entrypoints.json to manage multiple scripts and links tags
Use runtime.js to solve the problem when we include multiple entry JavaScript files on the same page (enableSingleRuntimeChunk, disableSingleRuntimeChunk)

Symfony 4 internals by Tobias Nyholm

Symfony is a request and response framework. But what about all the magic that happens around your code? That’s what Tobias Nyholm was talking about. He explained us the concept of building our own Framework like Symfony from scratch.

He explains by dividing in simple concepts and rising crescendo

What is Symfony ? Symfony is composed of:

  • HTTP Objects
  • Controllers
  • Event Loop (kernel.request, kernel.controller, kernel.view, kernel.response, kernel.finish_request, kernel.terminate)
  • Cache (PSR-6, PSR-16)
  • Container
  • Router
  • Security (Authentication vs Authorisation)
  • Autowiring
  • Toolbar
  • Exception

My opinion about this presentation was that he demystified a big Framework with simple parts which encourages to understand what’s under the hood. It’s a great talk to motivate people to give an interest in Open-Source.

What’s a typical Symfony 4.2 application like? By Nicolas Grekas

Symfony’s configuration system has improved a lot in recent years. Version 4.2 brings a lot of minor improvements that Nicolas Grekas explained us with a better developer experience.

He talked about SOLID principles in Symfony, fully qualified name in autowiring and gave us a good tip to manage env variables with a secret files in Symfony 4.2 :

$secretFile = getenv(“SECRETS_FILE”);

$data = json_decode(
file_get_contents($secretsFile)
);

$s = new DoorbellRingEventSubscriber($data[‘API_KEY’]);

Services:
_defaults:
bind:
$apiKey: ‘%env(key: API_KEY:json:file:SECRETS_FILE)%’

Integrate (Vue)JS components in a Symfony app, add E2E tests with Panther by Kévin Dunglas

Kévin Dunglas presented us the Symfony MakerBundle a fastest way to generate a Symfony app and automatically combined with API platform. The new MakerBundle takes the place of SensioGeneratorBundle which makes it much easier to create different types of files (commands, entities, controller, twig extension, event subscriber, etc.).

He presented symfony/panther as well, a great standalone library to scrape website and run end-to-end test with screenshots.

And finally he presented us the MercureBundle to easily dispatch real time push updates to web browsers with API Platform in HTTP/2.

A Year of Symfony by Nicolas Grekas and Sarah Khalil

Nicolas Grekas and Sarah Khalil reminded us of everything that has happened during this year in the Symfony community and it was a rich year!

Symfony year is composed by :

  • Last year, 376 PRs in official repo,
  • Diversity section created (One year diversity initiative)
  • CARE Team
  • MakerBundle,
  • Panther,
  • ICU Message,
  • i18n and inline routing,
  • Messenger component,
  • Profiler log filter,
  • DotEnv variables

The SymfonyCon ended with the video of the SymfonyTour’s date 2019, and the next SymfonyCon will be in Amsterdam in 21-23 November 2019
https://www.youtube.com/watch?v=3Vl9W10zmKI

To conclude

Two days that were exciting and rewarding!

We appreciated the beautiful organization, and the selection of talks. We are extremely happy to have been able to participate in this edition of SymfonyCon! We’ve never eaten so much Pastéis de nata! We couldn’t talk about all the talks but you will find the contents on this repository. You can find all the slides here: https://github.com/SymfonyCon/2018-talks