PHP递归以及如何在递归调用中获取数组变量来维护值
我有一个有顶级评论的评论系统,每个评论都可以有无限级别的回复评论。我试图将所有注释id按降序排列到一个数组中 当我只回显结果时,PHP/SQL代码运行良好。但是,我想以数组中正确顺序的注释列表作为结束。当数组变量通过递归例程传递时,它似乎失败了。我理解这是PHP递归中的变量范围问题 那么,为了得到我想要的东西,需要做些什么呢 我的代码:PHP递归以及如何在递归调用中获取数组变量来维护值,php,mysql,sql,recursion,Php,Mysql,Sql,Recursion,我有一个有顶级评论的评论系统,每个评论都可以有无限级别的回复评论。我试图将所有注释id按降序排列到一个数组中 当我只回显结果时,PHP/SQL代码运行良好。但是,我想以数组中正确顺序的注释列表作为结束。当数组变量通过递归例程传递时,它似乎失败了。我理解这是PHP递归中的变量范围问题 那么,为了得到我想要的东西,需要做些什么呢 我的代码: //get all comments and descendants for post id function get_comment_list($db,$po
//get all comments and descendants for post id
function get_comment_list($db,$post_id) {
$comment_array = array();
$sql = "SELECT comment_id FROM comments WHERE parent = 0 AND _post_id=".$post_id." "."ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $parent){
echo $parent;echo '<br>';//first level parent comment
$comment_array[] = $parent;//store comment_id's
get_descendants($db,$parent,$comment_array);
}
return $comment_array;
}
//get all descendants of parent level comments
function get_descendants($db,$parent,$comment_array){
$sql = "SELECT comment_id FROM comments WHERE parent = $parent ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $item){
echo ' '.$item;echo '<br>';
$comment_array[]=$item;//store comment_id's
get_descendants($db,$item,$comment_array);
}
}
$post_id = 199;
$comment_list = array();
$comment_list = get_comment_list($db,$post_id);
print_r($comment_list);
当我打印数组时,我只得到顶级id。在递归调用期间未添加子体
295
294
244
241
240
237
236
230
或者,您是否可以建议一个按降序进行的递归MYSQL查询
基本数据结构是:
comment_id comment parent post_id
父项将引用注释id作为其父项。parent=0是顶级父级。请尝试此操作>
//get all comments and descendants for post id
function get_comment_list($db,$post_id) {
$comment_array = array();
$sql = "SELECT comment_id FROM comments WHERE parent = 0 AND _post_id=".$post_id." "."ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $parent){
$comment_array[$parent] = get_descendants($db,$parent);
//Use Parent ID as a key then push all childs comment under this parent ID
}
print_R($comment_array);die;
return $comment_array;
}
//get all descendants of parent level comments
function get_descendants($db,$parent,$childComment_array = array()){
if(empty($childComment_array)){
$repliedComments = array();
}else{
$repliedComments = $childComment_array;
}
$sql = "SELECT comment_id FROM comments WHERE parent = $parent ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $item){
$repliedComments[]=$item;
get_descendants($db,$item,$repliedComments);
}
return $repliedComments;
}
我发现了一种使用会话数组变量的解决方法。它通过递归函数持续存在。调整代码:
$_SESSION['list']=array();
//get all comments and descendants for post id. First get parents at = 0, then recurse through children/descendants
function get_comment_list($db,$post_id) {
$comment_array = array();
$sql = "SELECT comment_id FROM comments WHERE parent = 0 AND _post_id=".$post_id." "."ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $parent){
//echo $parent;echo '<br>';//first level parent comment
$_SESSION['list'][] = $parent;//store comment_id's
get_descendants($db,$parent);
}
return $_SESSION['list'];
}
//get all descendants of parent level comments
function get_descendants($db,$parent){
$sql = "SELECT comment_id FROM comments WHERE parent = $parent ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $item){
//echo ' '.$item;echo '<br>';
$_SESSION['list'][]=$item;//store comment_id's
get_descendants($db,$item);
}
}
$post_id = 199;
$comment_list = get_comment_list($db,$post_id);
print_r($comment_list);
unset($_SESSION['list']);
$\u会话['list']=array();
//获取帖子id的所有注释和子体。首先获取=0处的父项,然后通过子项/子体递归
函数get_comment_list($db,$post_id){
$comment_array=array();
$sql=“从父项为0的注释中选择注释\u id”,“按日期描述排序”;
$result=$db->query($sql);
$q=$result->fetchAll(PDO::FETCH_列,0);//带有“0”参数的一级数组
foreach($q作为$parent){
//echo$parent;echo“
”;//第一级父注释
$\u会话['list'][]=$parent;//存储注释id
获取子代($db,$parent);
}
返回$_会话['list'];
}
//获取父级注释的所有子体
函数get_子体($db,$parent){
$sql=“从注释中选择注释\u id,其中父项=$parent ORDER BY dateTime DESC”;
$result=$db->query($sql);
$q=$result->fetchAll(PDO::FETCH_列,0);//带有“0”参数的一级数组
foreach($q作为$item){
//回显“”。$item;回显“
”;
$\会话['list'][]=$item;//存储注释id
获取子体($db$item);
}
}
$post_id=199;
$comment\u list=get\u comment\u list($db,$post\u id);
打印(评论列表);
取消设置($_会话['list']);
这里是获取帖子的单循环递归另一个递归循环显示在列表结果中
保护递归(最多40级帖子)
完全可行代码 $database用于全局避免大堆栈 (我添加了一个(字符串)字段注释,您可以删除或替换它,这是出于测试目的)
保险商实验室{
左边框:实心1px灰色;
边缘顶部:1米;
}
ul span.bold{
字体大小:粗体;
}
POST测试
您是否只有一条注释为0的记录?否,可以有多条注释为0的父记录。比如说某人发布了一段视频。直接对发布的注释将位于父项=0处。对评论的回复将具有parent=评论\u id。。。启用嵌套或分层答复。不太有效。向后并缺少后续级别,但不完全正确。结果是:230:{0:'235',1:'231},236:{},237:{0:'291',1:'238},240:{0:'290},241:{0:'292',1:'289',2:'283},244:{0:'304',1:'293',2:'288:'284',6:'282',7:'281',8:'279},294:{295 0:'296}
$_SESSION['list']=array();
//get all comments and descendants for post id. First get parents at = 0, then recurse through children/descendants
function get_comment_list($db,$post_id) {
$comment_array = array();
$sql = "SELECT comment_id FROM comments WHERE parent = 0 AND _post_id=".$post_id." "."ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $parent){
//echo $parent;echo '<br>';//first level parent comment
$_SESSION['list'][] = $parent;//store comment_id's
get_descendants($db,$parent);
}
return $_SESSION['list'];
}
//get all descendants of parent level comments
function get_descendants($db,$parent){
$sql = "SELECT comment_id FROM comments WHERE parent = $parent ORDER BY dateTime DESC";
$result = $db->query($sql);
$q = $result->fetchAll(PDO::FETCH_COLUMN, 0);//one level array with '0' parameter
foreach($q as $item){
//echo ' '.$item;echo '<br>';
$_SESSION['list'][]=$item;//store comment_id's
get_descendants($db,$item);
}
}
$post_id = 199;
$comment_list = get_comment_list($db,$post_id);
print_r($comment_list);
unset($_SESSION['list']);
<html>
<head>
<style>
ul {
border-left:solid 1px gray;
margin-top:1em;
}
ul span.bold {
font-weight:bold;
}
</style>
</head>
<body>
<H1>POSTs TEST</H1>
<?php
// get informations
// @PARAM $startParent = first id parent,
// @PARAM $whereToAppend = $root = array to fill
// @PARAM $level = increase each recursion, stop if greater than 40
function getComments($startParent,&$whereToAppend,$level) {
// use global database handler
global $bdd;
// secure infinite loop !
if ($level>40) { return; }
// get alls post with id_parent=$startParent
$i=0;
// NOTE you can append a SORT tag, DESC if you want etc...
$sql="select comment_id, parent, comment from comments where parent=$startParent";
$result = $bdd->query($sql);
// prepare a structure to store one post
while ($donnees = $result->fetch()) {
$datas=array('comment_id'=>$donnees['comment_id'],
'parent'=>$donnees['parent'],
'comment'=>$donnees['comment']
);
// for more readability
// this post has a id
$id=$datas['comment_id'];
// store the post in three
$whereToAppend[$i]['id']=$id;
$whereToAppend[$i]['datas']=$datas;
$whereToAppend[$i]['sub']=array();
// next post (always for post who has a id_parent : see parameters)
$i++;
}
// now recursion...
foreach ($whereToAppend as $k=>$d) {
// get posts who have parent_id=id of the post found
getComments($d['id'],$whereToAppend[$k]['sub'],$level+1);
}
return ;
}
// used to show result
// @param $start=array to iterate
// @param $level=level , always 0 at first call
function iterate($start,$level=0) {
echo('<ul>');
foreach ($start as $k=>$element) {
echo("<li>");
echo ("comment_id=<span class='bold'>{$element['datas']['comment_id']}</span><br>");
echo ("id parent=<span class='bold'>{$element['datas']['parent']}</span><br>");
echo ("comment=<span class='bold'>{$element['datas']['comment']}</span><br>");
iterate($element['sub'],$level+1);
echo("</li>");
}
echo('</ul>');
}
// MAIN
$bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
// prepare a array where to get informations
$root=array();
// get informations
// first para 0=> id parent, try with another id parent to get partial tree
// second param $root = array to fill
// third param=0, level 0 = recursion start at 0
getComments(0,$root,0);
// show informations
iterate($root,0);
?>
</body>
</html>