我知道instanceof是一个操作符,is_a是一个方法。
该方法的性能是否较慢?你更喜欢用什么?
我知道instanceof是一个操作符,is_a是一个方法。
该方法的性能是否较慢?你更喜欢用什么?
当前回答
下面是从中获得的性能结果:
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)
其他回答
下面是从中获得的性能结果:
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)
除了速度,另一个重要的区别是如何处理边缘情况。
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抑制它们。
有一种情况是,只有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的。
关于is_a()有一件有趣的事情需要注意:如果你正在为你的类使用自动加载器、名称空间和别名,你将需要在is_a()上使用你的类的真实和全名,因为这个方法不能很好地理解你的上下文中的什么是什么。另一方面,Instanceof理解它。
例如(不是双关语):
<?php
namespace MyNamespace;
use \MyNamespace\User;
use \MyNamespace\Thing as Something;
class Test
{
public function doTest()
{
$user = new User();
var_dump(is_a($user, "User")); // false
var_dump(is_a($user, "\MyNamespace\User")); // true
var_dump($user instanceof User); // true
var_dump($user instanceof \MyNamespace\User); // true
}
public function doAnotherTest()
{
$something = new Something();
var_dump(is_a($something, "Something")); // false
var_dump(is_a($something, "\MyNamespace\Thing")); // true
var_dump($something instanceof Thing); // true
var_dump($something instanceof \MyNamespace\Thing); // true
}
}
关于ChrisF的回答,is_a()从PHP 5.3.0起不再弃用。我发现这种事还是听官方消息比较安全。
关于你的问题,丹尼尔,我不能说性能上的差异,但部分原因在于可读性,以及你觉得哪个更容易使用。
此外,还有一些关于否定instanceof check与is_a()的混淆的讨论。例如,instanceof你会这样做:
<?php
if( !($a instanceof A) ) { //... }
?>
Vs is_a():
<?php
if( !is_a($a, 'A' ) { //... }
?>
or
<?php
if( is_a($a, 'A') === FALSE) { //... }
?>
看起来ChrisF删除了他的答案,但我的答案的第一部分仍然有效。