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 bel
Maybe this isn't actually answering the question, but you could add a parameter to get() specifing the type. then you can call
BaseModel::get('User', 1);
instead of calling User::get(). You could add logic in BaseModel::get() to check whether a get method exists in the subclass and then call that if you want to allow the subclass to override it.
Otherwise the only way I can think of obviously is by adding stuff to each subclass, which is stupid:
class BaseModel {
public static function get() {
$args = func_get_args();
$className = array_shift($args);
//do stuff
echo $className;
print_r($args);
}
}
class User extends BaseModel {
public static function get() {
$params = func_get_args();
array_unshift($params, __CLASS__);
return call_user_func_array( array(get_parent_class(__CLASS__), 'get'), $params);
}
}
User::get(1);
This would probably break if you then subclassed User, but I suppose you could replace get_parent_class(__CLASS__)
with 'BaseModel'
in that case
In case you don't want to use get_called_class() you can use other tricks of late static binding (PHP 5.3+). But the downside in this case you need to have getClass() method in every model. Which is not a big deal IMO.
<?php
class Base
{
public static function find($id)
{
$table = static::$_table;
$class = static::getClass();
// $data = find_row_data_somehow($table, $id);
$data = array('table' => $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)
It appears you might be trying to use a singleton pattern as a factory pattern. I would recommend evaluating your design decisions. If a singleton really is appropriate, I would also recommend only using static methods where inheritance is not desired.
class BaseModel
{
public function get () {
echo get_class($this);
}
public static function instance () {
static $Instance;
if ($Instance === null) {
$Instance = new self;
}
return $Instance;
}
}
class User
extends BaseModel
{
public static function instance () {
static $Instance;
if ($Instance === null) {
$Instance = new self;
}
return $Instance;
}
}
class SpecialUser
extends User
{
public static function instance () {
static $Instance;
if ($Instance === null) {
$Instance = new self;
}
return $Instance;
}
}
BaseModel::instance()->get(); // value: BaseModel
User::instance()->get(); // value: User
SpecialUser::instance()->get(); // value: SpecialUser