如何在创建子类对象时从基类获取子类名称

5
我希望在基类中获取子类的名称,以便每当创建子类的对象时,我都能在基类中获取子类的名称。就像这样:
class Base_class {
    function __construct() {
        // Some code Here to get the name of the child class
    }
}

class Child_class extends Base_Class {}

class Another_child_class extends Base_Class {}

$object = new Child_Class;
$object2 = new Another_child_class;

当创建$object时,我希望构造函数能够提供创建该对象的类的名称。


我的错误..我实际上想在构造函数中获取子类的名称。 - Mohan
你需要在输出中实际获得什么? - Narendrasingh Sisodia
超类不应该意识到它们的扩展。如果您需要根据类类型进行决策,请考虑使用工厂模式。 - moonwave99
我正在使用CodeIgniter框架,有一个MY_Model类,所有其他模型都将继承它。因此,我决定将我的模型命名为与数据库中表名相同的名称。因此,当我创建一个模型并仅通过扩展MY_Model类时,我希望能够获取子模型的名称,以便从数据库中获取其关联表并执行所需的查询。 - Mohan
显示剩余3条评论
4个回答

10

在一定程度上是可以的。在PHP 5.5中,添加了::class类常量,它返回应用于其上的类的类名。然后您可以将其与parentselfstatic结合使用。考虑以下代码:

<?php

class A {}

class B extends A
{
    public function foo() {
        echo parent::class . "\n";    // A
        echo __CLASS__ . "\n";        // B
        echo self::class . "\n";      // B
        echo static::class . "\n";    // D
        echo get_class($this) . "\n"; // D
    }
}

class C extends B {}
class D extends C {}

(new D)->foo();

self::class 将返回与 __CLASS__ 相同的结果,即当前执行函数所属的类 (在这种情况下为 B)。

parent::class 将返回该方法的父类名称 (A)。

static::class 通过Late Static Binding机制,将返回实际调用该方法的类名 (D)。

注意,如果不使用更高级的方法(比如通过debug_backtrace解析调用堆栈或反射),则无法获取当前函数的直接子孙类(C)。


5

可以使用 static::classget_class($this)get_called_class())在基类中获取子类的名称(在运行时最初被调用):

<?php

class Foo 
{

    public function __construct()
    {
        var_dump(static::class, get_class($this), get_called_class());
    }

}

class Bar extends Foo { }

class Baz extends Bar { }

new Foo();
new Bar();
new Baz();

生成:

string(3) "Foo"
string(3) "Foo"
string(3) "Foo"
string(3) "Bar"
string(3) "Bar"
string(3) "Bar"
string(3) "Baz"
string(3) "Baz"
string(3) "Baz"

这被称为延迟静态绑定。这里有一个演示

1
对于需要5.3版本的任何人,get_called_class() - Dan Lugg

2
您可以使用get_class(),将当前对象引用传递给它,如下所示:
class Base_class {

    function __construct() {
        $calledClassName = get_class($this);
    }

}

编辑:您可以在PHP手册中找到更多关于get_class()的信息:http://php.net/manual/en/function.get-class.php


我的错误..实际上我想在构造函数中获取子类的名称,这样我就不需要从外部进行其他调用了。 - Mohan
这将输出基类的名称。 - Mohan
不,这个可以正常工作,但@moonwave99是对的,它有点像代码异味。 - PiranhaGeorge

0

好的,那就明确地传递它:

class BaseClass{

  function __construct($tableName){
    // do stuff w/ $tableName
  }

}

class ChildClass extends BaseClass{

  function __construct(){
    parent::__construct('ChildClass');
  }

}

你的方法最明智,不应该被踩。给你点赞! - PiranhaGeorge
因为硬编码类名是一个相当糟糕的“解决方案”。 - PeeHaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接