加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – Propel ORM自引用外键

发布时间:2020-12-13 16:50:17 所属栏目:PHP教程 来源:网络整理
导读:我正在使用Propel ORM和Propel的新手.我需要一些帮助从一个表中选择数据,但我无法做出正确的查询.我有一个这样的表(注意:不是实际的表,但相同的主要): +---------------------+| ID | Page | Parent |+---------------------+| 1 | A | 0 || 2 | B | 0 ||
我正在使用Propel ORM和Propel的新手.我需要一些帮助从一个表中选择数据,但我无法做出正确的查询.我有一个这样的表(注意:不是实际的表,但相同的主要):

+---------------------+
| ID  | Page | Parent |
+---------------------+
| 1   |  A   |  0     |
| 2   |  B   |  0     |
| 3   |  C   |  2     |
| 4   |  D   |  3     |
| 5   |  E   |  1     |
| 6   |  F   |  0     |
| 7   |  G   |  3     |
| 8   |  H   |  4     |
| 9   |  I   |  6     |
| 10  |  J   |  5     |
+---------------------+

加载页面时,此表为我提供了类似树的结构.在使用propel之前,我有一个带有’loadPages’函数的类,它将内部页面嵌套在一个名为$nested的数组中,该类看起来像这样(注意:不是实际函数只是一个近似表示):

function loadPages($parent=0,$data){
    $sql = "sql query here to select pages where parent = $parent";
    while($results){
       $pages = new Pages();
       $pages->setId(blah blah);
       $pages->setPage(blah blah);
       $pages->setParent(blah blah);

       $innerPages = new Pages();
       /* load innerpages into the nested array */
       $innerPages->loadPages($pages->getId(),$pages->nested);

       array_push($data,$pages);
       return true;
    }
}

基本上我怎么能用Propel做到这一点?我可以很容易地将父值为0的页面拉出来:

$pages = PagesQuery::create()
->filterByParent(0)
->find();

但是我需要递归地将内部页面嵌套到它返回的对象上,即使有了Propel网站上的所有优秀文档,我的努力仍然存在.

使用我的旧Pages类,如果我print_r $data,我会得到这样的东西(仅仅是使用上表的一个例子.):

Array(
   [0] => Pages Object
   (
    [id] => 2
    [page] => B
    [parent] => 0
    [nested] = Array(
       [0] => Pages Object
       (
        [id] => 3
        [page] => C
        [parent] => 2
       )
    )
)

我有这个工作,但我不知道这是最好的方式.

function loadPages($parent=0,$siteId,&$arr){
        $arr = PagesQuery::create()
        ->filterBySiteId($siteId)
        ->filterByParentId($parent)
        ->find();

        foreach ($arr as $i => $v) {
            $arr[$i]->nested = '';
            loadPages($v->getId(),$arr[$i]->nested);
        }

    }
    $site->pages = '';
    loadPages(0,$site->getId(),$site->pages);

我的架构没有自我关系设置,所以我刚刚在同一个表中添加了一个外键,并重新运行propel来重新创建类.我仍然不确定如何编写推进查询(为了节省空间,我已经从架构中删除了几个列).对不起,这个帖子现在开始了.

<table name="pages" phpName="Pages">
    <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
    <column name="userId" type="integer" required="false"/>
    <column name="siteId" type="integer" required="false"/>
    <column name="parentId" type="integer" required="false"/>
    <foreign-key foreignTable="users" phpName="Users" refPhpName="Pages">
         <reference local="userId" foreign="id"/>
        </foreign-key>
    <foreign-key foreignTable="sites">
          <reference local="siteId" foreign="id"/>
        </foreign-key>
        <foreign-key foreignTable="pages">
         <reference local="parentId" foreign="id"/>
        </foreign-key>
</table>

解决方法

这不是您问题的直接答案,但它仍然是一个解决方案.

正如您在对该问题的评论中提到的那样:嵌套集就是答案.

起初这可能听起来像解决问题的方法,但嵌套集是其他人有类似问题的结果.它是一种很好的研究和一种表示树木的流行方式.它的主要优点是能够管理可变深度树.

你提到你是Propel的新手并且切换到嵌套集会有相当多的工作,所以我冒昧地假设你之前没有使用过Propel的行为.如果是这种情况,请务必阅读文档部分关于Behaviors.

如果你现在喜欢Propel,那么你会喜欢它!

要解决您的问题:请查看NestedSet Behavior.与所有其他行为一样,可以轻松地将其添加到您的架构中.重新生成模型,您只需要对代码进行小的重构(示例将向您展示如何).

(注意:如果您有现有数据库,则需要将该父链接迁移到嵌套集结构.但这基本上是您应该关注的唯一问题.)

Using a RecursiveIterator部分提供了显示整个树的示例.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读