2008-09-26 10 views
3

PHP, comme nous le savons tous est très faiblement typé. Le langage ne vous oblige pas à spécifier un type de type pour les paramètres de fonction ou les variables de classe. Cela peut être une fonctionnalité puissante. Parfois, cependant, il peut rendre le débogage de votre script une expérience douloureuse. Par exemple, le passage d'un type d'objet dans une méthode qui attend un type d'objet différent peut produire des messages d'erreur se plaignant qu'une certaine variable/méthode n'existe pas pour l'objet transmis. Ces situations sont principalement des ennuis. Les problèmes les plus onéreux sont lorsque vous initialisez un objet avec un objet de la mauvaise classe, et que "mauvais objet" ne sera pas utilisé plus tard dans l'exécution du script. Dans ce cas, vous obtenez une erreur beaucoup plus tard que lorsque vous avez passé l'argument d'origine. Plutôt que de me plaindre que ce que j'ai passé n'a pas de méthode ou variable spécifique, ou d'attendre beaucoup plus tard dans l'exécution du script pour que l'objet passé soit utilisé, Je préfère recevoir un message d'erreur, à exactement où je spécifie un objet du mauvais type, se plaignant du type de l'objet étant incorrect ou incompatible.Comment empêcher l'utilisation du type incorrect en PHP?

Comment gérez-vous ces situations dans votre code? Comment détectez-vous les types incompatibles? Comment puis-je introduire une vérification de type dans mes scripts afin que je puisse obtenir des messages d'erreur plus faciles à comprendre?

Aussi, comment pouvez-vous faire tout cela en tenant compte de l'héritage dans Php? Tenir compte:

<?php 
class InterfaceClass 
{ 
#... 
} 

class UsesInterfaceClass 
{ 
    function SetObject(&$obj) 
    { 
     // What do I put here to make sure that $obj either 
     // is of type InterfaceObject or inherits from it  

    } 
} 
?> 

Ensuite, un utilisateur de ce code implémente l'interface avec leur propre classe concrète:

<?php 

class ConcreteClass extends InterfaceClass 
{ 
} 



?> 

Je veux des instances ConcreteClass, et tous les futurs, les objets définis par l'utilisateur inconnus, aussi acceptable à SetObject. Comment rendriez-vous cela admissible en vérifiant le bon type?

Répondre

11

En fait, pour les classes, vous pouvez fournir des indications de type en PHP (5+).

<?php 
class UsesBaseClass 
{ 
     function SetObject(InterfaceObject $obj) 
     { 
     } 
} 
?> 

Cela fonctionnera également correctement avec l'héritage comme vous le souhaitez.

En aparté, ne pas mettre le mot « objet » dans vos noms de classe ...

4

comme un ajout à la réponse de Eran Galperin vous pouvez également utiliser le type hinting pour forcer les paramètres à être des tableaux - pas juste des objets d'une certaine classe.

<?php 
class MyCoolClass { 
    public function passMeAnArray(array $array = array()) { 
     // do something with the array 
    } 
} 
?> 

Comme vous pouvez le voir, vous pouvez taper allusion au fait que la méthode ::passMeAnArray() attend un array ainsi que de fournir une valeur par défaut dans le cas où la méthode est appelée w/o les paramètres.

1

@Eran Galperin La réponse est la méthode préférée pour s'assurer que l'objet que vous utilisez est du type correct.

Notez également l'opérateur instanceOf - il est utile lorsque vous souhaitez vérifier qu'un objet est l'un de plusieurs types.

+0

instanceof est utile. Rappelez-vous juste de ne pas en abuser. –

0

Vous pouvez définir le paramètre ini error_reporting dans votre php.fichier ini ou utiliser la fonction error_reporting pour le définir en temps d'exécution

1

Vous voyez, il y a plusieurs réponses à propos de indice de type. Ceci est la solution technique. Mais vous devez également vous assurer que tout le design est sensé et intuitif. Cela rendra les problèmes de type et les erreurs plus rares. N'oubliez pas que même ces échecs de type seront lancés au moment de l'exécution

Assurez-vous d'avoir des tests pour le code.

1

Même dans le cas que vous décrivez, votre script va planter, se plaignant qu'il n'y a pas de méthode/attribut X sur l'objet Y, donc vous saurez d'où cela vient. Quoi qu'il en soit, je pense que toujours essayer d'empêcher les programmeurs de passer le mauvais objet à une méthode n'est pas un bon investissement en temps: vous pouvez le dépenser en documentation et en entraînement.

Le typage de canards et les collègues attentifs sont ce dont vous avez besoin, pas de contrôles supplémentaires qui vous rendront plus rigide.

Mais il peut être un point de vue Pythonista ...

2

Pour les types primitifs, vous pouvez également utiliser le is_ * Fonctions:

public function Add($a, $b) 
{ 
    if (!is_int($a) || !is_int($b)) 
    throw new InvalidArgumentException(); 
    return $a + $b; 
} 
Questions connexes