静态和动态调用相同的方法

时间:2014-01-17 22:17:37

标签: php methods orm static call

我正在编写一个类似于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);


    }

}

两者都是班级的一部分。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

这段代码有很多问题。比你的许多逻辑错误(你为什么设置$self = $this,然后设置$self->db = NULL,然后设置$self->db = $this->db?)更重要的是你误解了能够动态调用静态函数意味着什么PHP。对象$this在静态方法中根本不存在。调用$podcast->findAll()看起来是非静态的,但它仍然是静态的。

要做你想做的事,这里有一些选择:

  1. 保持函数静态并根据需要调用findAll($this->db, $tablename)
  2. 将函数放入db类并使用参数tablename
  3. 调用它

    编辑:

    我列表中的第二个是如何做到的。这是因为您的原始示例中必须有一个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);
        }
    }