【PHP】富文本编辑器图片自动追加域名

1.安装phpQuery库来处理HTML内容
php 复制代码
// 可能适用的PHP版本较低,php7.4及以下。
composer require electrolinux/phpquery:"0.9.6"

代码解析示例:

php 复制代码
if (!function_exists('replace_content_file_url')) {
    function replace_content_file_url($content){
        \phpQuery::newDocumentHTML($content);
        $pq = pq(null);
        $images = $pq->find("img");
        if ($images->length) {
            foreach ($images as $img) {
                $img    = pq($img);
                $imgSrc = $img->attr("src");
 
                $img->attr("src", cdnurl($imgSrc, true));
 
            }
        }
 
        $links = $pq->find("a");
        if ($links->length) {
            foreach ($links as $link) {
                $link = pq($link);
                $href = $link->attr("href");
 
                if (!(preg_match("/^\//", $href) || preg_match("/^http/", $href))) {
                    $link->attr("href", cdnurl($href, true));
                }
 
            }
        }
 
        $content = $pq->htmlOuter();
 
        \phpQuery::$documents = null;
 
        return $content;
    }
}
2.使用兼容性更高的 phpQuery 版本
php 复制代码
composer require sebastian/phpquery
php 复制代码
if (!function_exists('replace_content_file_url')) {
    function replace_content_file_url($content)
    {
        // 使用 DOMDocument 替代 phpQuery
        $dom = new DOMDocument();
        
        // 处理 HTML 编码问题
        $internalErrors = libxml_use_internal_errors(true);
        
        // 添加 HTML5 文档类型和 meta 标签处理中文
        $content = '<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>' . $content . '</body></html>';
        
        $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        libxml_use_internal_errors($internalErrors);
        
        // 处理图片
        $images = $dom->getElementsByTagName('img');
        foreach ($images as $img) {
            $imgSrc = $img->getAttribute('src');
            if ($imgSrc) {
                $img->setAttribute('src', cdnurl($imgSrc, true));
            }
        }
        
        // 处理链接
        $links = $dom->getElementsByTagName('a');
        foreach ($links as $link) {
            $href = $link->getAttribute('href');
            if ($href && !preg_match("/^\//", $href) && !preg_match("/^http/", $href)) {
                $link->setAttribute('href', cdnurl($href, true));
            }
        }
        
        // 提取 body 内容
        $body = $dom->getElementsByTagName('body')->item(0);
        $result = '';
        foreach ($body->childNodes as $child) {
            $result .= $dom->saveHTML($child);
        }
        
        return $result;
    }
}
3.使用简单的字符串处理(更轻量)
php 复制代码
if (!function_exists('replace_content_file_url')) {
    function replace_content_file_url($content)
    {
        // 使用正则表达式替换 img 标签的 src
        $content = preg_replace_callback(
            '/<img[^>]+src="([^"]+)"[^>]*>/i',
            function ($matches) {
                $src = $matches[1];
                $newSrc = cdnurl($src, true);
                return str_replace($src, $newSrc, $matches[0]);
            },
            $content
        );
        
        // 使用正则表达式替换 a 标签的 href
        $content = preg_replace_callback(
            '/<a[^>]+href="([^"]+)"[^>]*>/i',
            function ($matches) {
                $href = $matches[1];
                // 如果不是以 / 或 http 开头
                if (!preg_match("/^\//", $href) && !preg_match("/^http/", $href)) {
                    $newHref = cdnurl($href, true);
                    return str_replace($href, $newHref, $matches[0]);
                }
                return $matches[0];
            },
            $content
        );
        
        return $content;
    }
}
4.使用其他 HTML 解析库
php 复制代码
composer require masterminds/html5 voku/simple_html_dom
php 复制代码
if (!function_exists('replace_content_file_url')) {
    function replace_content_file_url($content)
    {
        // 使用 simple_html_dom
        $html = new \voku\helper\SimpleHtmlDom();
        $html->loadHtml($content);
        
        // 处理图片
        foreach ($html->find('img') as $img) {
            $imgSrc = $img->getAttribute('src');
            if ($imgSrc) {
                $img->setAttribute('src', cdnurl($imgSrc, true));
            }
        }
        
        // 处理链接
        foreach ($html->find('a') as $link) {
            $href = $link->getAttribute('href');
            if ($href && !preg_match("/^\//", $href) && !preg_match("/^http/", $href)) {
                $link->setAttribute('href', cdnurl($href, true));
            }
        }
        
        return $html->html();
    }
}

推荐使用方案2,因为它:

  1. 使用 PHP 原生 DOMDocument,无需额外依赖

  2. 兼容性好,支持所有 PHP 版本

  3. 性能稳定

  4. 不会出现大括号语法问题

如果内容简单,也可以考虑方案3,正则表达式更轻量。

相关推荐
是娇娇公主~2 小时前
C++ 中 std::deque 的原理?它内部是如何实现的?
开发语言·c++·stl
SuperEugene3 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
xuxie994 小时前
N11 ARM-irq
java·开发语言
wefly20174 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
luanma1509805 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默5 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
kyriewen115 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
娇娇yyyyyy6 小时前
QT编程(18): Qt QItemSelectionModel介绍
开发语言·qt
豆豆的java之旅6 小时前
软考中级软件设计师 数据结构详细知识点(含真题+练习题,可直接复习)
java·开发语言·数据结构
sthnyph6 小时前
QT开发:事件循环与处理机制的概念和流程概括性总结
开发语言·qt