PHP目录清单 [英] PHP List Of Contents

查看:49
本文介绍了PHP目录清单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像维基百科一样制作目录清单.我的代码:

<?php 
$str = "[H1]Top Heading[/H1] My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3] string now again [H1]Top Heading[/H1] My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3]";

/**
 * Helper class
 */
class FaqHelper {
    static $count = 1;
    static $listItems = array();
    static $prefix = 'faq-';

    static function GetList() {

        $items = '';
            foreach (self::$listItems as $id => $label) {
                $items .= '<li><a href="#' . self::$prefix . $id .'">' . $label . '</a></li>';
            }

        return '<ul><ol>'. $items .'</ul></ol>';
    }
}

// the callback function
function make_faq($matches)
{
    $id = FaqHelper::$count;
    $label = $matches[1];

    FaqHelper::$listItems[$id] = $label;

  $res = '<span id="'. FaqHelper::$prefix . $id .'">' . $label . '</span>';

    FaqHelper::$count++;

    return $res;
}

$text = preg_replace_callback(
    "#\[H1\]([^\[]+)\[/H1\]#",
    "make_faq",
    $str
);

$list = FaqHelper::GetList();

echo $list;
echo '<br /><br />';
echo $text;


?>

这给了

         1. Top Heading
         2. Top Heading



Top Heading My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3] string now again Top Heading My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3]

但是我想要这个结果

     1. Top Heading
        1.1 My sub Heading 
            1.1.1 My deep Heading 
     2. Top Heading
        2.1 My sub Heading 
            2.1.1 My deep Heading 

等等... 顶部标题我的测试字符串我的子标题我的第二个我的深标题字符串再次出现顶部标题我的测试字符串我的子标题我的第二个我的深标题字符串现在又一次

基本理论是这个.

当您击中第一个[H1]时,会将计数器增加到1.当您击中h2时,您的第二级计数器将增加到1.当您击中h3时,您的第三级计数器将增加到1. /p>

这显然将输出1.1.1.

现在,当您点击下一个h1时,它们的子级别(即不是主要级别)将重置为0,然后第一个级别增加到2.您点击了h2,然后再次变为1.然后您具有第2级,sub 1,sub 1 = 2.1.1.

解决方案

请注意,此代码仅支持3个级别的标题.我知道该解决方案无法无限扩展,并且不支持递归解析,但是很遗憾,我没有时间为SO问题创建完美的解决方案.

基于您的最后一个问题,我的扩展解决方案如下.请对其进行测试,看看它是否按预期工作.请注意,我已经使匹配[H1] [/H1]标签的正则表达式区分大小写,因此[h1] [/h1]现在也可以使用.

同样,如果我很慢或者结果不是很完美,但是我无法完成整个项目,我深表歉意,您需要自己做一些研究,学习然后再做.另外,随着代码的发展和增厚,将需要更多的时间进行进一步的扩展和维护,而我并不总是能够做到这一点.

享受!

<?php

$str = "
[h1]Header 1[/h1]Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae rutrum tellus. Vestibulum nec nisl eu enim venenatis ornare. Suspendisse a nunc nibh, quis placerat urna. Pellentesque nec odio est. [h2]Header 2[/h2]Morbi et orci non nulla lobortis convallis. Curabitur vestibulum, felis auctor posuere posuere, mauris neque vulputate tellus, vel luctus urna sapien vitae sapien. [h2]Header 2-2[/h2] Integer accumsan lobortis euismod. Integer vitae tempor nisl.

[h1]Header 1[/h1]Mauris varius dolor nec risus viverra egestas. Suspendisse potenti. Nunc consectetur faucibus metus, nec sagittis felis pellentesque non. Ut mattis ligula non [h2]Header 2[/h2] purus vehicula sed tempus risus porttitor. Nullam eget arcu[h3]Header 3[/h3] at mi pulvinar pellentesque eu sed ipsum. Fusce vel laoreet sem. Duis hendrerit ligula iaculis felis hendrerit euismod vel ut mauris. Pellentesque tempus velit et velit cursus sodales. Sed adipiscing vulputate nibh sed venenatis. Quisque sit amet ante velit. Donec dui lectus, ultricies quis interdum eget, elementum vitae nibh. Nullam nec sapien purus, laoreet porta elit. Nam luctus elit sit amet est ultricies eget varius diam ullamcorper. Sed commodo viverra lobortis. Vivamus semper blandit arcu semper pellentesque. Duis interdum tincidunt nisl eget mollis.

