类型运算符

PHP 有一个类型运算符:instanceofinstanceof 用来测定一个给定的对象是否来自指定的对象类

instanceof 运算符是 PHP 5 引进的。在此之前用 is_a(),但是 is_a() 已经过时了,最好用 instanceof

<?php
class A { }
class B { }

$thing = new A;

if ($thing instanceof A) {
    echo 'A';
}
if ($thing instanceof B) {
    echo 'B';
}
?>

由于 $thing 是类型 A 的一个 object,而不是 B 的,只有和类型 A 相符合的程序块被运行:

A

参见 get_class()is_a()


add a note add a note User Contributed Notes
w dot bogaerts at kratz dot nl
22-Sep-2006 04:32
instanceof only works with objects. So if you want to check if a variable is an object that implements a certain interface, you need two checks: is_object and instanceof.
A fatal error occurs if instanceof is used with other data types.
MikeH
10-Mar-2006 07:14
This will fail:

<?
if ($moo instanceof "Moo") echo "Goo\n";
?>

and this will not:

<?
if ($moo instanceof Moo) echo "Goo\n";
?>

and although you cant use a quoted string as the class name to check, you can use a variable like this:

<?
$moo_class
= "Moo";
if (
$moo instanceof $moo_class) echo "Goo\n";
?>

so if you want to loop through an array of class names to check an object against, you can do it easily.
arnold at bean-it dot nl
25-Feb-2006 07:28
Note that operator 'instanceof' will trigger the autoloader.
If the class does not exists, it is not possible that the object  is an instance of this class (as shown by glen at arkadia-systems dot com). Loading this class will probably be a waste of excecution time, so use class_exists with $autoload set to false before using instanceof.

<?php
  
function __autoload($classname)
   {
       if ((
$fp = @fopen("$classname.php", 'r', 1)) and fclose($fp)) include_once "$classname.php";
   }

   function
foo($obj)
   {
       if (
class_exists('ABC', false) && $obj instanceof ABC) echo "object is an ABC";
   }
?>
Colin
06-Dec-2005 03:20
To MooGoo:

This will fail, as you pointed out:

<?
if ($moo instanceof "Moo") echo "Goo\n";
?>

but this will not

<?
if ($moo instanceof Moo) echo "Goo\n";
?>

This later example (no quotes around Moo) is shown twice in the example code.
klaazvaag . gmail . com
03-Oct-2005 05:02
If you wish to do a short but dynamic comparison using instanceof, you can use this code:

<?php
class any
{
  function
__construct($obj)
  {
   if (
is_object($obj))
     if (
$obj instanceof self)
       echo
'$obj is an instance of '.__CLASS__;
  }
}
?>
MooGoo
01-Sep-2005 10:42
instanceof can compare a class instance to a string which contains a class name. However that string must be contained in a variable, it will not work as a return value from a function (for instance, get_class()) or even from a regular inline string.

<?php
class Moo
{
   function
Goo()
   {
      
$moo = "I do nothing";
   }
}

$moo = new Moo;

//Will fail
if ($moo instanceof "Moo") echo "Goo\n";

//Will also fail
if ($moo instanceof get_class($moo)) echo "Goo\n";

//However...

//Will succeed
$className = get_class($moo);

if (
$moo instanceof $className) echo "Goo\n";

//Will also succeed
$className = "Moo";

if (
$moo instanceof $className) echo "Goo\n";

?>
archanglmr at yahoo dot com
18-Feb-2005 10: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');
}
?>
d dot schneider at 24you dot de
19-Dec-2004 04: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;
       }
   }

?>
glen at arkadia-systems dot com
11-Sep-2004 01:00
If you are updating code to replace 'is_a()' with the PHP5 compliant
'instanceof' operator, you may find it necessary to change the basic
architecture of your code to make this work.

'instanceof' will throw a fatal error if the object being checked for does not
exist.

'is_a()' will simply return false under this condition.

In the example below, 'is_a()' would effectively detect the need to create an
instance of class 'A', but in this case 'instanceof' will crash your program
with a fatal error.

<?php
// define classes

// Commenting this class will cause an error when 'instanceof' looks for 'A'
// class A {}

class B {}

// create a new object
// $thing = new A();
$thing = new B();

if (
is_a($thing, 'A')) {
   echo
'Yes, $thing is_a A<br>';
} else {
   echo
'No, $thing is not is_a A<br>';
}

if (
$thing instanceof A) {
   echo
'Yes, $thing is an instaceof A<br>';
} else {
   echo
'No, $thing is not an instaceof A<br>';
}

?>

>>> Output:
No, $thing is not is_a A
Fatal error: Class 'A' not found in is_a-instanceof.php on line 19
>>>

A suitable work-around for this situation is to check for the existence of the
class before performing the 'instanceof' comparison:

<?php

/* ... */

if (class_exists('A') && $thing instanceof A) {
   echo
'Yes, $thing is an instaceof A<br>';
} else {
   echo
'No, $thing is not an instaceof A<br>';
}

?>
zimba dot spam at gmail dot com
11-Sep-2004 03:17
instanceof cannot use a string for the comparison like is_a.
Instead, you can use a class instance (not documented)
Example :
<?
$x
= new myClass();
$y = new myClass();

echo
is_a($x, get_class($y));  // Returns true/1

echo $x instanceof get_class($y);  // Doesn't work, instead use :

echo $x instanceof $y;
?>

Cheers,
zimba
"Leo Pedretti" <lpedretti at suserver dot com>
24-Aug-2004 11:59
The instanceof operator also checks the interface tree. For example, the following code:

<?

interface Human
{
  
public function say($var);
  
public function gender();
}

class
man implements Human {
  
public function say($var) {
  
"Oh yeah, $var\n"
  
}

  
public function gender() {
   return
"male";
   }
}

class
woman implements Human {
  
public function say($var) {
  
"Oh dear, $var\n"
  
}

  
public function gender() {
   return
"female";
   }
}

$m = new man;
$w = new woman;
if (
$p instanceof Human) {
   print
"\$p is Human.\n";
} else {
   print
"\$p is not Human.\n";
}
print
"\$m is of gender ".$m->gender()."\n";

if (
$w instanceof Human) {
   print
"\$w is Human.\n";
} else {
   print
"\$w is not Human.\n";
}
print
"\$w is of gender ".$w->gender()."\n";
?>

Will produce the output

$m is Human.
$m is of gender male
$w is Human.
$w is of gender female
Jesse Scott (scotje at wwc dot edu)
07-Jul-2004 09:52
Since it's not stated authoritatively here, I'll add that instanceof *does* check all the way up the inheritence tree.

So in this code:

<?php
  
class A
  
{
       var
$someProp;
   }
  
   class
B extends A
  
{
       function
showProp()
       {
           echo
$someProp;
       }
   }
  
  
$obj1 = new B;

   if (
$obj1 instanceof A)
       echo
"Instanceof checks inheritence tree!";
   else
       echo
"Instanceof does not check inheritence tree!";
?>

The first branch of the if/else block is executed since ($obj1 instanceof A) evaulates to TRUE.