我正在编写一个类似于orm的php类。 我有一个方法,可以静态或实例化,它必须在两种情况下都有效。 你能看出什么是错的吗? 基本上是一个名为Model的对象。 创建时,它会根据继承的类创建一个表。 例如:
Podcast extends Model ....
有一些像这样的函数需要静态和动态调用。 例如:
$podcastList = Podcast::findAll($db);
我从DB获取所有播客对象,而无需实例化播客对象。 但我也可以这样做:
$podcast = new Podcast($db)
$podcastList = $podcast->findAll(); //no db here.... passed before
$ db是我编写的用于在Database上进行操作的类。 IT只是简单地使用OOP,mysql_ *对函数的作用。我没有使用PDO,我可能会在将来使用,但现在我使用的是mysql_ *:P
是有罪的职能
public static function findAll($db=NULL, $self=NULL) {
if($self == NULL) {
$self = new static($db);
} else {
$self = $this;
}
$self->tableName = "";
$self->db = NULL;
$is_static = !(isset($this) && get_class($this) == __CLASS__);
if($is_static) {
//die(__CLASS__ . "::" . __FUNCTION__ . " CALLED STATICALLY");
if(!$self->db) {
die(__CLASS__ . "::" . __FUNCTION__ . " CALLED STATICALLY AND DB IS NULL");
//It stops here!
}
$self->tableName = $self->genTableName();
} else {
$self->db = $this->db;
$self->tableName = $this->tableName;
}
$query = "SELECT * FROM {$self->tableName}";
$r = $self->db->exec($query);
if(!$r) {
die(__CLASS__ . ":Error " . __FUNCTION__ . " record: " . $self->db->getError());
}
if($self->db->countRows($r) == 0) {
return NULL;
}
$objects = array();
while($row = $self->db->fetch($r, DBF::FETCH_ASSOC)) {
$objectClass = __CLASS__;
$object = new $objectClass($this->db);
//TODO Do it dinamically indipendently of column name
$f = get_class_vars($objectClass);
foreach ($f as $field => $value) {
$chuncks = explode("_", $field);
if($chuncks[0] == "f") {
$object->{$field} = $row[$chuncks[2]];
}
}
$objects[] = $object;
}
return $objects;
}
public function __call($name, $arguments) {
if ($name === 'findAll'){
return static::findAll($arguments, $this);
}
}
两者都是班级的一部分。
感谢您的帮助!
答案 0 :(得分:0)
这段代码有很多问题。比你的许多逻辑错误(你为什么设置$self = $this
,然后设置$self->db = NULL
,然后设置$self->db = $this->db
?)更重要的是你误解了能够动态调用静态函数意味着什么PHP。对象$this
在静态方法中根本不存在。调用$podcast->findAll()
看起来是非静态的,但它仍然是静态的。
要做你想做的事,这里有一些选择:
findAll($this->db, $tablename)
tablename
编辑:
我列表中的第二个是如何做到的。这是因为您的原始示例中必须有一个db
对象,并且没有任何特别的功能使该函数的目的仅适用于Podcast对象,而不适用于表示数据库行的任何其他对象。
//calling examples:
$podcastlist = $db->findAll('Podcast');
$podcast = new Podcast($db);
$podcastlist = $podcast->findAll();
public class db {
....
function findAll($classname, $tablename=NULL) {
if(!isset($tablename)) {
//let's pretend you put default table names as class constants
$tablename = get_constant($classname.'::DEFAULT_TABLE');
}
$query = "SELECT * FROM {$tableName}";
$r = $this->exec($query);
if(!$r) {
throw new Exception("Error " . __FUNCTION__ . " record: " . $this->getError());
}
if($this->countRows($r) == 0) {
return NULL;
}
$objects = array();
while($row = $this->fetch($r, DBF::FETCH_ASSOC)) {
$object = new $classname($this);
//the following is an easier way to do your original foreach
foreach($row as $field=>$value) {
if(property_exists($classname, "f_".$field)) {
$object->{'f_'.$field} = $value;
}
}
$objects[] = $object;
}
//something you forgot:
return $objects;
}
}
public class Podcast extends Model {
....
public function findAll($tablename=NULL) {
return $this->db->findAll(class_name($this), $tablename);
}
}