[h1]Header 1[/h1]Suspendisse laoreet, tortor sed viverra pellentesque, enim felis tempus ante, sit amet dignissim leo augue non ipsum. Ut eu risus erat. Donec pellentesque ligula ac est tincidunt ullamcorper. [h2]My paragraph again[/h2] Pellentesque eget diam lacus, nec ornare urna. Nulla a interdum augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et justo turpis. ";

class FaqHeading
{
    var $heading_level;
    var $id;
    var $label;

    var $children = array();
    var $parent = null;

    function __construct($heading_level, $id, $label)
    {
        $this->heading_level = (int) $heading_level;
        $this->id = (int) $id;
        $this->label = $label;
    }

    function AddChild(FaqHeading $child)
    {
            if ($child->heading_level <= $this->heading_level) {
                return; // cannot add higher or equal leveld headings as children
            }

        $child->parent = $this;
        $this->children[] = $child;
    }

    function HasChildren()
    {
        return (bool) $this->children;
    }
}

class FaqHeadingList
{
    var $headings = array();
    var $current = null;
    var $prefix;

    function __construct($prefix)
    {
        $this->prefix = $prefix;
    }

    function AddHeading($heading_level, $id, $label)
    {
        $elem = new FaqHeading($heading_level, $id, $label);

            if ($this->current == null || $heading_level == 1) {
                $this->headings[] = $elem;
            }   else if ($heading_level == 2 && ($this->current->heading_level == 1)) {
                $this->current->AddChild($elem);
            } else if ($heading_level == 2 && ($this->current->heading_level == 2)) {
                $this->current->parent->AddChild($elem);
            } else if ($heading_level == 2 && ($this->current->heading_level == 3)) {
                $this->current->parent->parent->AddChild($elem);
            } else if ($heading_level == 3 && ($this->current->heading_level == 1)) {
                $this->current->AddChild($elem);
            } else if ($heading_level == 3 && ($this->current->heading_level == 2)) {
                $this->current->AddChild($elem);
            } else if ($heading_level == 3 && ($this->current->heading_level == 3)) {
                $this->current->parent->AddChild($elem);
            }

        $this->current = $elem;
    }

    function ToString()
    {
        $str = '<ol>';
            foreach ($this->headings as $h1)
            {
                    if ($h1->heading_level == 1)
                    {
                        $str .= '<li>'. $this->CreateLink($h1->id, $h1->label);
                            if ($h1->hasChildren())
                            {
                                $str .= '<ol>';
                                    foreach ($h1->children as $h2)
                                    {
                                        $str .= '<li>' . $this->CreateLink($h2->id, $h2->label);

                                            if ($h2->hasChildren())
                                            {
                                                $str .= '<ol>';
                                                    foreach ($h2->children as $h3)
                                                    {
                                                        $str .= '<li>'. $this->CreateLink($h3->id, $h3->label) .'</li>';
                                                    }
                                                $str .= '</ol>';
                                            }
                                        $str .= '</li>';
                                    }
                                $str .= '</ol>';
                            }
                        $str .= '</li>';
                    }
            }
        $str .= '</ol>';

        return $str;
    }

    function CreateLink($id, $label)
    {
        return '<a href="#' . $this->prefix . $id .'">' . $label . '</a>';
    }
}

/**
 * Helper class
 */
class FaqHelper
{
    static $count = 1;
    static $headingList;
    static $prefix = 'faq-';

    static function Init()
    {
        self::$headingList = new FaqHeadingList(self::$prefix);
    }

    static function ReplaceCallback($matches)
    {
        $id = self::$count;
        $heading_level = $matches[1];
        $label = $matches[2];

        self::$headingList->AddHeading($heading_level, $id, $label);

        $res = '<span id="'. self::$prefix . $id .'">' . $label . '</span>';

        self::$count++;

        return $res;
    }
}

FaqHelper::init();

