rosell-dk/dom-util-for-webp

替换HTML中找到的图片URL

0.7.1 2023-10-20 12:10 UTC

This package is auto-updated.

Last update: 2024-09-06 18:34:42 UTC


README

Latest Stable Version Minimum PHP Version Build Status Coverage Software License Dependents

替换HTML中找到的图片URL

这个库可以完成两件事

  1. 替换HTML中的图片URL
  2. <img>标签替换为<picture>标签,向源中添加webp版本

使用composer设置,运行 composer require rosell-dk/dom-util-for-webp

1. 替换HTML中的图片URL

ImageUrlReplacer::replace($html)方法接受一段HTML,并返回所有图片URL都已替换的HTML - 包括内联样式中的URL。

用法

$modifiedHtml = ImageUrlReplacer::replace($html);

示例替换

输入

<img src="image.jpg">
<img src="1.jpg" srcset="2.jpg 1000w">
<picture>
    <source srcset="1.jpg" type="image/webp">
    <source srcset="2.png" type="image/webp">
    <source src="3.gif"> <!-- gifs are skipped in default behaviour -->
    <source src="4.jpg?width=200"> <!-- urls with query string are skipped in default behaviour -->
</picture>
<div style="background-image: url('image.jpeg')"></div>
<style>
#hero {
    background: lightblue url("image.png") no-repeat fixed center;;
}
</style>
<input type="button" src="1.jpg">
<img data-src="image.jpg"> <!-- any attribute starting with "data-" are replaced (if it ends with "jpg", "jpeg" or "png"). For lazy-loading -->

输出

<img src="image.jpg.webp">
<img src="1.jpg.webp" srcset="2.jpg.webp 1000w">
<picture>
    <source srcset="1.jpg.webp" type="image/webp">
    <source srcset="2.jpg.webp" type="image/webp">
    <source srcset="3.gif"> <!-- gifs are skipped in default behaviour -->
    <source srcset="4.jpg?width=200"> <!-- urls with query string are skipped in default behaviour -->
</picture>
<div style="background-image: url('image.jpeg.webp')"></div>
<style>
#hero {
    background: lightblue url("image.png.webp") no-repeat fixed center;;
}
</style>
<input type="button" src="1.jpg.webp">
<img data-src="image.jpg.webp"> <!-- any attribute starting with "data-" are replaced (if it ends with "jpg", "jpeg" or "png"). For lazy-loading -->

ImageUrlReplacer::replace的默认行为

  • 修改后的URL与原始URL相同,并在其后附加".webp"(要更改,请覆盖replaceUrl函数)
  • 仅替换以"png"、"jpg"或"jpeg"结尾的URL(也没有查询字符串)(要更改,请覆盖replaceUrl函数)
  • 搜索/替换属性限制到以下标签:<img><source><input><iframe>(要更改,请覆盖$searchInTags属性)
  • 搜索/替换属性限制到以下属性:"src"、"src-set"以及以"data-"开头的任何属性(要更改,请覆盖attributeFilter函数)
  • 样式内部的URL也会被替换(background-imagebackground属性)

可以通过扩展ImageUrlReplacer并覆盖公共方法(如replaceUrl)来修改行为

ImageUrlReplacer使用Sunra\PhpSimple\HtmlDomParser来解析和修改HTML。它封装了simplehtmldom。Simplehtmldom支持无效HTML(它不会触摸无效的部分)

示例:自定义行为

class ImageUrlReplacerCustomReplacer extends ImageUrlReplacer
{
    public function replaceUrl($url) {
        // Only accept urls ending with "png", "jpg", "jpeg"  and "gif"
        if (!preg_match('#(png|jpe?g|gif)$#', $url)) {
            return;
        }

        // Only accept full urls (beginning with http:// or https://)
        if (!preg_match('#^https?://#', $url)) {
            return;
        }

        // PS: You probably want to filter out external images too...

        // Simply append ".webp" after current extension.
        // This strategy ensures that "logo.jpg" and "logo.gif" gets counterparts with unique names
        return $url . '.webp';
    }

    public function attributeFilter($attrName) {
        // Don't allow any "data-" attribute, but limit to attributes that smells like they are used for images
        // The following rule matches all attributes used for lazy loading images that we know of
        return preg_match('#^(src|srcset|(data-[^=]*(lazy|small|slide|img|large|src|thumb|source|set|bg-url)[^=]*))$#i', $attrName);

        // If you want to limit it further, only allowing attributes known to be used for lazy load,
        // use the following regex instead:
        //return preg_match('#^(src|srcset|data-(src|srcset|cvpsrc|cvpset|thumb|bg-url|large_image|lazyload|source-url|srcsmall|srclarge|srcfull|slide-img|lazy-original))$#i', $attrName);
    }
}

$modifiedHtml = ImageUrlReplacerCustomReplacer::replace($html);

2. 将<img>标签替换为<picture>标签

PictureTags::replace($html)方法接受一段HTML,并返回所有<img>标签都已替换为<picture>标签,并在源中添加webp版本

用法

$modifiedHtml = PictureTags::replace($html);

示例替换

输入

<img src="1.png">
<img srcset="3.jpg 1000w" src="3.jpg">
<img data-lazy-src="9.jpg" style="border:2px solid red" class="something">
<figure class="wp-block-image">
    <img src="12.jpg" alt="" class="wp-image-6" srcset="12.jpg 492w, 12-300x265.jpg 300w" sizes="(max-width: 492px) 100vw, 492px">
</figure>

输出:

<picture><source srcset="1.png.webp" type="image/webp"><img src="1.png" class="webpexpress-processed"></picture>
<picture><source srcset="3.jpg.webp 1000w" type="image/webp"><img srcset="3.jpg 1000w" src="3.jpg" class="webpexpress-processed"></picture>
<picture><source data-lazy-src="9.jpg.webp" type="image/webp"><img data-lazy-src="9.jpg" style="border:2px solid red" class="something webpexpress-processed"></picture>
<figure class="wp-block-image">
  <picture><source srcset="12.jpg.webp 492w, 12-300x265.jpg.webp 300w" sizes="(max-width: 492px) 100vw, 492px" type="image/webp"><img src="12.jpg" alt="" class="wp-image-6 webpexpress-processed" srcset="12.jpg 492w, 12-300x265.jpg 300w" sizes="(max-width: 492px) 100vw, 492px"></picture>
</figure>'

请注意,使用picture标签时,仍然是img标签显示选定的图片。picture标签只是一个包装器。因此,不将stylewidthclass或其他任何属性复制到picture标签是正确的行为。请参阅问题#9

ImageUrlReplacer一样,您可以覆盖replaceUrl函数。但是,目前没有其他方法可以覆盖。

PictureTags目前使用正则表达式来执行替换。计划将其实现更改为使用Sunra\PhpSimple\HtmlDomParser,就像我们的ImageUrlReplacer类一样。

平台

在以下平台上运行(至少)

  • 操作系统:Ubuntu(22.04、20.04、18.04)、Windows(2022、2019)、Mac OS(13、12、11、10.15)
  • PHP:5.6 - 8.2(2023年10月还测试了8.3和8.4的开发版本)

每个新版本将在所有由GitHub托管的运行器支持的操作系统和PHP版本的组合上进行测试,除了我们不支持低于PHP 5.6的情况。
状态: 构建状态

测试包括运行单元测试。这个库中的代码几乎完全由测试覆盖(约95%覆盖率)。

我们还每月测试PHP的未来版本,以便及早发现问题。
状态: PHP 8.3 PHP 8.4

你喜欢我所做的事情吗?

或许你想支持我的工作,这样我就可以继续做下去啦 :)