Soy consciente de que instanceof
es un operador y que is_a
es un método.¿Cuál es la diferencia entre is_a y instanceof?
¿El método es 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.¿Cuál es la diferencia entre is_a y instanceof?
¿El método es más lento en rendimiento? ¿Qué preferirías usar?
realidad, is_a
es una función, mientras que instanceof
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 cualquiera de los métodos.
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. Así:
is_a($object, $string); // <- Only way to call it
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 la clase escrito sin comillas) como parámetro 2.
$object instanceof $string; // <- string class name
$object instanceof $otherObject; // <- object instance
$object instanceof ClassName; // <- identifier for the class
¿Por qué 'is_a' no se preparó? –
@ theodore-r-smith De acuerdo con la documentación, "ha sido ignorada por petición popular" http://php.net/manual/en/migration53.undeprecated.php – Janci
instanceof puede tomar una cadena como parámetro, objeto o un identificador (nombre de clase escrito sin comillas) @ircmaxell - ¿puedes dar un ejemplo de cadena como parámetro? – danidacar
instanceof
se puede utilizar con otras instancias de objetos, el nombre de la clase o una interfaz.
No creo que
(Actualización: Ver 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:
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';
var_dump($a instanceof $b); // $b is an object of class MyClass
var_dump($a instanceof $c); // $c is a string 'MyClass'
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
salidas:
bool(true)
bool(true)
bool(false)
'is_a' funciona con interfaces de la misma manera que' instanceof' (Iba a decir lo mismo, pero lo comprobé antes de enviar, y de hecho funciona) ... – ircmaxell
-1 resuma la actualización en lugar de simplemente vinculando a una esencia. Eso no ayuda a las personas que intentan aprender. –
no puedo hablar por el rendimiento - no he medido nada todavía - pero dependiendo en lo que está intentando, hay limitaciones con instanceof
. Echa un vistazo a mi pregunta, hace poco, al respecto:
PHP 'instanceof' failing with class constant
he terminado usando is_a
lugar. Me gusta más la estructura de instanceof
(creo que se lee mejor) y la seguiré usando donde pueda.
En cuanto a la respuesta de ChrisF, is_a()
is no longer deprecated a partir de PHP 5.3.0. Creo que siempre es más seguro recurrir a la fuente oficial para este tipo de cosas.
Con respecto a su pregunta, Daniel, no puedo decir acerca de las diferencias de rendimiento, pero parte de esto se reducirá a la legibilidad y con la que le resultará más fácil trabajar.
También, there is some discussion sobre la confusión alrededor de negar un instanceof
cheque contra is_a()
.Por ejemplo, para instanceof
puede hacer:
<?php
if(!($a instanceof A)) { //... }
?>
vs lo siguiente para is_a()
:
<?php
if(!is_a($a, 'A') { //... }
?>
o
<?php
if(is_a($a, 'A') === FALSE) { //... }
?>
Editar Parece que ChrisF borra su respuesta, pero la primera parte de mi respuesta sigue en pie.
Aquí se ofrecen los resultados de rendimiento de is_a() y instanceof:
Test name Repeats Result Performance
instanceof 10000 0.028343 sec +0.00%
is_a() 10000 0.043927 sec -54.98%
fuente de prueba es here.
Éstos son los resultados de rendimiento obtenidos de here:
instanceof
es más rápido.
Funciones
function method_1($a = null) {
return is_object($a) && is_a($a, 'Example');
}
function method_2($a = null) {
return is_a((object) $a, 'Example');
}
function method_3($a = null) {
return $a instanceof 'Example';
}
tiempos de ejecución (5000 veces cada uno)
0.00573397 // method_1(5)
0.01437402 // method_2(5)
0.00376201 // method_3(5)
La optimización es mínima. Y las micro-optimizaciones nunca son una buena respuesta, frente a la legibilidad, comprensibilidad y estabilidad del código.
(personalmente me préféré instanceof, pero la elección es suya;))
La principal diferencia es la posibilidad de utilizar el nombre de clase directa con instanceof
$ un instanceof MiClase
es más corto que
is_a ($ clase, MyClass ::)
(bien ... no es trivial.)
La coloración sintáctica entre instanceof (estructura del lenguaje) e is_a también es útil (para mí). dejando que el color de la función funcione mejor. Y para un solo uso en if, instanciade dosn't necesita más paréntesis.
Nota: Por supuesto, en lugar de MyClass :: clase se puede utilizar una cadena directa más corta:
is_a ($ a, 'MiClase')
Pero utilizar cuerdas en directo un código no es una buena práctica.
La colocación sintáctica es mejor y más útil si se puede hacer una diferencia entre cadenas simples y nombres de clases. Y es más fácil cambiar los nombres con el nombre de clase constante. Especialmente si usa el espacio de nombres con alias.
Entonces, wy usa is_a()?
Por la misma razón: legibilidad y facilidad de lectura. (la elección es suya) Especialmente cuando se usa con ! u otros operadores booleanos: is_a parece más práctico con paréntesis.
if (! $ A y (is_a ($ a, MyClass :: clase) O is_a ($ a, MyOtherClass :: clase)))
es más fácil de leer que:
if ($ a Y (! ($ a MiClase instanceof) O ($ a MyOtherClass intanceof)))
otra buena razón es cuando se necesita utilizar devolución de llamada en funciones. (como array_map ...) instanceof instancia no es una función, es una construcción de lenguaje, por lo que no puede utilizarlo como devolución de llamada.
En ver estos casos, is_a puede ser útil
Además de la velocidad, otra diferencia importante es la forma en que manejan casos extremos.
is_a($x1, $x2) // fatal error if x2 is not a string nor an object
$x1 instanceof $x2 // returns false even if $x2 is int, undefined, etc.
Así, is_a() resalta los posibles errores mientras que instanceof los suprime.
is_a() podría ser más lento, pero puede llamarlo usando call_user_func() mientras instanceof no se puede llamar de esta manera ... –
+1 para vincular a la documentación en su pregunta. – cloudfeet