我知道instanceof是一个操作符,is_a是一个方法。

该方法的性能是否较慢?你更喜欢用什么?


当前回答

有一种情况是,只有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($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()有一件有趣的事情需要注意:如果你正在为你的类使用自动加载器、名称空间和别名,你将需要在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
    }
}

我不能谈论性能——我还没有测量过任何东西——但根据您的尝试,instanceof有局限性。看看我最近提出的问题:

PHP 'instanceof'类常量失败

我最终使用了is_a。我更喜欢instanceof的结构(我认为它读起来更好),并将继续在我可以使用的地方使用它。

下面是is_a()和instanceof的性能结果:

Test name       Repeats         Result          Performance     
instanceof      10000           0.028343 sec    +0.00%
is_a()          10000           0.043927 sec    -54.98%

测试源在这里。

有一种情况是,只有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的。