区别static :: class vs get_called_class()和__CLASS__ vs get_class()vs self :: class

时间:2017-12-13 17:16:46

标签: php class oop

我见过几个人们问如何在PHP中获取类或对象的名称的线程。但是,我无法看到解释各种可能性之间的差异。我希望有人可以帮助我。

因此,为了获得被调用类的类名,我知道两种可能性:

  1. get_called_class()

  2. static::class

  3. get_class($this)表示非静态类)

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

    1. get_class()

    2. __CLASS__

    3. self::class

    4. 我现在可能忽视哪些差异?单向另一种方式的潜在冒险和缺点是什么?

2 个答案:

答案 0 :(得分:4)

之间的差异

<强> get_class()

  

返回对象类的名称

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

<强> __CLASS__

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

<强> ::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'

答案 1 :(得分:2)

7.08.0之间的一个区别(如果您使用继承)很重要,那就是__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'. 这样的重复性覆盖代码。