在表单输入中自动关闭标签?

时间:2015-06-08 15:19:32

标签: php html

我正在创建一个BBcode类型的函数,它从表单输入中取出所有html代码,然后将[b] [/ b]转换为实际的粗体标签,将[u]转换为实际的u标签,并将[i]转换为实际的i标签。

然而,令我担心的是,无论是谁编写并提交输入都不会关闭所有标记。我不希望在以后显示信息时弄乱整个页面。

您如何建议我使用该功能自动关闭所有标签(仅允许b,i和u)?有没有办法计算有多少[b]和多少[/ b],如果有差异,可以添加多少[/ b]到最后?或者有更简单的方法吗?

顺便说一句,我还没有尝试过任何东西,因为我能想到的唯一一件事是计算有多少[b],计算有多少[/ b],得到两者之间的差异并制作一个循环多次添加结束标记。但我不知道如何做第一部分(返回有多少[b])。

如果有人愿意告诉我如何做到这一点(我知道我是个菜鸟),我会正确地尝试它并让你知道它是怎么回事。 :)

3 个答案:

答案 0 :(得分:1)

使用简单的数组。您添加每个允许的开始标记,然后添加每个结束标记的“array_pop”。在处理输入文本结束时,如果数组不为空,则可以关闭等待标记。

请告诉我们您在询问之前尝试找到解决方案,向我们展示您的代码:)

编辑:

好的,这是一个草稿(不是一个优秀的草稿)。 我正在使用FILO(先进先出)存储标签。

第一个“for循环”解析文本以存储未关闭的标记。第二个循环(foreach)在输入文本末尾添加等待标记。

如果发现错误,代码返回false,则应返回有关错误的更多信息:)

$text = "[u]hop[u]text[b]bar[/b][/u][b][i]foo";

echo closeTags($text);

function closeTags($text) {
    $tags = array();
    $currentTag = '';
    $tagOn = false;
    $closingTagOn = false;
    $lastPos = 2;

    $len = strlen($text);
    for ($i=0 ; $i < $len ; $i++) {
        // reading tag ?
        if ($tagOn or (!$tagOn and '[' === $text[$i])) {
            $currentTag .= $text[$i];
            $tagOn = true;
        }

        // closing tag ?
        if (isset($currentTag[1]) and '/' === $currentTag[1]) {
            $closingTagOn = true;
            $lastPos = 3;
        }

        // tag ending ?
        if (isset($currentTag[$lastPos])) {
            if (']' !== $currentTag[$lastPos]) {
                return false; // malformed text
            }
            else {
                if ($closingTagOn) {
                    // quick & dirty
                    if ($tags[count($tags)-1][1] === $currentTag[2]) {
                        array_pop($tags);
                    }
                    else {
                        // malformed, markups should not cross over each other
                        return false;
                    }
                }
                else {
                    // adding the tag
                    $tags[] = $currentTag;
                }

                // re-init
                $currentTag = '';
                $tagOn = false;
                $closingTagOn = false;
                $lastPos = 2;
            }
        }
    }

    $tags = array_reverse($tags);
    foreach($tags as $tag) {
        $text .= '[/' . $tag[1] . ']';
    }
    return $text;
}

答案 1 :(得分:0)

有不同的可能性。

  • 您可以使用不同的库扫描内容,例如“HTMLTidy”,这将删除任何未关闭的标签

  • 此外,您可以计算所有标签,如果它们没有关闭,只需动态地为每个未关闭的标签附加一个关闭标签。 preg_match可以帮到你......

  • 另一个想法是将带有用户编写内容的部分隔离到iframe中,这会导致破坏的HTML不会影响页面外的任何元素。

答案 2 :(得分:0)

好的,我发现PHP有一个漂亮的小整洁&#34;在PHP5 +中安装的类!所以,这是我提出的功能,似乎有效!

function bbcode($data) {

  $patterns = array();
    $patterns[0] = '/</';
    $patterns[1] = '/>/';
  $new = preg_replace($patterns, "", $data);

  $newer = sanitize($new);

    $search  = array('[b]', '[/b]', '[i]', '[/i]', '[u]', '[/u]');
    $replace = array('<b>', '</b>', '<i>', '</i>', '<u>', '</u>');

  $newest = str_replace($search, $replace, $newer );

  $data1 = nl2br($newest);

  $tidy = tidy_parse_string($data1);
    $tidy->cleanRepair();
  return $tidy;
}