Symfony: Form issue using Return type hinting in Doctrine Entity methods

All we need is an easy explanation of the problem, so here it is.

I was being exceptionally diligent today and decided to return-type hint all of my symfony entity methods. So:

<?php

Class User {
    private string $username;
    public method getUsername(): string {}
}

all good and well, until I made a form to create a new user:

$user = new User();
$this->createForm(SignupType::class, $user);

when the form is displayed, Symfony automatically gets the properties of this new instance of User $user. But since it is a new instantiation, its username property is of course still null, which is an incorrect return type as it needs to be string.

Should I either:

  1. have no return-type hinting in Symfony entities (meh);
  2. set $username = '' (but hat kind of defeats the purpose of not allowing blanks and I can see all sorts of errors evolving); or
  3. unmap the field on the symfony form
  4. other possible solutions…

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

If an Entity Property cannot be null (and you use PHP 7.1+), then applying the nullable return type declaration sounds more like a dirty and fast workaround to maintain a direct data binding between Entities and Forms (using the Symfony Form Component).

A better global approach (in my opinion) is to decouple the Form data binding from your Doctrine Entities using a DTO (Data Transfer Object), that is a simple POPO (Plain Old PHP Object) to contain your form data.

Using a DTO will allow you to maintain a strict type hinting in your Doctrine Entities (no loss of data consistency) and will decouple Form data binding (but also data validation) from your Entities.

DTO’s allows reusability and have many other advantages.

Some useful references about the use of DTO’s with Symfony Forms:

Method 2

If you’re using PHP 7.0, which has no nullable return type declaration support, the first option will be the right (non-hacky) choice. In case of you’re using PHP 7.1+, you can define a nullable return type declaration.

<?php

class User 
{
    public function getUsername(): ?string {}
}

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply