web-dev-qa-db-fra.com

Renvoyer NULL avec les déclarations de type de retour

J'étais en train de refactoriser une base de code pour l'utiliser avec PHP7, en particulier en implémentant des indications de type scalaire et des indications de type en retour, lorsque j'ai rencontré un problème.

J'ai une classe avec quelques propriétés, dont une id. Cet identifiant n'est pas obligatoire (vous pouvez construire un objet sans définir l'identifiant). Lors de la création d'un nouvel objet de cette classe, vous ne définissez pas l'identifiant. Il obtient un identifiant dès qu'il est inséré dans la base de données (par une classe de mappeur distincte).

Cette classe de mappeur doit vérifier si l'objet existe déjà dans la base de données et vérifie si l'identifiant est défini:

if(empty($exampleObject->getId())) {
    // Insert object
} else {
    // Update object
}

J'appliquais des indications de type de retour à chaque fonction de ma base de code et le problème est que la fonction getId() ne peut pas renvoyerNULLsi j'applique un type int return. Il TypeErrors, même sans avoir activé le typage strict:

Erreur fatale : Uncaught TypeError: la valeur renvoyée par ExampleClass :: getId () doit être du type entier, null renvoyé

J'ai envisagé de ne pas définir d'indicateur de type de retour pour ce getter, mais je me suis alors rendu compte que le problème n'était probablement pas l'indication de type de retour, mais le fait que j'utilise des types de retour mélangés. Je me souviens avoir lu quelque part que l’utilisation de types à rendement mixte était une mauvaise chose, mais je ne savais pas trop comment y remédier sans utiliser des types à rendement mixte. Je pouvais:

  • Lancez une exception dans le getter et concevez la vérification dans la classe de mappeur afin qu'elle capture cette exception.
  • Attrapez l'exception TypeError et utilisez-la pour indiquer que l'ID n'est pas défini.
  • Rendez la propriété id publique, pour que je puisse appeler isset directement à ce sujet.
  • Ajouter une méthode différente hasId() return isset($this->id)

Franchement, je n'aime pas vraiment l'une de ces solutions, et je me demandais s'il y avait une meilleure option. Quelle est la meilleure pratique pour des cas comme celui-ci?

De plus, ne devrais-je pas obtenir une erreur TypeError uniquement si le typage strict est activé? Je pensais que PHP7 utilisait par défaut les "indications de type faibles".

15
Compizfox

PHP 7.1 ajouté nullable types , où vous mettez un point d'interrogation avant le nom du type pour marquer le type de retour comme acceptant à la fois ce type et la valeur null:

public function getId(): ?int {
    /* … */
}

Si vous êtes toujours sur PHP 7.0, je vous suggère d'omettre la déclaration de type et d'utiliser un docblock.

24
Andrea

Utiliser null signifie utiliser des approches orientées objet car les types de valeur ne peuvent pas être null. Il pourrait donc être utile d’utiliser le wrapper de classe autour du type entier. Par exemple, SplInt de types SPL.

0
max