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,因为它:
-
使用 PHP 原生 DOMDocument,无需额外依赖
-
兼容性好,支持所有 PHP 版本
-
性能稳定
-
不会出现大括号语法问题
如果内容简单,也可以考虑方案3,正则表达式更轻量。