【问题标题】:Difference static::class vs get_called_class() and __CLASS__ vs get_class() vs self::class区别 static::class vs get_call_class() 和 __CLASS__ vs get_class() vs self::class
【发布时间】:2018-05-27 16:27:26
【问题描述】:

我见过几个线程,人们询问如何在 PHP 中获取类或对象的名称。但是,我在任何地方都看不到解释的各种可能性之间的区别。我希望这里有人可以帮助我。

所以为了得到被调用类的类名,我知道有两种可能:

  1. get_called_class()

  2. static::class

get_class($this) 用于非静态类)

为了获取你放置代码的类的类名,我知道这三种可能性:

  1. get_class()

  2. __CLASS__

  3. self::class

我现在有什么可以忽略的差异吗?一种方式相对于另一种方式的潜在风险和缺点是什么?

【问题讨论】:

  • 尝试在一个类和扩展它的类、实例方法和静态方法中使用所有这些方法来找出答案。
  • 这就是我所做的,它们都返回相同的结果。我想可能还有其他一些我想不出的区别。毕竟,他们为什么要在 PHP 5.5 中引入 ::class,而 get_class()__CLASS__get_called_class() 可以实现相同的功能?
  • ::class 可以在编译时计算,get_class() 是一个函数调用,因此它返回的值仅在执行时可用。
  • 这是否意味着::class效率更高?
  • 差别不大。如果您的目标是优化,请检查对数据库的访问(优化 SQL 查询并减少它们的数量和它们检索的数据量)、文件系统和远程资源。

标签: php class oop


【解决方案1】:

之间的区别

get_class()

返回对象的类名

当您将对象实例指针作为第一个也是唯一的参数传递时,它返回一个类名,包括当前类(不带参数)或任何指定对象实例的限定命名空间。

__CLASS__

返回限定命名空间和当前类名的魔术常量。在这里你不能测试其他对象的类名。 根据 PHP 5.4,它适用于特征。也就是说,当在类中使用 trait 时,它将返回该类的命名空间和名称。

::class

仅从 PHP 5.5 开始可用。它使用类名和命名空间解析来获取信息,因此它不需要预先实例化类。另请注意:

使用 ::class 的类名解析是编译时转换。这意味着在创建类名字符串时还没有发生自动加载。因此,即使类不存在,类名也会被扩展。在这种情况下不会发出错误。

测试

<?php
namespace nTest;
trait tTest {
  function __toString() {return get_class();}
  function className() {return __CLASS__;}  // per PHP 5.4
  function traitName() {return __TRAIT__;}
}
class cTest {
  use tTest;
  function usedTraitName() {return __TRAIT__;}
}
class cClassWithoutObject {}
$oTest = new cTest;

header('Content-type: text/plain');
print                                  // Output:
    $oTest . PHP_EOL                   // 'nTest::cTest'
  . get_class($oTest) . PHP_EOL        // 'nTest::cTest'
  . $oTest->className() . PHP_EOL      // 'nTest::cTest'
  . $oTest->traitName() . PHP_EOL      // 'nTest::tTest' (trait!)
  . $oTest->usedTraitName() . PHP_EOL  // '' (no trait!)
  . cTest::class . PHP_EOL             // 'nTest::cTest'
  . cClassWithoutObject::class;        // 'nTest::cTestNotInstantiated'

【讨论】:

  • 我爱你的回答。把我从好奇心的负担中解救出来!
【解决方案2】:

__CLASS__get_class($this) 之间的一个区别很重要,如果您使用继承,__CLASS__ 会为您提供包含该代码的类的名称(可能是父类),而 get_class($this)将在运行时为您提供$this 的具体类的名称。

例子:

class Animal {

    function printCompileTimeType() {

        echo __CLASS__;
    }

    function printOverridableCompileTimeType() {

        echo __CLASS__;
    }

    function printType() {

        echo get_class($this);
    }
}

class Dog extends Animal {

    function printOverridableCompileTimeType() {

        echo __CLASS__;
    }
}

$animal = new Animal();
$dog = new Dog();

$animal->printCompileTimeType(); // Prints 'Animal'.
$animal->printOverridableCompileTimeType(); // Prints 'Animal'.
$animal->printType(); // Prints 'Animal'.

$dog->printCompileTimeType(); // Prints 'Animal'.
$dog->printOverridableCompileTimeType(); // Prints 'Dog'.
$dog->printType(); // Prints 'Dog'.

我会说get_class($this) 通常更有用,因为无论您从何处使用它,它都能按预期工作,而无需编写像printOverridableCompileTimeType 这样的重复覆盖代码。

【讨论】:

    猜你喜欢
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2020-12-08
    • 2013-11-08
    相关资源
    最近更新 更多