2010-06-10 17 views
155

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?

+11

is_a() podría ser más lento, pero puede llamarlo usando call_user_func() mientras instanceof no se puede llamar de esta manera ... –

+9

+1 para vincular a la documentación en su pregunta. – cloudfeet

Respuesta

162

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 
+27

¿Por qué 'is_a' no se preparó? –

+17

@ 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

+1

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

7

instanceof se puede utilizar con otras instancias de objetos, el nombre de la clase o una interfaz. No creo que is_a() funcione con interfaces (solo una cadena que representa un nombre de clase), pero corrígeme si lo hace. (Actualización: Ver https://gist.github.com/1455148)

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) 
+2

'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

-1 resuma la actualización en lugar de simplemente vinculando a una esencia. Eso no ayuda a las personas que intentan aprender. –

1

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.

3

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.

39

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.

1

É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) 
2

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

2

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.

Cuestiones relacionadas