【问题标题】:How to make model "hasMany" and "belongsTo"? (Same like cakePHP)如何制作模型“hasMany”和“belongsTo”? (和 cakePHP 一样)
【发布时间】:2011-10-01 09:57:42
【问题描述】:

我目前正在开发我的 mvc 框架(在 PHP 中)。我看到 cakePHP 能够使用“belongsTo”和“hasMany”特性。我正在尝试创建自己的功能,但遇到了问题。

假设我们有约会表(id、where、date、year_id)和年份表(id、year)。我知道这个例子可以用一张桌子来完成,但这只是一个例子。

class appointment_model extends model{
    public $_belongs_to= array('table'=>'year','field_connector'=>'year_id');
    public $one_value;
}

......

class year_model extends model{
    public $_has_many= array('table'=>'appointment','field_connector'=>'year_id');
    public $many_values;
}

....

class model{

private function select($query=null){
    if(!$query)die("Query cannot be null. Line num: " . __LINE__);
    $results = $this->_db->mysql_select($query);
    if(count($results)==1){
        $one = $this->initialize($results[0]);
        $this->_do_for_other_tables($one);
        return $one;
    }elseif(count($results)>1){
        $returns = array();
        foreach($results as $result){
            $one = $this->initialize($result);
            $returns[] = $this->_do_for_other_tables($one);     
        }
        return $returns;
    }else{
        return null;
    }

}


private function _do_for_other_tables(&$one, $rec=1){


    if(property_exists($this, 'many_values')){
        if(!empty($one->many_values))return;
        $many = functions::load_model($this->_has_many["table"]);
        $res = $many->find_by($this->_has_many["field_connector"], $one->id);
        $one->many_values = $res;
    }
    elseif(property_exists($this, 'one_value')){
        if(!empty($one->_belongs_to))return;
        $only_one = functions::load_model($this->_belongs_to["table"]);
        $field = $this->_belongs_to['field_connector'];
        $res = $only_one->find_by('id', $one->$field);
        $one->one_value = $res;
    }

}

}

基本上这里发生的是我进入了无限循环。有什么建议我该如何解决?如果我需要更多解释,就直说吧。

谢谢:)。

【问题讨论】:

  • 你为什么要重新发明轮子?教义开箱即用!
  • @Francesco:这并不是因为您不想知道其他人也不想知道它是如何工作的。我自己构建了无数个框架来满足我的需求,因为它们中的每个人都不适合我的。这里的 Vizualni 可能也是如此……

标签: php cakephp activerecord


【解决方案1】:

您的问题是您将属性“hasMany”、“belongsTo”、“hasOne”、“etc”视为简单属性,而不是将它们视为 2way 关系。我在自己的许多框架中所做的是由程序员手动初始化这些属性,但是当类初始化时,您检查这些属性并生成将两者链接在一起的单个对象。

创建一个类似于 System_DB_Relationship 对象的类,然后将相同的副本放置在两个已初始化的模型中。如果您没有将模型实例化为工厂设计模式,您也可以使用静态 $relationship 模型来存储您的关系。我倾向于去工厂/活动记录,所以最好管理这些。现在,根据您的模型基类的逻辑,您可能希望在关系中放置一个标志,表示“嘿,此关系已被使用”,这样您就不会再次传入它。

另一种方法是始终以降序方式工作。也就是说,找到hasMany时忽略它,只创建一个代理方法来加载子元素,但加载所有的belongsTo,以便默认加载父元素。请注意,如果您有大量类,则此方法可能会变得危险,因此我在框架中实现的通常是加载参数,表示加载 X 级关系。当你想要 hasMany 时,你只需使用 __call() 来拦截对“$myobject->subobjects()”的调用并即时加载它们。

有很多方法可以做到这一点,只需花点时间手动跟踪您的代码,看看没有意义的地方,尝试一些东西,最终您会有所收获。但正如 Francesco 上面所说,除非您从事无法立即转变的非常古老的项目,否则重新发明轮子几乎没有用处。把你正在做的工作当作一个机会,让你变得更好,并了解它是如何运作的......

【讨论】:

  • 感谢您的回答。我改变了 60% 的模型类,所以我可以使用 MySQL 选择查询和两个选定的表。这样做要容易得多。你的回答真的很有帮助。谢谢。
  • 那么请您在答案中打勾,谢谢。这不是我贪婪,这只是它应该在 stackoverflow 上工作的方式,如果你不将帖子标记为答案,你会降低你的接受分数......
猜你喜欢
  • 1970-01-01
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
相关资源
最近更新 更多