$text = preg_replace_callback(
    "#\[H([0-9]+)\]([^\[]+)\[/H\\1\]#i",
    array('FaqHelper', "ReplaceCallback"),
    $str
);

$list = FaqHelper::$headingList->ToString();

echo $list;
echo '<br /><br />';
echo nl2br($text);
?>

应输出:

  1. Header 1
         1. Header 2
         2. Header 2-2
   2. Header 1
         1. Header 2
               1. Header 3
   3. Header 1
         1. My paragraph again




Header 1Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae rutrum tellus. Vestibulum nec nisl eu enim venenatis ornare. Suspendisse a nunc nibh, quis placerat urna. Pellentesque nec odio est. Header 2Morbi et orci non nulla lobortis convallis. Curabitur vestibulum, felis auctor posuere posuere, mauris neque vulputate tellus, vel luctus urna sapien vitae sapien. Header 2-2 Integer accumsan lobortis euismod. Integer vitae tempor nisl.

Header 1Mauris varius dolor nec risus viverra egestas. Suspendisse potenti. Nunc consectetur faucibus metus, nec sagittis felis pellentesque non. Ut mattis ligula non Header 2 purus vehicula sed tempus risus porttitor. Nullam eget arcuHeader 3 at mi pulvinar pellentesque eu sed ipsum. Fusce vel laoreet sem. Duis hendrerit ligula iaculis felis hendrerit euismod vel ut mauris. Pellentesque tempus velit et velit cursus sodales. Sed adipiscing vulputate nibh sed venenatis. Quisque sit amet ante velit. Donec dui lectus, ultricies quis interdum eget, elementum vitae nibh. Nullam nec sapien purus, laoreet porta elit. Nam luctus elit sit amet est ultricies eget varius diam ullamcorper. Sed commodo viverra lobortis. Vivamus semper blandit arcu semper pellentesque. Duis interdum tincidunt nisl eget mollis.

Header 1Suspendisse laoreet, tortor sed viverra pellentesque, enim felis tempus ante, sit amet dignissim leo augue non ipsum. Ut eu risus erat. Donec pellentesque ligula ac est tincidunt ullamcorper. My paragraph again Pellentesque eget diam lacus, nec ornare urna. Nulla a interdum augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et justo turpis. 

I want to make List of contents just like in wikipedia. My code:

<?php 
$str = "[H1]Top Heading[/H1] My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3] string now again [H1]Top Heading[/H1] My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3]";

/**
 * Helper class
 */
class FaqHelper {
    static $count = 1;
    static $listItems = array();
    static $prefix = 'faq-';

    static function GetList() {

        $items = '';
            foreach (self::$listItems as $id => $label) {
                $items .= '<li><a href="#' . self::$prefix . $id .'">' . $label . '</a></li>';
            }

        return '<ul><ol>'. $items .'</ul></ol>';
    }
}

// the callback function
function make_faq($matches)
{
    $id = FaqHelper::$count;
    $label = $matches[1];

    FaqHelper::$listItems[$id] = $label;

  $res = '<span id="'. FaqHelper::$prefix . $id .'">' . $label . '</span>';

    FaqHelper::$count++;

    return $res;
}

$text = preg_replace_callback(
    "#\[H1\]([^\[]+)\[/H1\]#",
    "make_faq",
    $str
);

$list = FaqHelper::GetList();

echo $list;
echo '<br /><br />';
echo $text;


?>

and this gives

         1. Top Heading
         2. Top Heading



Top Heading My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3] string now again Top Heading My test string [H2]My sub Heading[/H2] My second [H3]My deep Heading[/H3]

but i want this results

     1. Top Heading
        1.1 My sub Heading 
            1.1.1 My deep Heading 
     2. Top Heading
        2.1 My sub Heading 
            2.1.1 My deep Heading 

So on ... Top Heading My test string My sub Heading My second My deep Heading string now again Top Heading My test string My sub Heading My second My deep Heading string now again

The basic theory is this.

When you hit your first [H1], you increment the counter to 1. When you hit the h2, your second level counter is incremented to 1. When you hit the h3, your third level counter is incremented to 1.

This will obviously output 1.1.1.

Now when you hit the next h1, they sub levels (ie not the main level) are reset to 0, and then the first level is incremented to 2. You hit the h2, and it goes to 1 again... Then you have first level 2, sub 1, sub 1 = 2.1.1.

