Getting the name of a child class in the parent cl

2020-01-27 11:35发布

I'm building an ORM library with reuse and simplicity in mind; everything goes fine except that I got stuck by a stupid inheritance limitation. Please consider the code below:

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();

Obviously, this is not the behavior I was expecting (although the actual behavior also makes sense).. So my question is if you guys know of a mean to get, in the parent class, the name of child class.

9条回答
疯言疯语
2楼-- · 2020-01-27 12:15

I know its old post but want to share the solution I have found.

Tested with PHP 7+ Use the function get_class()link

<?php
abstract class bar {
    public function __construct()
    {
        var_dump(get_class($this));
        var_dump(get_class());
    }
}

class foo extends bar {
}

new foo;
?>

The above example will output:

string(3) "foo"
string(3) "bar"
查看更多
够拽才男人
3楼-- · 2020-01-27 12:16

in short. this is not possible. in php4 you could implement a terrible hack (examine the debug_backtrace()) but that method does not work in PHP5. references:

edit: an example of late static binding in PHP 5.3 (mentioned in comments). note there are potential problems in it's current implementation (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"
查看更多
ら.Afraid
4楼-- · 2020-01-27 12:16

The problem is not a language limitation, it is your design. Never mind that you have classes; the static methods belie a procedural rather than object-oriented design. You're also using global state in some form. (How does get_row_from_db_as_array() know where to find the database?) And finally it looks very difficult to unit test.

Try something along these lines.

$db = new DatabaseConnection('dsn to database...');
$userTable = new UserTable($db);
$user = $userTable->get(24);
查看更多
登录 后发表回答