Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从数据库中获取带有子项的项并显示它们的良好实践方法_Php_Algorithm - Fatal编程技术网

Php 从数据库中获取带有子项的项并显示它们的良好实践方法

Php 从数据库中获取带有子项的项并显示它们的良好实践方法,php,algorithm,Php,Algorithm,我有一份物品清单。每个项目都有子列表。这有点像StackOverflow上的答案,每个答案都有一个0-n子元素的列表 我使用的是一个PHP脚本,我能够在一个查询中查询所有注释和子元素,但是很难正确地组织数据 我遇到的困难是获取所有主要注释,然后聚合它们下面的所有子元素,然后动态地确定何时放置表单以添加额外的子元素 你知道如何以一种或多或少优雅或良好实践的方式做到这一点吗 谢谢 当遇到这个问题时,我通常从我的查询中构建两个数组:一个是主注释,然后是所有子注释中的一个。然后我循环浏览主注释,并使用一

我有一份物品清单。每个项目都有子列表。这有点像StackOverflow上的答案,每个答案都有一个0-n子元素的列表

我使用的是一个PHP脚本,我能够在一个查询中查询所有注释和子元素,但是很难正确地组织数据

我遇到的困难是获取所有主要注释,然后聚合它们下面的所有子元素,然后动态地确定何时放置表单以添加额外的子元素

你知道如何以一种或多或少优雅或良好实践的方式做到这一点吗


谢谢

当遇到这个问题时,我通常从我的查询中构建两个数组:一个是主注释,然后是所有子注释中的一个。然后我循环浏览主注释,并使用一些相关的键在子注释出现时拉入它们。因为o(n^2),它不是很好,但是对于小作业来说,它不是什么大问题。

当面临这个问题时,我通常从我的查询中构建两个数组:一个主注释,然后是一个所有子注释。然后我循环浏览主注释,并使用一些相关的键在子注释出现时拉入它们。因为o(n^2),它不是很好,但对于小作业来说,它不是什么大问题。

我发现唯一一种“适合”我的方法是将数据库中的所有内容读取到DOMDocument中,并将其转换为XML,然后可以使用标准的DOM导航技术遍历节点(如果您只想在URL中传递当前查看的“页面”的ID,则此功能非常有用)


例如,您可以从列表中的最后一个节点开始,然后“向上”列表,直到“parent_id”(例如)==0;

我发现的唯一方法是将整个数据库读取到DOMDocument中,将其转换为XML,然后可以使用标准的DOM导航技术遍历节点(如果您只想在URL中传递当前查看的“页面”的ID,则此功能非常有用)


例如,您可以从列表中的最后一个节点开始,然后在列表中“向上”直到“parent_id”(例如)==0;

如果您有每个项目的parent_id,则很容易使用引用

我的代码中的示例
/**
    * array for storing data
    *
    * @var array
    */
private $tree = array();
   /**
    * html - output of current module
    *
    * @var string
    */
    private $output = ''; 

  /**
   * Retreives data from table items.
   *
   * @return void
   */
    private function _getData()
{
    $pdo = App_Registry::get('pdo');
    $levels = array();
    foreach ($pdo->query('SELECT * FROM sellers ORDER BY parent_id ASC',PDO::FETCH_OBJ) as $k=>$v){
               //tree with references references
         $current =  &$levels[ $v->id ] ;
             $current['parent_id'] = $v->parent_id;
             $current['name'] = $v->name;
             if (0 == $v->parent_id){
             $this->tree[ $v->id ] = &$current;
             } else {
         $levels[$v->parent_id ]['children'][$v->id] = &$current;
             }
    }
}   

/*
*App_AbstractModule::preRender overriding
    * @return void
*/
protected  function preRender()
{
    $this->_getData();
    }
  /**
   * recursively build html output.
   *
   * @return string
   */
private function _render($arr)
{
    $this->output.= '<ul>';
    foreach ($arr as $k=>$v)
    {
        $this->output.= '<li>'.$v['name'].'</li>';
        if( !empty($v['children'])){
            $this->_render($v['children']);
        }
    }
    $this->output.= '</ul>';
    return $this->output;
}
/*
*App_AbstractModule::render overriding
    * @return string
*/
protected  function render()
{
        return $this->_render($this->tree);
}

如果每个项目都有父项id,那么引用就很容易了

我的代码中的示例
/**
    * array for storing data
    *
    * @var array
    */
private $tree = array();
   /**
    * html - output of current module
    *
    * @var string
    */
    private $output = ''; 

  /**
   * Retreives data from table items.
   *
   * @return void
   */
    private function _getData()
{
    $pdo = App_Registry::get('pdo');
    $levels = array();
    foreach ($pdo->query('SELECT * FROM sellers ORDER BY parent_id ASC',PDO::FETCH_OBJ) as $k=>$v){
               //tree with references references
         $current =  &$levels[ $v->id ] ;
             $current['parent_id'] = $v->parent_id;
             $current['name'] = $v->name;
             if (0 == $v->parent_id){
             $this->tree[ $v->id ] = &$current;
             } else {
         $levels[$v->parent_id ]['children'][$v->id] = &$current;
             }
    }
}   

/*
*App_AbstractModule::preRender overriding
    * @return void
*/
protected  function preRender()
{
    $this->_getData();
    }
  /**
   * recursively build html output.
   *
   * @return string
   */
private function _render($arr)
{
    $this->output.= '<ul>';
    foreach ($arr as $k=>$v)
    {
        $this->output.= '<li>'.$v['name'].'</li>';
        if( !empty($v['children'])){
            $this->_render($v['children']);
        }
    }
    $this->output.= '</ul>';
    return $this->output;
}
/*
*App_AbstractModule::render overriding
    * @return string
*/
protected  function render()
{
        return $this->_render($this->tree);
}

这也是我所想的。谢谢!这也会让你知道你什么时候没有或已经用完了子元素,这样你就知道什么时候该放进你的评论框。这也是我所想的。谢谢!这也会让你知道你什么时候没有或已经用完了子元素,这样你就知道什么时候该放进你的评论框。这是一个g好主意…但我觉得用xml做可能有点痛苦哈哈,我会尝试发布的其他解决方案,如果太麻烦,我会尝试你的想法。但是xml生成不是很昂贵吗?@MichaelDillon-它确实有开销,但你可以在更新数据库并将其保存为文本文件时从CMS生成它HTML或XML格式(使用XSLT).这样,您只在更改某些内容时更新它,实际上您减少了网站对数据库的调用,从而减少了瓶颈…但这一切都有点摇摆不定和迂回…基本上,您必须确定DOMDocument的开销是否小于嵌套递归循环和数据库调用的开销,这实际上取决于嵌套的深度。如果您使用的导航系统只有两个级别,那么循环可能还可以-如果它更像旧的skool线程消息板,那么使用DOMDocument可能会降低性能影响。这实际上是个好主意……但我认为使用xml可能有点困难痛呵呵,我会尝试发布的另一种解决方案,如果太麻烦,我会试试你的想法。但是xml生成不是很昂贵吗?@MichaelDillon-它确实有开销,但你可以在更新数据库时从CMS生成,并将其保存为HTML或xml格式的文本文件(使用XSLT).这样,您只在更改某些内容时更新它,实际上您减少了网站对数据库的调用,从而减少了瓶颈…但这一切都有点摇摆不定和迂回…基本上,您必须确定DOMDocument的开销是否小于嵌套递归循环和数据库调用的开销,这实际上取决于嵌套的深度。如果您使用的导航系统只有两个级别,那么循环可能还可以-如果它更像旧的skool线程消息板,那么使用DOMDocument可能会降低性能影响。