What is the difference between is_a and instanceof?
Update
As of PHP 5.3.9, the functionality of is_a()
has changed. The original answer below states that is_a()
must accept an Object
as the first argument, but PHP versions >= 5.3.9 now accept an optional third boolean argument $allow_string
(defaults to false
) to allow comparisons of string class names instead:
class MyBaseClass {}
class MyExtendingClass extends MyBaseClass {}
// Original behavior, evaluates to false.
is_a(MyExtendingClass::class, MyBaseClass::class);
// New behavior, evaluates to true.
is_a(MyExtendingClass::class, MyBaseClass::class, true);
The key difference in the new behavior between instanceof
and is_a()
is that instanceof
will always check that the target is an instantiated object of the specified class (including extending classes), whereas is_a()
only requires that the object be instantiated when the $allow_string
argument is set to the default value of false
.
Original
Actually, is_a
is a function, whereas instanceof
is a language construct. is_a
will be significantly slower (since it has all the overhead of executing a function call), but the overall execution time is minimal in either method.
It's no longer deprecated as of 5.3, so there's no worry there.
There is one difference however. is_a
being a function takes an object as parameter 1, and a string (variable, constant, or literal) as parameter 2. So:
is_a($object, $string); // <- Only way to call it
instanceof
takes an object as parameter 1, and can take a class name (variable), object instance (variable), or class identifier (class name written without quotes) as parameter 2.
$object instanceof $string; // <- string class name
$object instanceof $otherObject; // <- object instance
$object instanceof ClassName; // <- identifier for the class
Ruby: kind_of? vs. instance_of? vs. is_a?
kind_of?
and is_a?
are synonymous.
instance_of?
is different from the other two in that it only returns true
if the object is an instance of that exact class, not a subclass.
Example:
"hello".is_a? Object
and"hello".kind_of? Object
returntrue
because"hello"
is aString
andString
is a subclass ofObject
.- However
"hello".instance_of? Object
returnsfalse
.
What's the best way to determine if a variable is a particular object?
It depends on what you really want to check.
get_class check will tell you if given object is of given class. instanceof operator on the other hand will tell you, if given object is of given class OR has that class in it's inheritance tree OR implements given interface.
Some examples:
class Parent {}
class Child extends Parent {}
$obj = new Child;
var_dump($obj instanceof Parent); // true
var_dump(get_class($obj) === 'Parent'); // false
var_dump($obj instanceof Child); // true
var_dump(get_class($obj) === 'Child'); // true
So both ways can be used depending on what you need.
Regarding is_a(), it behaves the same way as instanceof operator, but is know to be a bit slower. In bigger applications the difference in performance will be negligible.
instanceof offers more flexibility. While is_a() only accepts string as its second argument, instanceof can be passed a string, an object or class identifier.
What is the difference between `this instanceof String` and `foo instanceof String`?
First of all, you cannot apply instanceof
to primitive values, that's why
"foo" instanceof String
returns false
. Primitives are not objects and hence cannot be an instance of a constructor function. *
So why does it seem to work inside the is_a
method?
In non-strict mode, the value of this
inside a function is always going to be an object (step 3). If this
value is not an object, it is implicitly converted to one. You can test this with console.log(typeof this)
.
That means that the string primitive "foo"
is converted to an String object new String("foo")
and that's why you can use instanceof
on it.
In strict mode, the value of this
doesn't have to be an object and is not automatically converted (step 1). Your method would fail in that case:
> Object.prototype.is_a = function (x) {
'use strict';
return this instanceof x;
}
> "foo".is_a(String)
false
*: That's a very simplified explanation. In reality, the instanceof
operator delegates the evaluation to the constructor function's internal [[HasInstance]]
method, which is defined to return false
if the passed value is not an object.
PHP instanceof and is_a when checking error object
It seems that instanceof
needs fully qualified classname. So this should work.
function throwException($exception = null)
{
$message = "";
if ($exception instanceof \MyNameSpace\Exception\ValidationException) {
$message .= "One";
}
if (is_a($exception, 'MyNameSpace\Exception\ValidationException')) {
$message .= "Two";
}
return $message;
}
Or
use MyNameSpace\Exception\ValidationException;
function throwException($exception = null)
{
$message = "";
if ($exception instanceof ValidationException) {
$message .= "One";
}
if (is_a($exception, 'MyNameSpace\Exception\ValidationException')) {
$message .= "Two";
}
return $message;
}
What is the meaning of the `allow_string` argument to `is_a`?
The answer has to do with subclassing. In PHP 5.3.7 is_a
changed so that if the first argument was not an object, PHP would __autoload
that argument, effectively attempting to make it an object:
> class A {}
> class B extends A {}
> echo is_a('B', 'A');
> // nada
> echo is_a('B', 'A', true);
1
Needless to say, that can lead to some unexpected side-effects and slowdowns, so adding the third argument gives you the choice about which behavior you want.
This all probably started when someone discovered that is_a
and subclass_of
don't behave exactly like instanceof
.
Check if variable which stores name of a class is an instanceof a class
Question:Check if variable which stores name of a class is an instanceof a class
My answer:
If a variable stores a name of a class it cannot be instance of that class because it's a string!
What you might wanted:
Check if variable stores a name of existing class
Solution to that:
if (class_exists($myclass)) { ... }
Related Topics
PHP Preg_Match - Only Allow Alphanumeric Strings and - _ Characters
Dyld: Library Not Loaded: /Usr/Local/Lib/Libjpeg.8.Dylib - Homebrew PHP
How to Rename Column in Laravel Using Migration
Array Merge on Multidimensional Array
Using Xampp, How to Swap Out PHP 5.3 for PHP 5.2
Why Is It Good Save to Save Sessions in the Database
Minifying Final HTML Output Using Regular Expressions with Codeigniter
Storage in Laravel Says Symlink - No Such File
How to Display Woocommerce Category Image
Symfony2 Collection of Entities - How to Add/Remove Association with Existing Entities
Find Duplicate Value in Multi-Dimensional Array
PHP Allocate Color Without Image Resource
Fatal Error - Too Many Open Files
In Laravel How to Add Values to a Request Array
Best Way to Check If a Url Is Valid
Send Email with a Template Using PHP