is_a和instanceof有什么区别?

时间:2010-06-10 19:19:05

标签: php

我知道instanceof是一个运算符,而is_a是一种方法。

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

9 个答案:

答案 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可以与其他对象实例,类的名称或接口一起使用。 我不认为is_a()适用于接口(只是表示类名的字符串),但如果确实如此,请更正。(更新:请参阅https://gist.github.com/1455148

来自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。