V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
IDCFAN
V2EX  ›  PHP

求问有没有自动闭合 HTML 标签的轮子

  •  
  •   IDCFAN · 2020-02-07 21:11:23 +08:00 · 4602 次点击
    这是一个创建于 1510 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用户在 textarea 里输入 HTML,可能存在输入不完整的情况,比如:

    <a href=www>我很大

    上面少了</a>,这样前台显示的时候会造成页面错乱。

    求问有没有可以在入库的时候自动补上</a>的 PHP 函数。

    帮忙的大佬先祝您佛光保佑,退散恶灵,全家安康。谢谢。
    第 1 条附言  ·  2020-02-07 22:23:41 +08:00
    找到了个轮子,试了一下大概是行。。。。
    12 条回复    2020-02-08 11:52:02 +08:00
    jugelizi
        1
    jugelizi  
       2020-02-07 21:18:11 +08:00   ❤️ 1
    有个东西叫富文本编辑器 自定义配置
    IDCFAN
        2
    IDCFAN  
    OP
       2020-02-07 21:27:58 +08:00
    @jugelizi 谢谢。但是我这情况是不超过 100 字符的一小段文本,富文本有点大材小用。
    Sunyanzi
        3
    Sunyanzi  
       2020-02-07 22:03:17 +08:00   ❤️ 2
    php 专门有个扩展做这个 ... php.net/tidy.repairstring 供参考 ...
    imn1
        4
    imn1  
       2020-02-07 22:05:39 +08:00   ❤️ 1
    这个比较难

    例一
    <a href=www>我很大
    ……
    上面少了</a>

    这几行算不算已经闭合?如果不计算最后一行,那么</a>加在省略号前还是后才算正确?

    例二
    <div>
    <div></div>
    <div></div>

    那么</div>加在哪一行?
    IDCFAN
        5
    IDCFAN  
    OP
       2020-02-07 22:22:32 +08:00
    @Sunyanzi 谢谢大佬。

    @imn1 我找到了个轮子试了一下。第一种情况不处理,直接入库。第二种情况处理成下面这样。

    <div>
    <div></div>
    <div></div></div>

    感觉上还行。
    greed1is9good
        6
    greed1is9good  
       2020-02-07 22:31:26 +08:00 via Android   ❤️ 1
    一般只能做总体的数量检验吧,像好多语言的括号一样数量不成对就报错,无法编译,其实少了“<>”这两个个符号的任一个也很麻烦。。。
    no1xsyzy
        7
    no1xsyzy  
       2020-02-07 23:10:57 +08:00   ❤️ 2
    一种是构造出树再重新组合,还有一种邪道是显示时每个丢进 iframe。
    但还是不建议允许用户使用 html (就怕自己某天偷懒 /后续维护者不懂,导致用户输入不过滤直接插 <script> 进网页里形成 XSS ),BBcode 或者 Markdown 都是不错的选择。


    另外,不成对的尖括号如何处理?
    〔由上式可知,b<a 〕
    内容根本不是标签如何处理?
    〔看这个:<https://www.v2ex.com/t/642852>〕
    关于其是否是标签具有歧义的如何处理?
    〔<ruby>明日<rp>(</rp><rt>Tomorrow</rt><rp>)</rp></ruby>〕
    〔参考这本书:<ruby on rails tutorial>〕
    hundan
        8
    hundan  
       2020-02-08 01:40:30 +08:00   ❤️ 2
    拜托你找到解决办法之后分享出来
    loading
        9
    loading  
       2020-02-08 09:37:57 +08:00   ❤️ 3
    既然找到个轮子就应该贴出来,以后别人遇到和你一样问题的时候,可以帮到他。
    不然以后就没人会回答你的问题了。

    请参阅《提问的智慧》
    mostkia
        10
    mostkia  
       2020-02-08 10:20:04 +08:00   ❤️ 1
    试试 Ace Editor 编辑器吧,这玩意儿可以方便的集成到自己的项目中,功能很强大,你拿它甚至能在 web 页面里写出 IDE 来。
    7gugu
        11
    7gugu  
       2020-02-08 10:52:22 +08:00 via Android   ❤️ 1
    你写成树之后,匹配一下吧
    IDCFAN
        12
    IDCFAN  
    OP
       2020-02-08 11:52:02 +08:00   ❤️ 1
    @hundan
    @loading
    其实我昨天就把这代码贴在回帖框里准备发一下,但是自己看不懂,只是自己感觉将就能用,也不知道这函数成熟不成熟,所以最终没发。既然大家说了,我就发一下,从 gayhub 扒下来的,大佬们顺便帮看看吧。其实感觉 3 楼 @Sunyanzi 用 PHP 扩展的方式更好,只是我比较菜,大概率不会弄。


    function CloseTags($html)
    {
    $html = preg_replace('/<[^>]*$/', '', $html);
    preg_match_all('#<([a-z1-6]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
    $opentags = $result[1];
    preg_match_all('#</([a-z1-6]+)>#iU', $html, $result);
    $closetags = $result[1];
    $len_opened = count($opentags);
    if (count($closetags) == $len_opened) {
    return $html;
    }
    $opentags = array_reverse($opentags);
    $sc = array('br', 'input', 'img', 'hr', 'meta', 'link');
    for ($i = 0; $i < $len_opened; $i++) {
    $ot = strtolower($opentags[$i]);
    if (!in_array($opentags[$i], $closetags) && !in_array($ot, $sc)) {
    $html .= '</' . $opentags[$i] . '>';
    } else {
    unset($closetags[array_search($opentags[$i], $closetags)]);
    }
    }
    return $html;
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3845 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 10:32 · PVG 18:32 · LAX 03:32 · JFK 06:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.