我知道instanceof
是一个运算符,而is_a
是一种方法。
方法的性能是否较慢?你更喜欢用什么?
答案 0 :(得分:201)
实际上,is_a
是一个函数,而instanceof
是一个语言结构。 is_a
将显着变慢(因为它具有执行函数调用的所有开销),但在任一方法中总体执行时间都是最小的。
自5.3以来不再弃用,所以不用担心。
然而,有一个区别。作为函数的is_a
将对象作为参数1,将字符串(变量,常量或文字)作为参数2.所以:
is_a($object, $string); // <- Only way to call it
instanceof
将对象作为参数1,并且可以将类名(变量),对象实例(变量)或类标识符(不带引号的类名称)作为参数2。
$object instanceof $string; // <- string class name
$object instanceof $otherObject; // <- object instance
$object instanceof ClassName; // <- identifier for the class
答案 1 :(得分:44)
以下是is_a()和instanceof的效果结果:
Test name Repeats Result Performance
instanceof 10000 0.028343 sec +0.00%
is_a() 10000 0.043927 sec -54.98%
测试来源为here。
答案 2 :(得分:10)
instanceof
可以与其他对象实例,类的名称或接口一起使用。 我不认为(更新:请参阅https://gist.github.com/1455148)is_a()
适用于接口(只是表示类名的字符串),但如果确实如此,请更正。
来自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'
输出:
bool(true)
bool(true)
bool(false)
答案 3 :(得分:5)
关于ChrisF的回答,is_a()
is no longer deprecated自PHP 5.3.0开始。我发现通过官方消息来源总是更安全。
关于你的问题,丹尼尔,我不能说性能差异,但部分内容将归结为可读性,你会发现它更容易使用。
另外,there is some discussion关于否定instanceof
支票与is_a()
的混淆。例如,对于instanceof
,您可以这样做:
<?php
if( !($a instanceof A) ) { //... }
?>
与is_a()
的以下内容:
<?php
if( !is_a($a, 'A' ) { //... }
?>
或
<?php
if( is_a($a, 'A') === FALSE) { //... }
?>
编辑看起来ChrisF删除了他的回答,但我的回答的第一部分仍然存在。
答案 4 :(得分:5)
除了速度之外,另一个重要的区别是它们如何处理边缘情况。
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.
因此,is_a()会突出显示可能的错误,而instanceof会抑制它们。
答案 5 :(得分:2)
优化很少。在代码的可读性,可理解性和稳定性面前,微优化从来不是一个真正的好答案。
(personaly我喜欢 instanceof ,但选择权是你的;)
主要区别在于可以将直接类名与 instanceof
一起使用$ myoflass的实例
比
短is_a($ a,MyClass :: class)
(好吧......这不是小事。)
instanceof(语言结构)和is_a之间的语法着色也很有用(对我而言)。让功能颜色更大的操作。 并且在if中单独使用,instanceof不需要更多的括号。
注意: 当然,您可以使用更短的直接字符串代替MyClass :: class:
is_a($一个,&#39; MyClass的&#39)
但在代码中使用直接字符串不是一个好习惯。
如果您可以在简单的字符串和类名称之间做出区分,语法colloration会更好,更有用。 使用常量类名更改名称更容易。特别是如果您使用带别名的命名空间。
那么,我们使用 is_a()?
同样的存在:可读性和不可靠性。 (这是你的选择) 特别是当与!或其他布尔运算符一起使用时: is_a 似乎对括号更有用。
if($ a AND(!is_a($ a,MyClass :: class)OR is_a($ a,MyOtherClass :: class)))
比以下内容更具可读性:
if($ a AND(!($ a instanceof MyClass)OR($ a inanceof MyOtherClass)))
另一个很好的理由是当你需要在函数中使用回调时。 (比如 array_map ...) instanceof 不是函数,它是一种语言构造,因此您不能将其用作回调。
在这种情况下, is_a 可能是有用的
答案 6 :(得分:1)
我不能说出表现 - 我还没有测量任何东西 - 但是根据你的尝试,instanceof
有限制。最近看看我的问题:
PHP 'instanceof' failing with class constant
我最终使用的是is_a
。我更喜欢instanceof
的结构(我觉得它看起来更好)并且会尽我所能继续使用它。
答案 7 :(得分:1)
以下是从here获得的效果结果:
instanceof
更快。
<强>功能强>
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';
}
时间(每次运行5000次)
0.00573397 // method_1(5)
0.01437402 // method_2(5)
0.00376201 // method_3(5)
答案 8 :(得分:0)
在某些情况下,只有is_a()
起作用并且instanceof
会失败。
instanceof
期望将文字类名或作为对象或字符串(具有类名)的变量作为其正确参数。
但是,如果要从函数调用中提供类名称的字符串,则该字符串将不起作用并导致语法错误。
但是,在is_a()
下,同样的情况也可以正常工作。
示例:
<?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()));
这基于PHP 7.2.14。