The PHP parser generates a parse error on either of the two lines that are commented out here.
Apparently the 'instanceof' construct will take a string variable in the second spot, but it will NOT take a string... lame
class Bar {}
$b = new Bar;
$b_class = "Bar";
var_export($b instanceof Bar); // this is ok
var_export($b instanceof $b_class); // this is ok
//var_export($f instanceof "Bar"); // this is syntactically illegal
//var_export($f instanceof 'Bar'); // this is syntactically illegal
型演算子
instanceof を使用して、 ある PHP 変数が特定の クラス のオブジェクトのインスタンスであるかどうかを調べます。
例1 クラスでの instanceof の使用法
<?php
class MyClass
{
}
class NotMyClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof NotMyClass);
?>
上の例の出力は以下となります。
bool(true) bool(false)
instanceof は、ある変数が 特定の親クラスを継承したクラスのオブジェクトのインスタンスであるかどうかを調べることもできます。
例2 継承したクラスでの instanceof の使用法
<?php
class ParentClass
{
}
class MyClass extends ParentClass
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>
上の例の出力は以下となります。
bool(true) bool(true)
あるオブジェクトが特定のクラスのインスタンスで ない ことを調べるには、 論理 否定 演算子 を使用します。
例3 instanceof を使用して、オブジェクトがクラスのインスタンスで ない かどうかを調べる方法
<?php
class MyClass
{
}
$a = new MyClass;
var_dump(!($a instanceof stdClass));
?>
上の例の出力は以下となります。
bool(true)
最後に、instanceof は、ある変数が特定の インターフェイス を実装したクラスのオブジェクトのインスタンスであるかどうかも調べることができます。
例4 クラスでの instanceof の使用法
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
var_dump($a instanceof MyClass);
var_dump($a instanceof MyInterface);
?>
上の例の出力は以下となります。
bool(true) bool(true)
通常、instanceof ではリテラルのクラス名を使用しますが、 別のオブジェクトや文字列変数を使用することもできます。
例5 変数を用いた instanceof の使用法
<?php
interface MyInterface
{
}
class MyClass implements MyInterface
{
}
$a = new MyClass;
$b = new MyClass;
$c = 'MyClass';
$d = 'NotMyClass';
var_dump($a instanceof $b); // $b MyClass クラスのオブジェクトです
var_dump($a instanceof $c); // $c は文字列 'MyClass' です
var_dump($a instanceof $d); // $d は文字列 'NotMyClass' です
?>
上の例の出力は以下となります。
bool(true) bool(true) bool(false)
注意すべき落とし穴があります。PHP 5.1.0 より前のバージョンでは、 instanceof は、クラス名が存在しない場合に __autoload() をコールしていました。 さらに、クラスが読み込めなかった場合に致命的なエラーが発生していました。 この問題の回避策としては、動的なクラス参照 を使用するか、クラス名を含む文字列変数を使用します。
例6 PHP 5.0 における、クラス名検索時の致命的エラーの回避策
<?php
$d = 'NotMyClass';
var_dump($a instanceof $d); // これで、致命的なエラーは発生しません
?>
上の例の出力は以下となります。
bool(false)
instanceof 演算子は PHP 5 から使用可能になりました。 それ以前には is_a() が使用されていましたが、 現在は is_a() は推奨されておらず、 instanceof の使用が推奨されています。
get_class() および is_a() も参照ください。
型演算子
18-Jan-2008 01:59
20-Jul-2007 06:56
Response to vinyanov at poczta dot onet dot pl:
You mentionned "the instanceof operator will not accept a string as its first operand". However, this behavior is absolutely right and therefore, you're misleading the meaning of an instance.
<?php 'ClassA' instanceof 'ClassB'; ?> means "the class named ClassA is an instance of the class named ClassB". This is a nonsense sentence because when you instanciate a class, you ALWAYS obtain an object. Consequently, you only can ask if an object is an instance of a class.
I believe asking if "a ClassA belongs to a ClassB" (or "a ClassA is a class of (type) ClassB") or even "a ClassA is (also) a ClassB" is more appropriate. But the first is not implemented and the second only works with objects, just like the instanceof operator.
Plus, I just have tested your code and it does absolutely NOT do the same as instanceof (extended to classes)! I can't advise anyone to reuse it. The use of <?php is_instance_of ($instanceOfA, 'ClassB'); ?> raises a warning "include_once(Object id #1.php) …" when using __autoload (trying to look for $instanceOfA as if it was a class name).
Finally, here is a fast (to me) sample function code to verify if an object or class:
<?php
function kind_of (&$object_or_class, $class)
{
return is_object ($object_or_class) ?
$object_or_class instanceof $class
: (is_subclass_of ($object_or_class $class)
|| strtolower ($object_or_class) == strtolower ($class));
}
?>
11-Jul-2007 10:50
Posting this so the word typeof appears on this page, so that this page will show up when you google 'php typeof'. ...yeah, former Java user.
19-Jun-2007 03:57
Unfortunately the instanceof operator will not accept a string as its first operand. So I wrote this function. It does exactly the same (ie, successively checks identicalness, inheritance and implementation). Just on strings.
<?php
function is_instance_of($sub, $super)
{
$sub = (string)$sub;
$super = is_object($super) ? get_class($super) : (string)$super;
switch(true)
{
case $sub === $super; // well ... conformity
case is_subclass_of($sub, $super):
case in_array($super, class_implements($sub)):
return true;
default:
return false;
}
}
// testing
interface X {}
class A {}
class B extends A {}
class C extends B {}
class D implements X {}
$i = 'is_instance_of';
var_dump($i('A', 'A'), $i('B', 'A'), $i('C', 'A'), $i('D', 'X'));
?>
13-Mar-2007 01:34
Cross version function even if you are working in php4
(instanceof is an undefined operator for php4)
function isMemberOf($classename) {
$ver = floor(phpversion());
if($ver > 4) {
$instanceof = create_function ('$obj,$classname','return $obj instanceof $classname;');
return $instanceof($this,$classname);
} else {
// Php4 uses lowercase for classname.
return is_a($this, strtolower($classname));
}
} // end function isMemberOf
03-Mar-2007 04:04
Please note: != is a separate operator with separate semantics. Thinking about language grammar it's kind of ridicilous to negate an operator. Of course, it's possible to negate the result of a function (like is_a()), since it isn't negating the function itself or its semantics.
instanceof is a binary operator, and so used in binary terms like this
terma instanceof termb
while ! (negation) is a unary operator and so may be applied to a single term like this
!term
And a term never consists of an operator, only! There is no such construct in any language (please correct me!). However, instanceof doesn't finally support nested terms in every operand position ("terma" or "termb" above) as negation does:
!!!!!!!!!!!!!!term == term
So back again, did you ever write
a !!!!!!!!!!!!= b
to test equivalence?
05-Dec-2006 08:34
I can confirm what thisbizness at gmail dot com said just below in PHP 5.2, furthermore, people looking to use this as a "if $a is not instance of A" for error throwing purposes or other, just type it like this:
<?php
if( !$a instanceof A ) {
throw new Exception( '$a is not instance of A.' );
}
?>
This also works if $a is not an object, or not even set (you will get an E_NOTICE if it isn't set though).
A note worth making is that if you are unsure of if class A is present when making this comparison, and you don't want to trigger the __autoload() magic method, scroll down for examples of how to get around this.
I was unsure about it at first since most other operators have their own negative (like !=) or they are/can be used as function calls (like !is_a()) but it is this simple. Hope it helps someone.
Until again!
17-Feb-2005 06:37
Negated instanceof doesn't seem to be documented. When I read instanceof I think of it as a compairson operator (which I suppose it's not).
<?php
class A {}
class X {}
//parse error from !
if (new X !instanceof A) {
throw new Exception('X is not an A');
}
//proper way to negate instanceof ?
if (!(new X instanceof A)) {
throw new Exception('X is not an A');
}
?>
18-Dec-2004 12:42
use this for cross-version development...
<?php
function is_instance_of($IIO_INSTANCE, $IIO_CLASS){
if(floor(phpversion()) > 4){
if($IIO_INSTANCE instanceof $IIO_CLASS){
return true;
}
else{
return false;
}
}
elseif(floor(phpversion()) > 3){
return is_a($IIO_INSTANCE, $IIO_CLASS);
}
else{
return false;
}
}
?>
