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

Php 静态和动态调用相同的方法,php,methods,orm,static,call,Php,Methods,Orm,Static,Call,我正在编写一个类似于orm的php类。 我有一个方法,可以静态调用或实例化,它必须在这两种情况下都能工作。 你能看出来是怎么回事吗。 基本上是一个名为Model的对象。 创建时,它会基于继承的类创建一个表。 例如: Podcast extends Model .... $podcastList = Podcast::findAll($db); 有些类似的函数需要静态和动态调用。 例如: Podcast extends Model .... $podcastList = Podcast::f

我正在编写一个类似于orm的php类。 我有一个方法,可以静态调用或实例化,它必须在这两种情况下都能工作。 你能看出来是怎么回事吗。 基本上是一个名为Model的对象。 创建时,它会基于继承的类创建一个表。 例如:

Podcast extends Model ....
$podcastList = Podcast::findAll($db);
有些类似的函数需要静态和动态调用。 例如:

Podcast extends Model ....
$podcastList = Podcast::findAll($db);
我从DB获取所有播客对象,而不需要实例化播客对象。 但我也能做到:

$podcast = new Podcast($db)
$podcastList = $podcast->findAll(); //no db here.... passed before
$db是我编写的用于对数据库进行操作的类。它只是用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);


    }

}
两者都是一个类的一部分


谢谢你的帮助

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

要执行您想要执行的操作,以下是一些选项:

  • 让函数保持静态,并根据需要调用
    findAll($this->db,$tablename)
  • 将函数放入db类,并使用参数
    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);
        }
    }
    

    类中以f开头的每个属性都被视为mysql表的字段。例如$podcast->f\u foo被视为podcast\u table的字段。fooThank!谢谢!是的,我对如何管理静态和非静态方法有点困惑。我研究这个代码:)