我见过几个人们问如何在PHP中获取类或对象的名称.但是,我无法看到解释各种可能性之间的差异.我希望这里有人可以帮助我.
因此,为了获得被调用类的类名,我知道两种可能性:
get_called_class()
static::class
(get_class($this)对于非静态类)
为了获得放置代码的类的类名,我知道这三种可能性:
get_class()
__CLASS__
self::class
我现在可能忽视哪些差异?单向另一种方式的潜在冒险和缺点是什么?
之间的一个区别__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'.
Run Code Online (Sandbox Code Playgroud)
我会说它get_class($this)通常更有用,因为无论您从哪里使用它,它都会按预期工作,而无需编写重复的覆盖代码,例如printOverridableCompileTimeType.
之间的差异
返回对象的类的名称
当您将对象实例指针作为第一个也是唯一的参数传递时,它将返回一个类名称,包括当前类(不带参数)或任何指定对象实例的限定名称空间。
一个魔术常量,它返回合格的名称空间和当前的类名称。在这里,您无法测试其他对象的类名。根据PHP 5.4,它可以在特征中使用。也就是说,在类中使用特征时,它将返回该类的名称空间和名称。
仅从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'
Run Code Online (Sandbox Code Playgroud)