Я знаю, что instanceof
является оператором, а метод is_a
является методом.
Является ли метод более медленным в производительности? Что бы вы предпочли использовать?
На самом деле 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
может использоваться с другими экземплярами объекта, именем класса или интерфейсом. Я не думаю, что (Обновление: см. https://gist.github.com/1455148 ) is_a()
работает с интерфейсами (только строка, представляющая имя класса), но исправьте меня, если это произойдет.
Пример из 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)