从 PHP 5.5 开始,您也可以使用 "static::class" 来获取调用的类的名称。
<?php
class Bar {
public static function test() {
var_dump(static::class);
}
}
class Foo extends Bar {
}
Foo::test();
Bar::test();
?>
输出
string(3) "Foo"
string(3) "Bar"
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
get_called_class — “延迟静态绑定”类名
此函数没有参数。
返回类名。
示例 #1 使用 get_called_class()
<?php
class foo {
static public function test() {
var_dump(get_called_class());
}
}
class bar extends foo {
}
foo::test();
bar::test();
?>
上面的示例将输出
string(3) "foo" string(3) "bar"
从 PHP 5.5 开始,您也可以使用 "static::class" 来获取调用的类的名称。
<?php
class Bar {
public static function test() {
var_dump(static::class);
}
}
class Foo extends Bar {
}
Foo::test();
Bar::test();
?>
输出
string(3) "Foo"
string(3) "Bar"
在闭包作用域中的 get_called_class()
<?PHP
ABSTRACT CLASS Base
{
protected static $stub = ['baz'];
//final public function boot()
static public function boot()
{
print __METHOD__.'-> '.get_called_class().PHP_EOL;
array_walk(static::$stub, function()
{
print __METHOD__.'-> '.get_called_class().PHP_EOL;
});
}
public function __construct()
{
self::boot();
print __METHOD__.'-> '.get_called_class().PHP_EOL;
array_walk(static::$stub, function()
{
print __METHOD__.'-> '.get_called_class().PHP_EOL;
});
}
}
CLASS Sub EXTENDS Base
{
}
// static boot
Base::boot(); print PHP_EOL;
// Base::boot -> Base
// Base::{closure} -> Base
Sub::boot(); print PHP_EOL;
// Base::boot -> Sub
// Base::{closure} -> Base
new sub;
// Base::boot -> Sub
// Base::{closure} -> Base
// Base->__construct -> Sub
// Base->{closure} -> Sub
// instance boot
new sub;
// Base->boot -> Sub
// Base->{closure} -> Sub
// Base->__construct -> Sub
// Base->{closure} -> Sub
?>
namespace root;
class Factor {
protected static $instance = null;
private function __construct() {
}
public static function getInstance() {
if (!self::$instance) {
$name = get_called_class();
self::$instance = new $name();
}
return self::$instance;
}
}
namespace admin\test;
use root\Factor;
class Single extends Factor {
public function abc() {
return 'abc';
}
}
namespace index;
use admin\test\Single;
class Index {
public function get() {
return Single::getInstance();
}
}
$index = new Index();
var_dump($index->get());
结果是
object(admin\test\Single)#2 (0) {
}
参见:https://php.net/manual/en/language.oop5.late-static-bindings.php
我认为在这页上值得一提的是,get_called_function() 返回值的许多用法可以用旧关键字 static 的新用法来处理,例如
<?php
static::$foo;
?>
对比
<?php
$that=get_called_class();
$that::$foo;
?>
我一直使用 $that:: 作为 self:: 的常规替换,直到我的谷歌搜索带我到了上面的 URL。我已经成功地将所有 $that 的用法替换成了 static,无论是在
<?php
static::$foo; // 以及...
new static();
?>
由于 static:: 的限制是:“另一个区别是 static:: 只能引用静态属性。”,因此您可能仍然需要使用 $that:: 来调用静态函数;虽然我还没有遇到这种语义需求。
在 PHP 5.6(低于 7)中以静态方式调用动态方法时,它允许这样做,但它不起作用,它会错误地评估调用我们主题类的类,因此包含方法必须是静态的。
可以使用 get_called_class 在 PHP 5.3 中编写一个完全独立的单例基类。
<?php
抽象类 Singleton {
受保护的函数 __construct() {
}
最终公共静态函数 getInstance() {
静态 $aoInstance = 数组();
$calledClassName = get_called_class();
如果 (! isset ($aoInstance[$calledClassName])) {
$aoInstance[$calledClassName] = new $calledClassName();
}
返回 $aoInstance[$calledClassName];
}
最终私有函数 __clone() {
}
}
类 DatabaseConnection 扩展 Singleton {
受保护的 $connection;
受保护的函数 __construct() {
// @todo 连接到数据库
}
公共函数 __destruct() {
// @todo 断开与数据库的连接
}
}
$oDbConn = new DatabaseConnection(); // 致命错误
$oDbConn = DatabaseConnection::getInstance(); // 返回单个实例
?>
如果你调用一个静态的 getInstance() 函数从另一个类创建一个类的实例,这个函数必须是静态的,如果不是静态的,就会返回调用类的原始名称,而不是当前类的名称。
例子
<?php
类 a {
函数 getXName() {
返回 x::getClassName();
}
函数 getXStaticName() {
返回 x::getStaticClassName();
}
}
类 b 扩展 a {
}
类 x {
公共函数 getClassName() {
返回 get_called_class();
}
公共静态函数 getStaticClassName() {
返回 get_called_class();
}
}
$a = new a();
$b = new b();
echo $a->getXName(); // 将返回 "a"
echo $b->getXName(); // 将返回 "b"
echo $a->getXStaticName(); // 将返回 "x"
echo $b->getXStaticName(); // 将返回 "x"
?>
注意,如果你的方法没有声明为静态的,这将不会按预期工作!例如
<?php
类 foo {
静态公共函数 test() {
var_dump(get_called_class());
}
公共函数 testTwo() {
var_dump(get_called_class());
}
}
类 bar 扩展 foo {
}
类 abc {
函数 test() {
foo::test();
bar::test();
}
函数 testTwo() {
foo::testTwo();
bar::testTwo();
}
}
echo "basic\n";
foo::test();
bar::test();
echo "basic without static declaration\n";
foo::testTwo();
bar::testTwo();
echo "in a class\n";
$abc = new abc();
$abc->test();
echo "in a class without static declaration\n";
$abc->testTwo();
?>
结果是
basic
string 'foo'
string 'bar'
basic without static declaration
string 'foo'
string 'bar'
in a class
string 'foo'
string 'bar'
in a class without static declaration
string 'abc'
string 'abc'
这是一个获得类继承树的简单方法,无论函数实际定义在哪个类中。也可以作为静态函数方法工作。
<?php
类 A {
公共函数 get_class_tree(){
$cur_class = get_called_class();
do {
echo $cur_class;
}
while($cur_class = get_parent_class($cur_class));
}
}
类 B {
}
类 C {
}
$foo = new C();
$foo->get_class_tree();
?>
CBA