递归循环创建家谱?(PHP / MySQL / HTML)


Recursive loop to create a family tree? (PHP/MySQL/HTML)

目前正在创建我自己的育种网站,但我正在努力检索,处理和显示给定狗的血统。我可以这样做,如果我几乎硬编码它,但不是动态地检索父母(和父母的父母,等等…),直到父母找不到了。

MYSQL是基本的:

tbl_dogs (表)——dog_id——dog_name——dog_sex——mother_id——father_id

这个想法是检索一只狗的父母,然后检索树中每只狗的父母,直到没有指定mother_id/father_id。

我完全迷路了,到目前为止我一直在做硬编码的方式:

    $mother["id"] = get_post_meta(get_the_ID(), "_mother_id", true);
    $mother["name"] = get_animal_name($mother["id"]);
    $mother["permalink"] = get_the_permalink($mother["id"]);
        $mother_mother["id"] = get_mother_id($mother["id"]);
        $mother_mother["name"] = get_animal_name($mother_mother["id"]);
        $mother_mother["permalink"] = get_the_permalink($mother_mother["id"]);
        $mother_father["id"] = get_father_id($mother["id"]);
        $mother_father["name"] = get_animal_name($mother_father["id"]);
        $mother_father["permalink"] = get_the_permalink($mother_father["id"]);
    $father["id"] = get_post_meta(get_the_ID(), "_father_id", true);
    $father["name"] = get_animal_name($father["id"]);
    $father["permalink"] = get_the_permalink($father["id"]);
        $father_mother["id"] = get_mother_id($father["id"]);
        $father_mother["name"] = get_animal_name($father_mother["id"]);
        $father_mother["permalink"] = get_the_permalink($father_mother["id"]);
        $father_father["id"] = get_father_id($father["id"]);
        $father_father["name"] = get_animal_name($father_father["id"]);
        $father_father["permalink"] = get_the_permalink($father_father["id"]);

然后我将使用我的家谱HTML5结构来显示这些数据。

<div class="pedigree-tree">
  <ul>
    <li><span><a href="<?php echo $mother["permalink"] ?>"><?php echo $mother["name"]; ?></a></span>
      <ul>
        <li><span><a href="<?php echo $mother_mother["permalink"] ?>"><?php echo $mother_mother["name"] ?></a></span>
          <ul>
            <li>
                <span>Grand-Grandmother</span>
                <ul>
                    <li><span><a href="<?php echo $mother_mother["permalink"] ?>"><?php echo $mother_mother["name"] ?></a></span></li>
                    <li><span><a href="<?php echo $mother_mother["permalink"] ?>"><?php echo $mother_mother["name"] ?></a></span></li>
                </ul>
            </li>
            <li><span>Grand-Grandfather</span></li>
          </ul>
        </li>
        <li><span><a href="<?php echo $mother_father["permalink"] ?>"><?php echo $mother_father["name"] ?></a></span>
          <ul>
            <li><span>Entry-1-2-1</span></li>
            <li><span>Entry-1-2-1</span></li>
          </ul>
        </li>
      </ul>
    </li>
    <li><span><a href="<?php echo $father["permalink"] ?>"><?php echo $father["name"]; ?></a></span>
      <ul>
        <li><span><a href="<?php echo $father_mother["permalink"] ?>"><?php echo $father_mother["name"] ?></a></span>
          <ul>
            <li><span>Entry-1-1-1</span></li>
            <li><span>Entry-1-1-1</span></li>
          </ul>
        </li>
        <li><span><a href="<?php echo $father_father["permalink"] ?>"><?php echo $father_father["name"] ?></a></span>
          <ul>
            <li><span>Entry-1-2-1</span></li>
            <li><span>Entry-1-2-1</span></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

但是这个解决方案,虽然有效,但根本不适合我的需要,因为它一点也不灵活。我想构建一个函数,它可以遍历我所要求的所有代(如果它们存在的话),并将其放入一个数组中,然后通过嵌套的HTML列表输出,如上所述。

这个"逻辑循环"来检索所有的父母是把我逼疯了,任何帮助将不胜感激。万分感谢!

没什么大不了的。所以基本上你检查一只狗是否有母亲和/或父亲,然后对每只狗再次执行这个函数。

$stmnt = $pdo->prepare("
    SELECT dog_id, dog_name, dog_sex, mother_id, father_id
    FROM tbl_dogs
    WHERE dog_id = ?
");
fetchDogRecursive($yourDogId);
function fetchDogRecursive($dogId)
{
    $stmnt->execute(array($dogId));
    $dogData = $stmnt->fetchAll(PDO::FETCH_ASSOC)[0];
    $dog = array(
        'id' => $dogData['dog_id'],
        'name' => $dogData['dog_name'],
        'mother' => null,
        'father' => null
    );
    if($dogData['mother_id'] !== null) {
        $dog['mother'] = fetchDogRecursive($dogData['mother_id']);
    }
    if($dogData['father_id'] !== null) {
        $dog['father'] = fetchDogRecursive($dogData['father_id']);
    }
    return $dog;
}

基本思想是这样的:

function getDog ($id)
{
    // do your lookup
    if (isset($dog->father_id) && !empty($dog->father_id)) {
        $dog->father = getDog($dog->father_id);
    }
    if (isset($dog->mother_id) && !empty($dog->mother_id)) {
        $dog->mother = getDog($dog->mother_id);
    }
    return $dog;
}

这并不美观,您需要添加逻辑来查找适当的祖先名称,但是您可以使用getDog(123)->father->father

获得狗的祖父。

另一个可能解决方案的起点:

function tree($motherId) {
    $tree = array();
    while ($motherId <> 0) :
        $sqlToGetMother = "SELECT * FROM tbl_dogs WHERE mother_id = ".$motherId;
       // run the query.....
       $motherId = "dog_id from the query above";
       $motherName = "dog_name from the query above";
       $tree[] = $motherName;
    endwhile;
    // if you need to reverse the family tree
    krsort($tree);
    return $tree;
}

// Starts with a given dog_id....
tree($dog_id);

由您来保护sql代码,您可以重复父树的函数或将母亲和父亲组合在同一个函数中。