Skip to content

TYPO3 Extbase and type annotations with PHP 7.4

We all want to use latest PHP features when creating new code. As always, the details pave your way to success. This short article should provide you with a small hint on how to use PHP type annotations correctly, in order to work with Extbase.

Observation

Lets dive straight into it and have a look at this very simple model:

class Label extends AbstractEntity
{
    protected string $title;
    public function __construct() { $this->title = ''; }
    public function getTitle(): string { return $this->title; }
    public function setTitle(string $title): void { $this->title = $title; }
}

Looks good so far, doesn't it?

Fetching database rows with Extbase (using the appropriate repository of course) leads to a nice set of objects of type Label, but without the property $title.

So wait. We got an object of the desired type, but it lacks the properties?
At this point, one would probably call it a day and go home.

Right, PHP has just proven that an object of some class may not include all properties declared in the class.
Hell has frozen!

Reason

It turns out that Extbase's data mapper - the part of an ORM responsible to create objects from plain database results - tries to convert the Label database row by creating an uninitialized object of the Label class. This is done using a lot of internal code, finally ending up in the Doctrine Instantiator. This libary uses the PHP's core functionality ReflectionClass to call the method newInstanceWithoutConstructor() on it.

While there seems nothing wrong so far, it turns out that specifically this functionality gets into troubles once typed class properties come into the game.

Typed properties must be initialized in the constructor of the class or by providing a default value in the declaration, otherwise the value of the property remains undefined/uninitialized (not null!). This should be common knowledge.

The problem now arises when creating an instance of a class, explicitely omitting the constructor. This is the point where ReflectionClass fails to create those uninitialized properities, hence yielding objects with missing properties!

Solution

Use proper default values for your type annotated properties and you are good to go. As simple as that.

protected string $title = '';

Still, I tempt to say that PHP should at least die very hard, once such a situation is observed, instead of silently generating invalid objects.

 

Information in this article covers TYPO3 10 LTS with PHP 7.4