在PHP中具有唯一名称的递归函数

1) I am selecting a goat from dropdown list and having goat_id and its sire and dam both fields are stores parent goat_name.

2) I am try to call it recursively with goat_name, for each sire and dam both fields.

function generate_tree($goat_id) 
{
    global $wpdb;

    // get all records from database whose parent is $id
    $sql = $wpdb->prepare("SELECT * FROM mm_goats WHERE id = %d", $goat_id);
    $row2 = $wpdb->get_row($sql, ARRAY_A);

    //check if there are any results

        if(!empty($row2))
        {
            echo "<ul>";
            if($row2['sire'] != "" || $row2['dam'] != "")
            {
                //print result and call function to check if it has children
                echo "<li>Sire: ".$row2['sire']."</li>";
                echo "<li>Dam: ".$row2['dam']."</li>";
                generate_tree($row2['id']);
            }
            echo "</ul>";
        }
}

I used this function its goes to infinite loop with first selected sire and dam.

Follow this structure. for ex: enter image description here

$sql = $wpdb->prepare("SELECT * FROM mm_goats WHERE id = %d", $goat_id);
                                                    ^^^^^^^                          

You fetch the indicated ID, which then is used in the recusrive call:

            generate_tree($row2['id']);
                          ^^^^^^^^^^^

So you just keep fetching information about the SAME goat on every recursive iteration. Goat #42 -> Goat #42 -> Goat #42 etc... until you hit the recursion/memory limit.

Your recursive call should be using the dam/sire IDs:

  generate_tree($row['id_of_dam']);
  generate_tree($row['id_of_sire']);

instead.

#42 -> #7,10 -> #1,2,3,4 etc...

You should update your table structure to something like

mm_goats
   - id
   - sire_id
   - dam_id
   - name

you can then do an inner join to select them

SELECT `mm_goats`.`name`, `mm_goats`.`sire_id`, `mm_goats`.`dam_id`, `sire`.`name` AS `sire_name`, `dam`.`name` AS `dam_name`
    FROM `mm_goats`
        INNER JOIN `mm_goats` AS `sire` ON `mm_goats`.`sire_id` = `sire`.`id`
        INNER JOIN `mm_goats` AS `dam` ON `mm_goats`.`dam_id` = `dam`.`id`
    WHERE `mm_goats`.`id` = %d

after this you can then initiate your recursion

echo "<li>Sire: ".$row2['sire_name'];
generate_tree($row2['sire_id']);
echo "</li>";
echo "<li>Dam: ".$row2['dam_name'];
generate_tree($row2['dam_id']);
echo "</li>";