2014-01-17 5 views
0

Я пишу класс php, который похож на orm. У меня есть метод, который можно назвать статически или instanciated, и он должен работать в обоих случаях. Вы видите, что не так. В основном это объект под названием Модель. При создании создается таблица, основанная на унаследованном классе. Например:вызов статически и динамически одного метода

Podcast extends Model .... 

Есть некоторые функции, такие как это, что должна быть вызвана статически и динамически. , например:

$podcastList = Podcast::findAll($db); 

Я получаю все подкасты объекты из БД без необходимости иметь объект подкаста инстанциирован. Но я также могу сделать:

$podcast = new Podcast($db) 
$podcastList = $podcast->findAll(); //no db here.... passed before 

$ дб класс я написал, чтобы сделать операцию по базе данных. 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

Каждое свойство класса, которое начинается с f, рассматривается как поле таблицы mysql. – apubaba

+0

Например $ podcast-> f_foo считается полем podcasts_table.foo – apubaba

ответ

0

С этим кодом очень много. Более важно, чем ваши многочисленные логические ошибки (почему вы устанавливаете $self = $this, затем $self->db = NULL, затем $self->db = $this->db?) Заключается в том, что вы не понимаете, что значит иметь возможность динамически вызывать статические функции в PHP. Объект $this просто не существует в статическом методе. Вызов $podcast->findAll() выглядит нестационарным, но он по-прежнему является статичным.

Чтобы сделать то, что вы хотите сделать, вот несколько вариантов:

  1. оставить функцию статического и вызвать findAll($this->db, $tablename) при необходимости
  2. поставить функцию в класс БД и вызвать его с параметром tablename

EDIT:

Второй в моем списке, как я бы это сделать. Это связано с тем, что вы уже должны иметь объект 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); 
    } 
} 
+0

Большое вам спасибо! Да, я немного запутался в том, как управлять статическими и нестационарными методами. Я изучаю этот код :) – apubaba

Смежные вопросы