Soy consciente de que instanceof
es un operador y que is_a
es un método.
¿Es el método más lento en rendimiento? ¿Qué preferirías usar?
Soy consciente de que instanceof
es un operador y que is_a
es un método.
¿Es el método más lento en rendimiento? ¿Qué preferirías usar?
Respuestas:
Actualizar
A partir de PHP 5.3.9 , la funcionalidad de
is_a()
ha cambiado. La respuesta original a continuación establece queis_a()
debe aceptar unObject
como primer argumento, pero las versiones de PHP> = 5.3.9 ahora aceptan un tercer argumento booleano opcional$allow_string
(por defectofalse
) para permitir comparaciones de nombres de clase de cadena en su lugar:La diferencia clave en el nuevo comportamiento entre
instanceof
yis_a()
es queinstanceof
siempre comprobará que el objetivo es un objeto instanciado de la clase especificada (incluidas las clases extendidas), mientras queis_a()
solo requiere que el objeto se instancia cuando el$allow_string
argumento se establece en el valor predeterminado defalse
.Original
En realidad,
is_a
es una función, mientras queinstanceof
es una construcción del lenguaje.is_a
será significativamente más lento (ya que tiene toda la sobrecarga de ejecutar una llamada de función), pero el tiempo de ejecución general es mínimo en cualquier método.Ya no está en desuso a partir de 5.3, por lo que no hay que preocuparse.
Sin embargo, hay una diferencia.
is_a
ser una función toma un objeto como parámetro 1 y una cadena (variable, constante o literal) como parámetro 2. Entonces:instanceof
toma un objeto como parámetro 1 y puede tomar un nombre de clase (variable), instancia de objeto (variable) o identificador de clase (nombre de clase escrito sin comillas) como parámetro 2.fuente
is_a
desaprobado?$class = 'Foo'; var_dump($obj instanceof $class);
is_a
elinstanceof
operador es queis_a
aceptará expresiones para el segundo parámetro, mientras que instancia de wont. Por ejemplo,is_a($object, 'Prefix_'.$name)
funciona mientras$object instanceof 'Prefix_'.$name
no funcionais_a
nunca debería haber sido desaprobado en primer lugar. Sin embargo, es un poco tarde para arreglarlo ahora. El problema es que elinstanceof
operador arroja errores de sintaxis en PHP 4, y dado queis_a
fue desaprobado exactamente al mismo tiempo que se introdujo el operador, se hizo imposible escribir código para PHP 4 y 5 sin lanzar un E_STRICT. Ni siquiera puede hacerloif (version_compare(PHP_VERSION, 5) >= 0) { /* use instanceof */ } else { /* use is_a */ }
porque aún causaría un error de sintaxis en PHP 4.Aquí están los resultados de rendimiento de is_a () y instanceof :
La fuente de prueba está aquí .
fuente
php 7
no hay diferencia.instanceof
se puede usar con otras instancias de objetos, el nombre de la clase o una interfaz.No creo que(Actualización: consulte https://gist.github.com/1455148 )is_a()
funcione con interfaces (solo una cadena que representa un nombre de clase), pero corrígeme si lo hace.Ejemplo de php.net :
salidas:
fuente
is_a
funciona con interfaces de la misma manera queinstanceof
(iba a decir lo mismo, pero lo verifiqué antes de enviarlo, y de hecho funciona) ...En lo que respecta a la respuesta de ChrisF,
is_a()
ya no está en desuso a partir de PHP 5.3.0. Creo que siempre es más seguro recurrir a la fuente oficial para cosas como esta.Con respecto a su pregunta, Daniel, no puedo decir sobre las diferencias de rendimiento, pero parte de esto se reducirá a la legibilidad y con la que le resultará más fácil trabajar.
Además, existe cierto debate acerca de la confusión en torno a la negación de un
instanceof
cheque vsis_a()
. Por ejemplo, parainstanceof
usted haría:vs lo siguiente para
is_a()
:o
Editar Parece que ChrisF eliminó su respuesta, pero la primera parte de mi respuesta sigue en pie.
fuente
Además de la velocidad, otra diferencia importante es cómo manejan los casos extremos.
Entonces, is_a () resalta posibles errores, mientras que instanceof los suprime.
fuente
La optimización es mínima. Y las micro optimizaciones nunca son una buena respuesta, frente a la legibilidad, la comprensión y la estabilidad del código.
(Personalmente prefiero instancia de , pero la elección es suya;))
La principal diferencia es la posibilidad de usar el nombre de clase directo con instanceof
es más corto que
(ok ... no es trivial)
La coloración sintáctica entre instanceof (estructura del lenguaje) e is_a también es útil (para mí). dejando el color de la función para operaciones más grandes. Y para un solo uso en if, instancia de dos no necesita más paréntesis.
Nota: Por supuesto, en lugar de MyClass :: class puede usar una cadena directa más corta:
Pero usar una cadena directa en un código no es una buena práctica .
La colocación sintáctica es mejor y más útil si puede hacer una diferencia entre una cadena simple y nombres de clases. Y es más fácil cambiar nombres con nombre de clase constante. Especialmente si usa el espacio de nombres con alias.
Entonces, ¿por qué usar is_a () ?
Por la misma razón: legibilidad e inteligibilidad. (la elección es suya) Especialmente cuando se usa con ! u otros operadores booleanos: is_a parece más práctico con paréntesis.
es más legible que:
Otra buena razón es cuando necesita usar la devolución de llamada en las funciones. (como array_map ...) instanceof no es una función, es una construcción de lenguaje, por lo que no puede usarla como devolución de llamada.
En estos casos, is_a puede ser útil
fuente
No puedo hablar por el rendimiento, todavía no he medido nada, pero dependiendo de lo que esté intentando, existen limitaciones con
instanceof
. Mira mi pregunta, recientemente, al respecto:PHP 'instanceof' falla con constante de clase
Terminé usando en su
is_a
lugar. Me gusta la estructura deinstanceof
mejor (creo que se lee mejor) y continuaré usándola donde pueda.fuente
Aquí están los resultados de rendimiento obtenidos de aquí :
instanceof
es más rápido.Las funciones
Tiempos (ejecutados 5000 veces cada uno)
fuente
Hay un escenario donde solo
is_a()
funciona yinstanceof
fallará.instanceof
espera un nombre de clase literal o una variable que sea un objeto o una cadena (con el nombre de una clase) como argumento correcto.Pero si desea proporcionar la cadena de un nombre de clase de una llamada de función, no funcionará y dará como resultado un error de sintaxis.
Sin embargo, el mismo escenario funciona bien con
is_a()
.Ejemplo:
Esto se basa en PHP 7.2.14.
fuente