PHP 7.4 introduit les propriétés typées : une classe peut désormais déclarer directement le type attendu pour chacune de ses propriétés, sans passer par un simple commentaire de documentation qu’aucun outil n’était obligé de respecter. Pour une équipe qui construit des objets de valeur destinés à servir de fixtures dans ses tests, cette nouveauté change plusieurs habitudes d’écriture.
Avant cette version, un objet de valeur utilisé comme fixture reposait sur la discipline du développeur et sur un bloc de documentation PHPDoc, jamais vérifié à l’exécution. Une propriété censée contenir une chaîne pouvait recevoir un entier sans qu’aucune erreur ne soit levée avant que ce mauvais type ne provoque un échec ailleurs, parfois loin du test qui l’avait introduit.
Avant PHP 7.4 : une convention non vérifiée
class ArticleFixture {
/** @var string */
public $titre;
/** @var int */
public $auteur_id;
/** @var bool */
public $est_publie;
}
$fixture = new ArticleFixture();
$fixture->auteur_id = '42'; // Chaîne au lieu d'un entier, aucune erreur
Ce code s’exécute sans le moindre avertissement. Le commentaire @var int ne sert qu’à l’analyse statique ou à l’auto-complétion de l’éditeur ; à l’exécution, PHP accepte n’importe quelle valeur. Une fixture construite avec un mauvais type peut ainsi masquer un vrai bug jusqu’à ce qu’un test, bien plus loin dans la suite, échoue pour une raison qui semble sans rapport.
Avec les propriétés typées

class ArticleFixture {
public string $titre;
public int $auteur_id;
public bool $est_publie;
}
$fixture = new ArticleFixture();
$fixture->auteur_id = '42'; // TypeError immédiate
Ici, l’assignation d’une chaîne à une propriété déclarée int déclenche immédiatement une TypeError, au moment précis où l’erreur est commise, pas plus tard dans une suite de tests qui l’utilise. Ce comportement transforme des bugs silencieux en échecs explicites et localisés, ce qui réduit sensiblement le temps passé à remonter jusqu’à la cause réelle d’un test cassé.
Le piège des propriétés non initialisées
Une propriété typée qui n’accepte pas null doit être initialisée avant d’être lue, sans quoi PHP lève une erreur au moment de l’accès, pas au moment de la déclaration de la classe. Ce détail surprend souvent les équipes qui migrent une fixture existante :
class ArticleFixture {
public string $titre;
}
$fixture = new ArticleFixture();
echo $fixture->titre; // Error: must not be accessed before initialization
Pour une fixture, ce comportement est en réalité une protection utile : il empêche un test de lire silencieusement une valeur par défaut inattendue, comme une chaîne vide ou un zéro, qui aurait pu masquer un oubli d’initialisation dans le constructeur ou dans une méthode de fabrique.
Rendre un champ optionnel explicitement
Quand une propriété peut légitimement rester absente, il faut le déclarer explicitement avec le type nullable, plutôt que de compter sur un comportement implicite :
class ArticleFixture {
public string $titre;
public ?string $sous_titre = null;
public int $auteur_id;
}
Cette écriture documente directement, dans la signature de la propriété, qu’un sous-titre est optionnel, alors qu’un titre et un auteur sont toujours attendus. Pour une équipe qui lit rapidement une fixture avant d’écrire un nouveau test, cette information est immédiatement visible, sans avoir à remonter dans le constructeur pour comprendre quels champs sont réellement obligatoires.
Un effet secondaire utile : des constructeurs plus courts
class ArticleFixture {
public string $titre;
public int $auteur_id;
public bool $est_publie = false;
public function __construct( string $titre, int $auteur_id ) {
$this->titre = $titre;
$this->auteur_id = $auteur_id;
}
}
Le type de chaque propriété étant déjà déclaré, le constructeur n’a plus besoin de docblock séparé pour documenter ce qu’il attend : la déclaration de la propriété fait ce travail une seule fois, à un seul endroit, plutôt que de le répéter dans chaque méthode qui manipule l’objet.
Une fixture typée qui échoue à la construction vaut mieux qu’une fixture souple qui échoue trois tests plus loin, sans lien apparent avec l’origine réelle du problème.
Une migration progressive, pas un big bang
Il n’est pas nécessaire de typer toutes les fixtures existantes d’un seul coup. La migration se fait naturellement à chaque nouvelle fixture créée, ou à chaque fois qu’une fixture existante est modifiée pour un autre motif. Les deux styles cohabitent sans problème dans une même base de code, PHP 7.4 n’imposant le typage que sur les propriétés qui le déclarent explicitement.
En résumé
Les propriétés typées de PHP 7.4 transforment une convention purement documentaire en une vérification effective à l’exécution. Pour des objets de valeur utilisés comme fixtures, ce changement rend les erreurs de type immédiates et localisées, réduit la taille des constructeurs, et documente clairement, dans la classe elle-même, quels champs sont obligatoires et lesquels sont réellement optionnels.