В чем разница между is_a и instanceof?

Я знаю, что instanceof является оператором, а метод is_a является методом.

Является ли метод более медленным в производительности? Что бы вы предпочли использовать?

Solutions Collecting From Web of "В чем разница между is_a и instanceof?"

На самом деле is_a – это функция, тогда как instanceof – это языковая конструкция. is_a будет значительно медленнее (поскольку у него есть все накладные расходы на выполнение вызова функции), но общее время выполнения минимально в любом методе.

Он больше не устарел от 5.3, поэтому там не беспокойтесь.

Однако есть одно отличие. is_a является функцией, которая принимает объект как параметр 1 и строку (переменную, константу или литерал) в качестве параметра 2. Итак:

 is_a($object, $string); // <- Only way to call it 

instanceof принимает объект как параметр 1 и может принимать имя класса (переменную), экземпляр объекта (переменную) или идентификатор класса (имя класса, записанное без кавычек) в качестве параметра 2.

 $object instanceof $string; // <- string class name $object instanceof $otherObject; // <- object instance $object instanceof ClassName; // <- identifier for the class 

Вот результаты работы is_a () и instanceof :

 Test name Repeats Result Performance instanceof 10000 0.028343 sec +0.00% is_a() 10000 0.043927 sec -54.98% 

Здесь находится источник тестирования.

instanceof может использоваться с другими экземплярами объекта, именем класса или интерфейсом. Я не думаю, что is_a() работает с интерфейсами (только строка, представляющая имя класса), но исправьте меня, если это произойдет. (Обновление: см. https://gist.github.com/1455148 )

Пример из 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' 

выходы:

 bool(true) bool(true) bool(false) 

Что касается ответа is_a() , is_a() больше не устарел от PHP 5.3.0. Я нахожу, что всегда безопасно идти официальным источником таких вещей.

Что касается вашего вопроса, Даниэль, я не могу сказать о различиях в производительности, но часть его дойдет до читаемости и с которой вам будет легче работать.

Кроме того, есть некоторая дискуссия о путанице вокруг отрицания instanceof проверки vs is_a() . Например, instanceof вы бы сделали:

 <?php if( !($a instanceof A) ) { //... } ?> 

vs для is_a() :

 <?php if( !is_a($a, 'A' ) { //... } ?> 

или

 <?php if( is_a($a, 'A') === FALSE) { //... } ?> 

Редактировать Похоже, что ChrisF удалил свой ответ, но первая часть моего ответа все еще стоит.

Оптимизация минимальна. И микрооптимизации никогда не являются хорошим ответом, перед читабельностью, понятностью и стабильностью кода.

(лично я предпочитаю экземпляр , но выбор за вами;))

Основное отличие заключается в возможности использования прямого имени класса с экземпляром

$ a экземпляр MyClass

короче, чем

is_a ($ a, MyClass :: class)

(хорошо … это не тривиально.)

Синтаксическая окраска между instanceof (структура языка) и is_a тоже полезна (для меня). позволяя цвет функции более крупным операциям. И для однократного использования в if, instanceof не нужно больше скобок.

Примечание. Конечно, вместо класса MyClass :: class вы можете использовать более короткую прямую строку:

is_a ($ а, 'MyClass')

Но использование прямой строки в коде не является хорошей практикой .

Синтаксическое сравнение лучше и полезнее, если вы можете сделать разницу между простыми именами строк и классов. И проще сменить имена с постоянным именем класса. Специально, если вы используете пространство имен с псевдонимом.

Итак, wy use is_a () ?

Для такой же разницы: читаемость и неустранимость. (выбор за вами) Специально при использовании ! или другие логические операторы: is_a кажется более ориентированным с круглыми скобками.

if ($ a AND (! is_a ($ a, MyClass :: class) ИЛИ is_a ($ a, MyOtherClass :: class)))

более читабельна, чем:

if ($ a AND (! ($ a instanceof MyClass) ИЛИ ($ a intanceof MyOtherClass)))

Другая важная причина – когда вам нужно использовать обратный вызов в функциях. (например, array_map …) instanceof не является функцией, это языковая конструкция, поэтому вы не можете использовать ее как обратный вызов.

В тех случаях is_a может быть полезным

Помимо скорости, еще одна важная разница заключается в том, как они обрабатывают крайние случаи.

 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. 

Итак, is_a () выделяет возможные ошибки, в то время как instanceof подавляет их.

Я не могу говорить о производительности – я еще ничего не измерил – но в зависимости от того, что вы пытаетесь, есть ограничения с instanceof . Запомните мой вопрос, совсем недавно, об этом:

PHP 'instanceof' не работает с константой класса

is_a этого я использовал is_a . Мне нравится структура instanceof лучше (я думаю, он читает лучше) и будет продолжать использовать его там, где я могу.

Вот результаты работы, полученные здесь :

instanceof быстрее.

функции

 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'; } 

Время (по 5000 раз)

 0.00573397 // method_1(5) 0.01437402 // method_2(5) 0.00376201 // method_3(5)