Php pdo:可以在递归中重用prepare语句吗?


Php pdo: Is it possible to reuse prepare statement in recursive

尝试遍历DB中的树形结构数据

表是这样的

main_id  sub_id
------------------------
1            2
1            3
2            4
3            5

我的功能如下:

$sql="Select * from info_map where main_id= ? ";
$stmt=$conn->prepare($sql);
if(!$stmt){ throw new Exception ( implode(' ',$conn->errorInfo()),0); }
search_child($stmt,215);
function search_child($stmt,$mom){   
   $res=$stmt->execute(array($mom));
   if(!$res){ throw new Exception( implode(' ',$stmt->errorInfo()),1); }
   $rc=$stmt->rowCount();
   if($rc>0){
        while($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)){
            $nextMom=$row['sub_id'];
            echo $mom.'->'.$nextMom.'<br>';
            search_child($stmt,$nextMom);
        }    
}

$stmt=$conn->prepare()在函数内,我得到了我想要的结果(返回所有的孩子和他们的孙子....等)

,但它没有重用prepare语句,因为我们运行相同的sql。

所以我把$stmt=$conn->prepare()移出函数,就像上面的代码一样,但这样它只返回一个子节点和它的孙子节点。

我可以在递归函数中重用这样的语句对象吗?还是我做错了什么?


更新:@Barmar你的回复帮助我意识到为什么我只有一行家谱,因为当循环回到第二代的第二个孩子时,语句obj已经消失了,因为它已经被用于其他一代的查询(第二代的第一个孩子的后代),谢谢。

正如@Barmar所暗示的,php和mysql服务器之间可能存在一些冲突。我通常为我的递归函数传递准备好的语句没有问题,但通过fetchAll()这样得到结果:

function search_child($stmt,$mom){   
    $res=$stmt->execute(array($mom));
    if(!$res){ throw new Exception( implode(' ',$stmt->errorInfo()),1); }
    foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row){ 
    // PDO fetch orientation is next by default. no need to specify it.
        $nextMom=$row['sub_id'];
        echo $mom.'->'.$nextMom.'<br>';
       search_child($stmt,$nextMom);
    }   
}