3

我正在尝试实现一个简单的函数,该函数给定文本输入,返回在xhp_a检测到链接时修改的文本,在一个段落xhp_p中。

考虑这个类

class Urlifier {

    protected static $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";


    public static function convertParagraphWithLink(?string $input):xhp_p{
        if (!$input)
            return <p></p>;
        else
        {
            if (preg_match(self::$reg_exUrl,$input,$url_match)) //match found
            {
                return <p>{preg_replace($reg_exUrl, '<a href="'.$url_match[0].'>'.$url_match[0].'</a>', $input)}<p>;
            }else{//no link inside
                <p>{$input}</p>
            }
        }
}

这里的问题是xhp转义html和链接未按预期显示。我想这是因为 a 没有按预期创建 dom 层次结构(appendChild例如使用方法),因此所有regex替换都是一个字符串。

所以我解决这个问题的另一种方法是使用preg_match_callback一个回调函数,该函数将创建xhp_a并添加到下面的层次结构中,xhp_p但这也不起作用。

我在某个地方错了吗?如果不存在任何安全风险/更大的开销,只需在客户端而不是服务器上查找和替换加载 html 吗?

谢谢你的时间 !

4

1 回答 1

0

由于 XHP 维护映射到 DOM 的对象层次结构,因此仅替换部分字符串不会创建任何新对象。要操作 XHP 对象,应使用相应的方法,例如appendChild.

这是一个示例,说明如何使用 XHP 操作来实现您的需求。

class Urlifier {

  public static function convertParagraphWithLink(
    ?string $input,
  ): xhp_p {
    $url_pattern = re"/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
    if (HH\Lib\Str\is_empty($input)) {
      return <p/>;
    }
    $input = $input as nonnull;
    // Extract links
    $link_matches = HH\Lib\Regex\every_match($input, $url_pattern);
    $links = HH\Lib\Vec\map($link_matches, $m ==> $m[0]);
    $a_elements = HH\Lib\Vec\map($links, $link ==> <a href={$link}>{$link}</a>);
    // Extract all pieces between matches
    $texts = HH\Lib\Regex\split($input, $url_pattern);
    $p_elements = HH\Lib\Vec\map($texts, $text ==> <p>{$text}</p>);
    
    // Merge texts and links
    $pairs = HH\Lib\Vec\zip($p_elements, $a_elements);
    $elements = HH\Lib\Vec\flatten($pairs);
    
    // Because there's one more p element than a element, append last p
    $elements[] = HH\Lib\C\last($p_elements);

    $result = <p/>;
    $result->appendChild($elements);
    
    return $result;
  }
于 2022-01-06T12:20:04.823 回答