Php value type check
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.
Checking an object is not an instance of a class, example #3 uses extraneous parentheses.
var_dump (!( $a instanceof stdClass ));
?>
Because instanceof has higher operator precedence than ! you can just do
var_dump ( ! $a instanceof stdClass );
?>
I don’t see any mention of «namespaces» on this page so I thought I would chime in. The instanceof operator takes FQCN as second operator when you pass it as string and not a simple class name. It will not resolve it even if you have a `use MyNamespace\Bar;` at the top level. Here is what I am trying to say:
## testinclude.php ##
namespace Bar1 ;
class Foo1 < >
>
namespace Bar2 ;
class Foo2 < >
>
?>
## test.php ##
include( ‘testinclude.php’ );
use Bar1 \ Foo1 as Foo ;
$foo1 = new Foo (); $className = ‘Bar1\Foo1’ ;
var_dump ( $foo1 instanceof Bar1 \ Foo1 );
var_dump ( $foo1 instanceof $className );
$className = ‘Foo’ ;
var_dump ( $foo1 instanceof $className );
use Bar2 \ Foo2 ;
$foo2 = new Foo2 (); $className = ‘Bar2\Foo2’ ;
var_dump ( $foo2 instanceof Bar2 \ Foo2 );
var_dump ( $foo2 instanceof $className );
$className = ‘Foo2’ ;
var_dump ( $foo2 instanceof $className );
?>
## stdout ##
bool(true)
bool(true)
bool(false)
bool(true)
bool(true)
bool(false)
You are also able to compare 2 objects using instanceOf. In that case, instanceOf will compare the types of both objects. That is sometimes very useful:
$a = new A ;
$b = new B ;
$a2 = new A ;
echo $a instanceOf $a ; // true
echo $a instanceOf $b ; // false
echo $a instanceOf $a2 ; // true
Using an undefined variable will result in an error.
If variable is in doubt, one must prequalify:
if ( isset( $MyInstance ) and $MyInstance instanceof MyClass ) .
if you have only class names (not objects) you can use that snippet: https://3v4l.org/mUKUC
interface i <>
class a implements i <>
var_dump ( a ::class instanceof i ); // false
var_dump ( in_array ( i ::class, class_implements ( a ::class), true )); // true
Example #5 could also be extended to include.
var_dump($a instanceof MyInterface);
So — instanceof is smart enough to know that a class that implements an interface is an instance of the interface, not just the class. I didn’t see that point made clearly enough in the explanation at the top.
You can use «self» to reference to the current class:
class myclass <
function mymethod ( $otherObject ) <
if ( $otherObject instanceof self ) <
$otherObject -> mymethod ( null );
>
return ‘works!’ ;
>
>
$a = new myclass ();
print $a -> mymethod ( $a );
?>
Doing $a instanceof stdClass from inside a namespace will not work on its own.
if ( $a instanceof \ stdClass )
?>
If you want to test if a classname is an instance of a class, the instanceof operator won’t work.
$classname = ‘MyClass’ ;
if( $classname instanceof MyParentClass ) echo ‘Child of it’ ;
else echo ‘Not child of it’ ;
?>
Will always output
Not child of it
You must use a ReflectionClass :
$classname = ‘MyClass’ ;
$myReflection = new ReflectionClass ( $classname );
if( $myReflection -> isSubclassOf ( ‘MyParentClass’ )) echo ‘Child of it’ ;
else echo ‘Not child of it’ ;
?>
Will output the good result.
If you’re testing an interface, use implementsInterface() instead of isSublassOf().
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
If you want to use «$foo instanceof $bar» to determine if two objects are the same class, remember that «instanceof» will also evaluate to true if $foo is an instance of a _subclass_ of $bar’s class.
If you really want to see if they are the _same_ class, then they both have to be instances of each other’s class. That is:
( $foo instanceof $bar && $bar instanceof $foo )
?>
Consider it an alternative to «get_class($bar) == get_class($foo)» that avoids the detour through to string lookups and comparisons.
SIMPLE, CLEAN, CLEAR use of the instanceof OPERATOR
First, define a couple of simple PHP Objects to work on — I’ll introduce Circle and Point. Here’s the class definitions for both:
class Circle
protected $radius = 1.0 ;
/*
* This function is the reason we are going to use the
* instanceof operator below.
*/
public function setRadius ( $r )
$this -> radius = $r ;
>
public function __toString ()
return ‘Circle [radius=’ . $this -> radius . ‘]’ ;
>
>
class Point
protected $x = 0 ;
protected $y = 0 ;
/*
* This function is the reason we are going to use the
* instanceof operator below.
*/
public function setLocation ( $x , $y )
$this -> x = $x ;
$this -> y = $y ;
>
public function __toString ()
return ‘Point [x=’ . $this -> x . ‘, y=’ . $this -> y . ‘]’ ;
>
>
?>
Now instantiate a few instances of these types. Note, I will put them in an array (collection) so we can iterate through them quickly.
$myCollection = array( 123 , ‘abc’ , ‘Hello World!’ ,
new Circle (), new Circle (), new Circle (),
new Point (), new Point (), new Point ());
$i = 0 ;
foreach( $myCollection AS $item )
/*
* The setRadius() function is written in the Circle class
* definition above, so make sure $item is an instance of
* type Circle BEFORE calling it AND to avoid PHP PMS!
*/
if( $item instanceof Circle )
$item -> setRadius ( $i );
>
/*
* The setLocation() function is written in the Point class
* definition above, so make sure $item is an instance of
* type Point BEFORE calling it AND to stay out of the ER!
*/
if( $item instanceof Point )
$item -> setLocation ( $i , $i );
>
echo ‘$myCollection[‘ . $i ++ . ‘] = ‘ . $item . ‘
‘ ;
>
?>
$myCollection[0] = 123
$myCollection[1] = abc
$myCollection[2] = Hello World!
$myCollection[3] = Circle [radius=3]$myCollection[4] = Circle [radius=4]$myCollection[5] = Circle [radius=5]$myCollection[6] = Point [x=6, y=6]$myCollection[7] = Point [x=7, y=7]$myCollection[8] = Point [x=8, y=8]
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.
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 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:
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
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
while ! (negation) is a unary operator and so may be applied to a single term like this
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:
So back again, did you ever write
use this to check instance of or you can add the else part inside the if making it nested if for dual varification.:-
class MyClass <>
class Test extends MyClass public function checkObjectArray (array $array , $classname , $strict = false )if(! $strict )foreach( $array as $element ) if(!( $element instanceOf $classname )) < //we can use typehint objects
INSIDE an array
echo «false» ;
echo «
» ;
break;
>
else print «
true (if)» ;
>
>
>
elseforeach( $array as $element )if( get_class ( $element )!= $classname ) < // or we can use this function to
check the classes inside this array
echo «false (else)» ;
>
>
>
echo «
true» ;
>
>
$ob =new Test ;
$a =new MyClass ();
$array =array( $a );
$ob -> checkObjectArray ( $array , ‘MyClass’ );
?>
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).
//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’ );
>
?>
Sometimes you want to typehint objects INSIDE an array, but I think you can’t.
Instead, you can use this function to check the classes inside this array:
public checkObjectsArray (array $array , $classname , $strict = false ) if (! $strict ) foreach ( $array as $element ) if (!( $element instanceof $classname )) return false ;
>
>
>
else foreach ( $array as $element ) if ( get_class ( $element ) != $classname ) return false ;
>
>
>
return true ;
>
use this for cross-version development.
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 ;
>
>
gettype
Returns the type of the PHP variable value . For type checking, use is_* functions.
Parameters
The variable being type checked.
Return Values
- «boolean»
- «integer»
- «double» (for historical reasons «double» is returned in case of a float , and not simply «float» )
- «string»
- «array»
- «object»
- «resource»
- «resource (closed)» as of PHP 7.2.0
- «NULL»
- «unknown type»
Changelog
Version | Description |
---|---|
7.2.0 | Closed resources are now reported as ‘resource (closed)’ . Previously the returned value for closed resources were ‘unknown type’ . |
Examples
Example #1 gettype() example
$data = array( 1 , 1. , NULL , new stdClass , ‘foo’ );
foreach ( $data as $value ) echo gettype ( $value ), «\n» ;
>
The above example will output something similar to:
integer double NULL object string
See Also
- get_debug_type() — Gets the type name of a variable in a way that is suitable for debugging
- settype() — Set the type of a variable
- get_class() — Returns the name of the class of an object
- is_array() — Finds whether a variable is an array
- is_bool() — Finds out whether a variable is a boolean
- is_callable() — Verify that a value can be called as a function from the current scope.
- is_float() — Finds whether the type of a variable is float
- is_int() — Find whether the type of a variable is integer
- is_null() — Finds whether a variable is null
- is_numeric() — Finds whether a variable is a number or a numeric string
- is_object() — Finds whether a variable is an object
- is_resource() — Finds whether a variable is a resource
- is_scalar() — Finds whether a variable is a scalar
- is_string() — Find whether the type of a variable is string
- function_exists() — Return true if the given function has been defined
- method_exists() — Checks if the class method exists
User Contributed Notes 2 notes
Be careful comparing ReflectionParameter::getType() and gettype() as they will not return the same results for a given type.
string — string // OK
int — integer // Type mismatch
bool — boolean // Type mismatch
array — array // OK
Same as for «boolean» below, happens with integers. gettype() return «integer» yet proper type hint is «int».
If your project is PHP8+ then you should consider using get_debug_type() instead which seems to return proper types that match used for type hints.