从 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
?>
命名空间 root;
类 Factor {
受保护的静态 $instance = null;
私有函数 __construct() {
}
公共静态函数 getInstance() {
如果 (!self::$instance) {
$name = get_called_class();
self::$instance = new $name();
}
返回 self::$instance;
}
}
命名空间 admin\test;
使用 root\Factor;
类 Single 扩展 Factor {
公共函数 abc() {
返回 'abc';
}
}
命名空间 index;
使用 admin\test\Single;
类 Index {
公共函数 get() {
返回 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:: 的常规替换。我已经成功地将所有 $that 用法替换为 static,无论是作为
<?php
static::$foo; //以及...
new static();
?>
由于`static::`有此限制:“另一个区别是`static::`只能引用静态属性”,因此可能仍然需要使用`$that::`来调用静态函数;尽管我还没有用到这个语义。
在PHP 5.6(7以下版本)中静态调用动态方法时,虽然允许这样做,但它不起作用,它会错误地评估调用我们目标类的类,因此包含该方法的类必须是静态的。
可以使用`get_called_class`在PHP 5.3中编写一个完全自包含的单例基类。
<?php
abstract class Singleton {
protected function __construct() {
}
final public static function getInstance() {
static $aoInstance = array();
$calledClassName = get_called_class();
if (! isset ($aoInstance[$calledClassName])) {
$aoInstance[$calledClassName] = new $calledClassName();
}
return $aoInstance[$calledClassName];
}
final private function __clone() {
}
}
class DatabaseConnection extends Singleton {
protected $connection;
protected function __construct() {
// @todo 连接数据库
}
public function __destruct() {
// @todo 关闭数据库连接
}
}
$oDbConn = new DatabaseConnection(); // 致命错误
$oDbConn = DatabaseConnection::getInstance(); // 返回单个实例
?>
如果从另一个类调用静态`getInstance()`函数来创建类的实例,则此函数必须是静态的,如果不是静态的,则返回调用类的原始名称,而不是当前类的名称。
示例
<?php
class a {
function getXName() {
return x::getClassName();
}
function getXStaticName() {
return x::getStaticClassName();
}
}
class b extends a {
}
class x {
public function getClassName() {
return get_called_class();
}
public static function getStaticClassName() {
return 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
class foo {
static public function test() {
var_dump(get_called_class());
}
public function testTwo() {
var_dump(get_called_class());
}
}
class bar extends foo {
}
class abc {
function test() {
foo::test();
bar::test();
}
function testTwo() {
foo::testTwo();
bar::testTwo();
}
}
echo "基本\n";
foo::test();
bar::test();
echo "非静态声明的基本情况\n";
foo::testTwo();
bar::testTwo();
echo "在类中\n";
$abc = new abc();
$abc->test();
echo "在类中,非静态声明\n";
$abc->testTwo();
?>
结果是
基本
string 'foo'
string 'bar'
非静态声明的基本情况
string 'foo'
string 'bar'
在类中
string 'foo'
string 'bar'
在类中,非静态声明
string 'abc'
string 'abc'
这是一个获取类继承树的简单方法,无论函数实际在哪个类中定义。也可以作为静态函数方法工作。
<?php
class A {
public function get_class_tree(){
$cur_class = get_called_class();
do {
echo $cur_class;
}
while($cur_class = get_parent_class($cur_class));
}
}
class B {
}
class C {
}
$foo = new C();
$foo->get_class_tree();
?>
CBA