我正在构建一个重用和简单的ORM库; 一切都很顺利,除了我被一个愚蠢的继承限制所困扰.请考虑以下代码:
class BaseModel { /* * Return an instance of a Model from the database. */ static public function get (/* varargs */) { // 1. Notice we want an instance of User $class = get_class(parent); // value: bool(false) $class = get_class(self); // value: bool(false) $class = get_class(); // value: string(9) "BaseModel" $class = __CLASS__; // value: string(9) "BaseModel" // 2. Query the database with id $row = get_row_from_db_as_array(func_get_args()); // 3. Return the filled instance $obj = new $class(); $obj->data = $row; return $obj; } } class User extends BaseModel { protected $table = 'users'; protected $fields = array('id', 'name'); protected $primary_keys = array('id'); } class Section extends BaseModel { // [...] } $my_user = User::get(3); $my_user->name = 'Jean'; $other_user = User::get(24); $other_user->name = 'Paul'; $my_user->save(); $other_user->save(); $my_section = Section::get('apropos'); $my_section->delete();
显然,这不是我期望的行为(虽然实际行为也有意义).所以我的问题是,如果你们知道在父类中获得子类名称的意思.
如果您能够想到在静态上下文之外执行此操作的方法,则无需等待PHP 5.3.在php 5.2.9中,在父类的非静态方法中,您可以:
get_class($this);
它将以字符串形式返回子类的名称.
即
class Parent() { function __construct() { echo 'Parent class: ' . get_class() . "\n" . 'Child class: ' . get_class($this); } } class Child() { function __construct() { parent::construct(); } } $x = new Child();
这将输出:
Parent class: Parent Child class: Child
甜啊?
简而言之.这是不可能的.在php4中你可以实现一个可怕的黑客(检查debug_backtrace()
)但该方法在PHP5中不起作用.引用:
30423
37684
34421
编辑:PHP 5.3中后期静态绑定的一个例子(在评论中提到).请注意,它的当前实现(src)存在潜在问题.
class Base { public static function whoAmI() { return get_called_class(); } } class User extends Base {} print Base::whoAmI(); // prints "Base" print User::whoAmI(); // prints "User"
我知道这个问题确实很旧,但是对于那些寻找比在包含类名的每个类中定义属性更实用的解决方案的人来说:
您可以使用static
关键字.
正如在php文档中的贡献者注释中所解释的那样
的
static
关键字可以超类中被用来访问该子类从该方法被调用.
例:
class Base { public static function init() // Initializes a new instance of the static class { return new static(); } public static function getClass() // Get static class { return static::class; } public function getStaticClass() // Non-static function to get static class { return static::class; } } class Child extends Base { } $child = Child::init(); // Initializes a new instance of the Child class // Output: var_dump($child); // object(Child)#1 (0) {} echo $child->getStaticClass(); // Child echo Child::getClass(); // Child
我知道它的旧帖子,但想分享我找到的解决方案。
经PHP 7+测试使用功能get_class()
链接
上面的示例将输出:
string(3) "foo" string(3) "bar"
如果你不想使用get_called_class(),你可以使用后期静态绑定的其他技巧(PHP 5.3+).但在这种情况下,你需要在每个模型中都有getClass()方法.这对IMO来说不是什么大问题.
$table, 'id' => $id); return new $class($data); } public function __construct($data) { echo get_class($this) . ': ' . print_r($data, true) . PHP_EOL; } } class User extends Base { protected static $_table = 'users'; public static function getClass() { return __CLASS__; } } class Image extends Base { protected static $_table = 'images'; public static function getClass() { return __CLASS__; } } $user = User::find(1); // User: Array ([table] => users [id] => 1) $image = Image::find(5); // Image: Array ([table] => images [id] => 5)