php is_a 和 instanceof 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3017684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between is_a and instanceof?
提问by Daniel
I am aware that instanceofis an operator and that is_ais a method.
我知道这instanceof是一个运算符,那is_a是一种方法。
Is the method slower in performance? What would you prefer to use?
该方法的性能是否较慢?你更喜欢使用什么?
回答by ircmaxell
Update
更新
As of PHP 5.3.9, the functionality of is_a()has changed. The original answer below states that is_a()mustaccept an Objectas 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:
从PHP 5.3.9 开始, 的功能发生is_a()了变化。下面的原始答案指出is_a()必须接受 anObject作为第一个参数,但 PHP 版本 >= 5.3.9 现在接受可选的第三个布尔参数$allow_string(默认为false)以允许比较字符串类名称:
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 instanceofand is_a()is that instanceofwill 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_stringargument is set to the default value of false.
instanceof和之间的新行为的主要区别is_a()在于,instanceof将始终检查目标是否是指定类(包括扩展类)的实例化对象,而is_a()仅在$allow_string参数设置为默认值时才要求实例化对象false。
Original
原来的
Actually, is_ais a function, whereas instanceofis a language construct. is_awill be significantly slower (since it has all the overhead of executing a function call), but the overall execution time is minimal in either method.
实际上,is_a是一个函数,而instanceof是一个语言结构。 is_a将显着变慢(因为它具有执行函数调用的所有开销),但两种方法的总体执行时间都很短。
It's no longer deprecated as of 5.3, so there's no worry there.
从 5.3 开始,它不再被弃用,所以不用担心。
There is one difference however. is_abeing a function takes an object as parameter 1, and a string (variable, constant, or literal) as parameter 2. So:
然而,有一个区别。 is_a作为一个函数,将一个对象作为参数 1,将一个字符串(变量、常量或文字)作为参数 2。所以:
is_a($object, $string); // <- Only way to call it
instanceoftakes 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.
instanceof将对象作为参数1,可以将类名(变量)、对象实例(变量)或类标识符(不带引号的类名)作为参数2。
$object instanceof $string; // <- string class name
$object instanceof $otherObject; // <- object instance
$object instanceof ClassName; // <- identifier for the class
回答by Alexander Yancharuk
Here is performance results of is_a()and instanceof:
下面是is_a()和instanceof 的性能结果:
Test name Repeats Result Performance
instanceof 10000 0.028343 sec +0.00%
is_a() 10000 0.043927 sec -54.98%
Test source is here.
测试源在这里。
回答by Lotus Notes
instanceofcan be used with other object instances, the class's name, or an interface. I don't think that (Update: See https://gist.github.com/1455148)is_a()works with interfaces (only a string representing a class name), but correct me if it does.
instanceof可以与其他对象实例、类的名称或接口一起使用。我认为这不适(更新:见https://gist.github.com/1455148)is_a()用于接口(仅表示类名的字符串),但如果确实如此,请纠正我。
Example from php.net:
来自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'
outputs:
输出:
bool(true)
bool(true)
bool(false)
回答by Mike Branski
In regards to ChrisF's answer, is_a()is no longer deprecatedas of PHP 5.3.0. I find it's always safer to go by the official source for things like this.
关于 ChrisF 的回答,自 PHP 5.3.0 起is_a()不再弃用。我发现通过官方来源获取此类信息总是更安全。
With regards to your question, Daniel, I can't say about the performance differences, but part of it will come down to readibility and which you find easier to work with.
关于你的问题,丹尼尔,我不能说性能差异,但部分归结为可读性,你觉得更容易使用。
Also, there is some discussionabout the confusion around negating an instanceofcheck vs is_a(). For example, for instanceofyou would do:
此外,还有一些关于否定instanceofcheck 与is_a(). 例如,instanceof你会这样做:
<?php
if( !($a instanceof A) ) { //... }
?>
vs the following for is_a():
与以下内容相比is_a():
<?php
if( !is_a($a, 'A' ) { //... }
?>
or
或者
<?php
if( is_a($a, 'A') === FALSE) { //... }
?>
EditLooks like ChrisF deleted his answer, but the first part of my answer still stands.
编辑看起来 ChrisF 删除了他的答案,但我的答案的第一部分仍然有效。
回答by Csongor Halmai
Besides the speed, another important difference is how they handle edge cases.
除了速度之外,另一个重要的区别是它们如何处理边缘情况。
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.
So, is_a() highlights possible bugs while instanceof suppresses them.
因此,is_a() 会突出可能的错误,而 instanceof 会抑制它们。
回答by Titsta
The optimisation is minimal. And micro-optimisations are never a real good answer, in front of the readability, understandability and stability of the code.
优化是最小的。在代码的可读性、可理解性和稳定性面前,微优化从来都不是一个真正好的答案。
( personaly I prefere instanceof, but the choice is yours ;) )
(我个人更喜欢instanceof,但选择权在你;))
The principal difference is the possibility to use direct class name with instanceof
主要区别是可以将直接类名与instanceof一起使用
$a instanceof MyClass
$一个 MyClass 的实例
is shorter than
短于
is_a($a, MyClass::class)
is_a($a, MyClass::class)
( ok… it's not trivial. )
(好吧……这不是微不足道的。)
The syntaxical coloration between instanceof (language structure) and is_a is usefull too (for me). letting function color to bigger operations. And for single use in if, instanceof dosn't need more parenthesis.
instanceof(语言结构)和 is_a 之间的语法着色也很有用(对我来说)。让函数颜色更大的操作。对于 if 中的单次使用,instanceof 不需要更多的括号。
Note : Of course instead of MyClass::class you can use a shorter direct string :
注意:当然,您可以使用较短的直接字符串代替 MyClass::class:
is_a($a,'MyClass')
is_a($a,'MyClass')
But use direct string in a code isn't a good practice.
但是在代码中使用直接字符串并不是一个好习惯。
The syntaxical colloration is better and more usefull if you can make a difference between simple string and classes names. And it's easier to change names with constant classname. Specialy if you use namespace with alias.
如果您可以区分简单字符串和类名称,则语法排序会更好、更有用。使用常量类名更容易更改名称。特别是如果您使用带别名的命名空间。
So, wy use is_a()?
那么,为什么要使用is_a()?
For same raison : readability and undestandability. (the choice is yours) Specialy when used with !or others boolean operators : is_aseems more pratical with parenthesis.
出于同样的原因:可读性和不可理解性。(选择权在您手中)Specialy 与! 或其他布尔运算符:is_a似乎更实用,带括号。
if( $a AND (!is_a ($a, MyClass::class) OR is_a ($a, MyOtherClass::class)) )
if( $a AND (!is_a ($a, MyClass::class) OR is_a ($a, MyOtherClass::class)) )
is more readable than :
比以下内容更具可读性:
if( $a AND (!( $a instanceof MyClass) OR ($a intanceof MyOtherClass)))
if( $a AND (!( $a instanceof MyClass) OR ($a instanceof MyOtherClass)))
An other good reason is when you need use callback in functions. ( like array_map… ) instanceofisn't a function, it's a language construct, so you cannot use it as callback.
另一个很好的理由是当您需要在函数中使用回调时。(如array_map... ) instanceof不是函数,它是一种语言结构,因此您不能将其用作回调。
In thoses cases, is_amay be usefull
在这些情况下,is_a可能有用
回答by dayuloli
Here are performance results obtained from here:
以下是从此处获得的性能结果:
instanceofis faster.
instanceof是比较快的。
Functions
职能
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';
}
Times (run 5000 times each)
次数(每次运行5000次)
0.00573397 // method_1(5)
0.01437402 // method_2(5)
0.00376201 // method_3(5)
回答by Nathan Loding
I can't speak for performance -- I haven't measured anything yet -- but depending on what you are attempting, there are limitations with instanceof. Check out my question, just recently, about it:
我不能谈论性能——我还没有测量过任何东西——但是根据你的尝试,instanceof. 看看我最近的问题:
PHP 'instanceof' failing with class constant
I've ended up using is_ainstead. I like the structure of instanceofbetter (I think it reads nicer) and will continue to use it where I can.
我最终使用了is_a。我喜欢instanceof更好的结构(我认为它读起来更好)并将继续尽可能地使用它。
回答by Erik Kalkoken
There is a scenario where only is_a()works and instanceofwill fail.
有一种情况,它只能is_a()工作,但instanceof会失败。
instanceofexpects a literal class name or a variable that is either an object or a string (with the name of a class) as its right argument.
instanceof需要一个文字类名或一个对象或字符串(带有类名)的变量作为其正确参数。
But if you want to provide the string of a class name from a function call it will not work and result in a syntax error.
但是,如果您想从函数调用中提供类名的字符串,它将不起作用并导致语法错误。
However, the same scenario works fine with is_a().
但是,相同的场景适用于is_a().
Example:
例子:
<?php
function getClassName() : string
{
return "Foobar";
}
class Foobar
{
private $xyz;
}
$x = new Foobar();
// this works of course
var_dump($x instanceof Foobar);
// this creates a syntax error
var_dump($x instanceof getClassName());
// this works
var_dump(is_a($x, getClassName()));
This is based on PHP 7.2.14.
这是基于 PHP 7.2.14。