解决方案

Note that this code will only support 3 levels of headings. I'm aware that this solution doesn't scale endlessly and does not support recursive parsing, but unfortunately I don't have time to create the perfect solution for SO questions.

My extended solution based on your last question is below. Please test it and see if it works as expected. Note that I've made the regex that matches the [H1][/H1] tags in case-sensitive so [h1][/h1] also works now.

Again, I apologize if I'm slow or the results are not perfect but I can't be making your entire project, you'll need to do some research yourself, learn it and then do it. Also as the code develops and thickens it will take more time to make further extensions and maintain it, of which I don't always have the capacity to do.

Enjoy!

<?php

$str = "
[h1]Header 1[/h1]Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae rutrum tellus. Vestibulum nec nisl eu enim venenatis ornare. Suspendisse a nunc nibh, quis placerat urna. Pellentesque nec odio est. [h2]Header 2[/h2]Morbi et orci non nulla lobortis convallis. Curabitur vestibulum, felis auctor posuere posuere, mauris neque vulputate tellus, vel luctus urna sapien vitae sapien. [h2]Header 2-2[/h2] Integer accumsan lobortis euismod. Integer vitae tempor nisl.

[h1]Header 1[/h1]Mauris varius dolor nec risus viverra egestas. Suspendisse potenti. Nunc consectetur faucibus metus, nec sagittis felis pellentesque non. Ut mattis ligula non [h2]Header 2[/h2] purus vehicula sed tempus risus porttitor. Nullam eget arcu[h3]Header 3[/h3] at mi pulvinar pellentesque eu sed ipsum. Fusce vel laoreet sem. Duis hendrerit ligula iaculis felis hendrerit euismod vel ut mauris. Pellentesque tempus velit et velit cursus sodales. Sed adipiscing vulputate nibh sed venenatis. Quisque sit amet ante velit. Donec dui lectus, ultricies quis interdum eget, elementum vitae nibh. Nullam nec sapien purus, laoreet porta elit. Nam luctus elit sit amet est ultricies eget varius diam ullamcorper. Sed commodo viverra lobortis. Vivamus semper blandit arcu semper pellentesque. Duis interdum tincidunt nisl eget mollis.

[h1]Header 1[/h1]Suspendisse laoreet, tortor sed viverra pellentesque, enim felis tempus ante, sit amet dignissim leo augue non ipsum. Ut eu risus erat. Donec pellentesque ligula ac est tincidunt ullamcorper. [h2]My paragraph again[/h2] Pellentesque eget diam lacus, nec ornare urna. Nulla a interdum augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et justo turpis. ";

class FaqHeading
{
    var $heading_level;
    var $id;
    var $label;

    var $children = array();
    var $parent = null;

    function __construct($heading_level, $id, $label)
    {
        $this->heading_level = (int) $heading_level;
        $this->id = (int) $id;
        $this->label = $label;
    }

    function AddChild(FaqHeading $child)
    {
            if ($child->heading_level <= $this->heading_level) {
                return; // cannot add higher or equal leveld headings as children
            }

        $child->parent = $this;
        $this->children[] = $child;
    }

    function HasChildren()
    {
        return (bool) $this->children;
    }
}

class FaqHeadingList
{
    var $headings = array();
    var $current = null;
    var $prefix;

    function __construct($prefix)
    {
        $this->prefix = $prefix;
    }

    function AddHeading($heading_level, $id, $label)
    {
        $elem = new FaqHeading($heading_level, $id, $label);

            if ($this->current == null || $heading_level == 1) {
                $this->headings[] = $elem;
            }   else if ($heading_level == 2 && ($this->current->heading_level == 1)) {
                $this->current->AddChild($elem);
            } else if ($heading_level == 2 && ($this->current->heading_level == 2)) {
                $this->current->parent->AddChild($elem);
            } else if ($heading_level == 2 && ($this->current->heading_level == 3)) {
                $this->current->parent->parent->AddChild($elem);
            } else if ($heading_level == 3 && ($this->current->heading_level == 1)) {
                $this->current->AddChild($elem);
            } else if ($heading_level == 3 && ($this->current->heading_level == 2)) {
                $this->current->AddChild($elem);
            } else if ($heading_level == 3 && ($this->current->heading_level == 3)) {
                $this->current->parent->AddChild($elem);
            }

        $this->current = $elem;
    }

