Je sais que instanceof
c'est un opérateur et c'est is_a
une méthode.
Les performances de la méthode sont-elles plus lentes? Que préférez-vous utiliser?
Je sais que instanceof
c'est un opérateur et c'est is_a
une méthode.
Les performances de la méthode sont-elles plus lentes? Que préférez-vous utiliser?
Réponses:
Mettre à jour
Depuis PHP 5.3.9 , la fonctionnalité de
is_a()
a changé. La réponse d'origine ci-dessous indique queis_a()
doit accepter unObject
comme premier argument, mais les versions PHP> = 5.3.9 acceptent désormais un troisième argument booléen facultatif$allow_string
(par défautfalse
) pour permettre des comparaisons de noms de classe de chaînes à la place:La principale différence dans le nouveau comportement entre
instanceof
etis_a()
est qu'ilinstanceof
vérifie toujours que la cible est un objet instancié de la classe spécifiée (y compris les classes d'extension), alors qu'ilis_a()
ne nécessite que l'objet soit instancié lorsque l'$allow_string
argument est défini sur la valeur par défaut defalse
.Original
En fait,
is_a
c'est une fonction, alors queinstanceof
c'est une construction de langage.is_a
sera beaucoup plus lent (car il a tous les frais généraux d'exécution d'un appel de fonction), mais le temps d'exécution global est minimal dans l'une ou l'autre méthode.Il n'est plus obsolète à partir de la version 5.3, il n'y a donc pas de souci là-bas.
Il y a cependant une différence.
is_a
être une fonction prend un objet comme paramètre 1 et une chaîne (variable, constante ou littérale) comme paramètre 2. Donc:instanceof
prend un objet comme paramètre 1 et peut prendre un nom de classe (variable), une instance d'objet (variable) ou un identificateur de classe (nom de classe écrit sans guillemets) comme paramètre 2.la source
is_a
obsolète?$class = 'Foo'; var_dump($obj instanceof $class);
is_a
l'instanceof
opérateur est qu'ilis_a
acceptera des expressions pour le deuxième paramètre, tandis que instanceof ne le fera pas. Par exemple,is_a($object, 'Prefix_'.$name)
fonctionne tout en$object instanceof 'Prefix_'.$name
ne pasis_a
n'aurait jamais dû être déprécié en premier lieu. Il est un peu tard pour le réparer maintenant. Le problème est que l'instanceof
opérateur jette des erreurs de syntaxe dans PHP 4, et depuis qu'ilis_a
était obsolète en même temps que l'opérateur a été introduit, il est devenu impossible d'écrire du code pour PHP 4 et 5 sans lancer un E_STRICT. Vous ne pouvez même pas le faireif (version_compare(PHP_VERSION, 5) >= 0) { /* use instanceof */ } else { /* use is_a */ }
car cela provoquerait toujours une erreur de syntaxe en PHP 4.Voici les résultats de performance de is_a () et instanceof :
La source du test est ici .
la source
php 7
il n'y a pas de différence.instanceof
peut être utilisé avec d'autres instances d'objet, le nom de la classe ou une interface.Je ne pense pas que cela(Mise à jour: voir https://gist.github.com/1455148 )is_a()
fonctionne avec les interfaces (seulement une chaîne représentant un nom de classe), mais corrigez-moi si c'est le cas.Exemple de php.net :
les sorties:
la source
is_a
fonctionne avec les interfaces de la même manière queinstanceof
(j'allais dire la même chose, mais je l'ai vérifié avant de soumettre, et cela fonctionne en effet) ...En ce qui concerne la réponse de ChrisF,
is_a()
n'est plus obsolète depuis PHP 5.3.0. Je trouve qu'il est toujours plus sûr de consulter la source officielle pour des choses comme ça.En ce qui concerne votre question, Daniel, je ne peux pas dire sur les différences de performances, mais une partie se résumera à la lisibilité et avec laquelle vous trouverez plus facile à travailler.
En outre, il y a une discussion au sujet de la confusion autour de la négation d' un
instanceof
chèque vsis_a()
. Par exemple,instanceof
vous feriez:vs ce qui suit pour
is_a()
:ou
Modifier On dirait que ChrisF a supprimé sa réponse, mais la première partie de ma réponse est toujours valable.
la source
Outre la vitesse, une autre différence importante réside dans la façon dont ils gèrent les boîtiers de bord.
Ainsi, is_a () met en évidence les bogues possibles tandis que instanceof les supprime.
la source
L'optimisation est minime. Et les micro-optimisations ne sont jamais une vraie bonne réponse, devant la lisibilité, l'intelligibilité et la stabilité du code.
(personnellement, je préfère l' instance , mais le choix vous appartient;))
La principale différence est la possibilité d'utiliser un nom de classe direct avec instanceof
est plus court que
(ok… ce n'est pas anodin.)
La coloration syntaxique entre instanceof (structure du langage) et is_a est également utile (pour moi). laissant la fonction colorer à des opérations plus importantes. Et pour une utilisation unique dans if, instanceof n'a pas besoin de plus de parenthèses.
Remarque: Bien sûr, au lieu de MyClass :: class, vous pouvez utiliser une chaîne directe plus courte:
Mais utiliser une chaîne directe dans un code n'est pas une bonne pratique .
La collation syntaxique est meilleure et plus utile si vous pouvez faire la différence entre une chaîne simple et des noms de classes. Et il est plus facile de changer les noms avec un nom de classe constant. Spécialement si vous utilisez un espace de noms avec un alias.
Alors, pourquoi utiliser is_a () ?
Pour la même raison: lisibilité et incompréhension. (à vous de choisir) Spécialement utilisé avec ! ou d'autres opérateurs booléens: is_a semble plus pratique avec des parenthèses.
est plus lisible que:
Une autre bonne raison est lorsque vous devez utiliser le rappel dans les fonctions. (comme array_map …) instanceof n'est pas une fonction, c'est une construction de langage, vous ne pouvez donc pas l'utiliser comme rappel.
Dans ces cas, is_a peut être utile
la source
Je ne peux pas parler de performance - je n'ai encore rien mesuré - mais selon ce que vous essayez, il y a des limites avec
instanceof
. Découvrez ma question, récemment, à ce sujet:PHP 'instanceof' échoue avec la constante de classe
J'ai fini par utiliser à la
is_a
place. J'aime la structure deinstanceof
mieux (je pense que ça se lit mieux) et je continuerai de l'utiliser quand je le pourrai.la source
Voici les résultats de performance obtenus à partir d' ici :
instanceof
est plus rapide.Les fonctions
Heures (exécutées 5000 fois chacune)
la source
Il existe un scénario où seul
is_a()
fonctionne etinstanceof
échouera.instanceof
attend un nom de classe littéral ou une variable qui est soit un objet soit une chaîne (avec le nom d'une classe) comme argument de droite.Mais si vous souhaitez fournir la chaîne d'un nom de classe à partir d'un appel de fonction, cela ne fonctionnera pas et entraînera une erreur de syntaxe.
Cependant, le même scénario fonctionne bien avec
is_a()
.Exemple:
Ceci est basé sur PHP 7.2.14.
la source