    function ToString()
    {
        $str = '<ol>';
            foreach ($this->headings as $h1)
            {
                    if ($h1->heading_level == 1)
                    {
                        $str .= '<li>'. $this->CreateLink($h1->id, $h1->label);
                            if ($h1->hasChildren())
                            {
                                $str .= '<ol>';
                                    foreach ($h1->children as $h2)
                                    {
                                        $str .= '<li>' . $this->CreateLink($h2->id, $h2->label);

                                            if ($h2->hasChildren())
                                            {
                                                $str .= '<ol>';
                                                    foreach ($h2->children as $h3)
                                                    {
                                                        $str .= '<li>'. $this->CreateLink($h3->id, $h3->label) .'</li>';
                                                    }
                                                $str .= '</ol>';
                                            }
                                        $str .= '</li>';
                                    }
                                $str .= '</ol>';
                            }
                        $str .= '</li>';
                    }
            }
        $str .= '</ol>';

        return $str;
    }

    function CreateLink($id, $label)
    {
        return '<a href="#' . $this->prefix . $id .'">' . $label . '</a>';
    }
}

/**
 * Helper class
 */
class FaqHelper
{
    static $count = 1;
    static $headingList;
    static $prefix = 'faq-';

    static function Init()
    {
        self::$headingList = new FaqHeadingList(self::$prefix);
    }

    static function ReplaceCallback($matches)
    {
        $id = self::$count;
        $heading_level = $matches[1];
        $label = $matches[2];

        self::$headingList->AddHeading($heading_level, $id, $label);

        $res = '<span id="'. self::$prefix . $id .'">' . $label . '</span>';

        self::$count++;

        return $res;
    }
}

FaqHelper::init();

$text = preg_replace_callback(
    "#\[H([0-9]+)\]([^\[]+)\[/H\\1\]#i",
    array('FaqHelper', "ReplaceCallback"),
    $str
);

$list = FaqHelper::$headingList->ToString();

echo $list;
echo '<br /><br />';
echo nl2br($text);
?>

Should output:

  1. Header 1
         1. Header 2
         2. Header 2-2
   2. Header 1
         1. Header 2
               1. Header 3
   3. Header 1
         1. My paragraph again




Header 1Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae rutrum tellus. Vestibulum nec nisl eu enim venenatis ornare. Suspendisse a nunc nibh, quis placerat urna. Pellentesque nec odio est. Header 2Morbi et orci non nulla lobortis convallis. Curabitur vestibulum, felis auctor posuere posuere, mauris neque vulputate tellus, vel luctus urna sapien vitae sapien. Header 2-2 Integer accumsan lobortis euismod. Integer vitae tempor nisl.

Header 1Mauris varius dolor nec risus viverra egestas. Suspendisse potenti. Nunc consectetur faucibus metus, nec sagittis felis pellentesque non. Ut mattis ligula non Header 2 purus vehicula sed tempus risus porttitor. Nullam eget arcuHeader 3 at mi pulvinar pellentesque eu sed ipsum. Fusce vel laoreet sem. Duis hendrerit ligula iaculis felis hendrerit euismod vel ut mauris. Pellentesque tempus velit et velit cursus sodales. Sed adipiscing vulputate nibh sed venenatis. Quisque sit amet ante velit. Donec dui lectus, ultricies quis interdum eget, elementum vitae nibh. Nullam nec sapien purus, laoreet porta elit. Nam luctus elit sit amet est ultricies eget varius diam ullamcorper. Sed commodo viverra lobortis. Vivamus semper blandit arcu semper pellentesque. Duis interdum tincidunt nisl eget mollis.

Header 1Suspendisse laoreet, tortor sed viverra pellentesque, enim felis tempus ante, sit amet dignissim leo augue non ipsum. Ut eu risus erat. Donec pellentesque ligula ac est tincidunt ullamcorper. My paragraph again Pellentesque eget diam lacus, nec ornare urna. Nulla a interdum augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et justo turpis. 

这篇关于PHP目录清单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