自动为添加宽度和高度属性带有 PHP 函数的标签

发布于 2024-09-08 00:19:57 字数 801 浏览 8 评论 0原文

我想要的是一个可以在用户输入上运行的函数,该函数将智能地查找 widthheight 属性并将其添加到任何 HTML blob 中的标记,以避免图像加载时的页面重排问题。

我正在为 PHP 论坛编写发布脚本,其中用户的输入在写入数据库以供以后显示之前会被清理并且通常会变得更好。作为我如何让事情变得更好的一个例子,我有一个脚本,它将 alt 属性插入到图像中,如下所示:

这里有两个图像:

经过发布脚本的清理后,变成

这里有两个图像: 发布的图片 Posted image

(这使得它在严格的 HTML 4 下验证,但也许不符合alt 属性——唉!)

因此,对于我的函数,我有一个模糊的想法,即服务器需要在 HTML 块中找到的每个外部图像上运行 getimagesize(),然后应用属性该函数生成它遇到的每个 标签。我假设这个函数以前已经写过,但我在 Google 或 php.net 文档上没有运气。我是否必须从头开始,或者有人知道我可以使用或适应完成这项工作的(相对)强大的功能吗?

What I want is a function I can run on user input that will intelligently find and add the width and height attributes to any <img> tag in a blob of HTML so as to avoid page-reflowing issues while images load.

I am writing the posting script for a PHP forum, where a user's input is sanitised and generally made nicer before writing it to the database for later display. As an example of what I do to make things nicer, I have a script that inserts alt attributes into images like so:

Here are two images: <img src="http://example.com/image.png"> <img src="http://example.com/image2.png">

which, upon sanitising by the posting script, becomes

Here are two images: <img src="http://example.com/image.png" alt="Posted image"> <img src="http://example.com/image2.png" alt="Posted image">

(This makes it validate under HTML 4 strict, but maybe isn't in the spirit of the alt attribute—alas!)

So, for my function, I have a vague idea that the server will need to run getimagesize() on each external image it finds in the block of HTML, then apply the attributes that function generates to each and every <img> tag it runs into. I assume that this function has been written before, but I have had no luck on Google or php.net docs. Do I have to start from scratch, or is somebody aware of a (relatively) robust function that I can use or adapt to do this job?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深爱不及久伴 2024-09-15 00:19:57

您对 getimagesize() 的看法是正确的。您可以简单地执行以下操作:

$img = 'image2.png';
$info = getimagesize($img);
printf('<img src="%s" %s>', $img, $info[3]);

如果图像托管在远程位置,则您必须下载所有图像(该函数会处理它),因此您可能需要缓存结果以加快速度后续请求。

编辑:刚刚看到您有一个包含各种 元素的字符串。这应该可以解决问题:

<?php
$html = <<<EOF
something <img src="https://www.google.com/images/logos/ssl_logo_lg.gif"> hello <img src="https://mail.google.com/mail/images/2/5/logo1.png">
EOF;

$dom = new DOMDocument();
$dom->loadHTML($html);

foreach ($dom->getElementsByTagName('img') as $img) {
    list($width, $height) = getimagesize($img->getAttribute('src'));
    $img->setAttribute('width', $width);
    $img->setAttribute('height', $height);
}

$xpath = new DOMXpath($dom);
$newDom = new DOMDocument();
foreach ($xpath->query('//body/p')->item(0)->childNodes as $node) {
    $newDom->appendChild($newDom->importNode($node, true));
}

$newHtml = $newDom->saveHTML();
?>

You're right about getimagesize(). You can simply do something like this:

$img = 'image2.png';
$info = getimagesize($img);
printf('<img src="%s" %s>', $img, $info[3]);

If the image is hosted at a remote location, you'll have to download all the images though (the function takes care of it), so you might want to cache the result to speed things up on subsequent requests.

Edit: Just saw that you have a string containing various <img> elements. This should do the trick:

<?php
$html = <<<EOF
something <img src="https://www.google.com/images/logos/ssl_logo_lg.gif"> hello <img src="https://mail.google.com/mail/images/2/5/logo1.png">
EOF;

$dom = new DOMDocument();
$dom->loadHTML($html);

foreach ($dom->getElementsByTagName('img') as $img) {
    list($width, $height) = getimagesize($img->getAttribute('src'));
    $img->setAttribute('width', $width);
    $img->setAttribute('height', $height);
}

$xpath = new DOMXpath($dom);
$newDom = new DOMDocument();
foreach ($xpath->query('//body/p')->item(0)->childNodes as $node) {
    $newDom->appendChild($newDom->importNode($node, true));
}

$newHtml = $newDom->saveHTML();
?>
蓝色星空 2024-09-15 00:19:57

问题是您需要服务器预先完成大量工作。我怀疑离线填充大小数据库(或维护大小缓存)会更有效。

完成此操作后,您可以使用可缓存的 JavaScript 将工作推送到浏览器,该 JavaScript 设置图像大小并在 html 末尾调用内联(这样做的优点是您不需要推送所有 html通过你的PHP代码进行重写)。提示:迭代 document.images[]

HTH

C.

The problem is that you are requiring the server to do an awful lot of work up front. I suspect it would be a lot more efficient to populate a database of sizes offline (or maintain a cache of sizes).

And having done this, you could push the work out to the browser by using a cacheable javascript which sets the image sizes and is called inline at the end of the html (which has the advantage the you don't need to push all the html through you PHP code for rewriting). Hint: iterate through document.images[]

HTH

C.

朦胧时间 2024-09-15 00:19:57

您可以使用 getimagesize() 但明智的做法是存储此信息一次并重复使用它,或者至少积极缓存(因为它不太可能经常更改),否则您的服务器将因负载较高而停止运行

you can use getimagesize() but it would be smart to store this information once and reuse it, or at least cache aggressively (as it's unlikely to change often) or your server will crawl to a halt with higher load

只有一腔孤勇 2024-09-15 00:19:57

我知道答案已被接受。我正在分享我使用缓存的代码。

function addImageAttributes($html) {
    $dom = new DOMDocument;
    libxml_use_internal_errors(true); // Disable libxml errors
    $dom->loadHTML($html);
    libxml_use_internal_errors(false); // Enable libxml errors

    $images = $dom->getElementsByTagName('img');

    foreach ($images as $image) {
        $src = $image->getAttribute('src');

        // Check if the image is an external URL
        if (filter_var($src, FILTER_VALIDATE_URL)) {
            $cacheKey = 'image_' . md5($src);
            $imageSize = apc_fetch($cacheKey); // Use an appropriate caching mechanism (e.g., APC)

            if ($imageSize === false) {
                // If not found in cache, fetch and store the image size
                $imageSize = @getimagesize($src);
                if ($imageSize !== false) {
                    apc_store($cacheKey, $imageSize); // Store in cache for future use
                }
            }

            if ($imageSize !== false) {
                list($width, $height) = $imageSize;
                $image->setAttribute('width', $width);
                $image->setAttribute('height', $height);
            }
        }
    }

    return $dom->saveHTML();
}

// Example usage:
$html = 'Here are two images: <img src="http://example.com/image.png"> <img src="http://example.com/image2.png">';
$processedHtml = addImageAttributes($html);

echo $processedHtml;

此示例使用替代 PHP 缓存 (APC) 来存储和检索图像尺寸。确保在您的服务器上启用并配置 APC。您可以将 APC 替换为其他缓存机制,例如 Redis、Memcached,甚至是简单的基于文件的缓存,具体取决于您的服务器环境和要求。缓存有助于减少重复调用 getimagesize() 的开销并提高函数的性能。

I know the answer is accepted. I am sharing my code that uses cache.

function addImageAttributes($html) {
    $dom = new DOMDocument;
    libxml_use_internal_errors(true); // Disable libxml errors
    $dom->loadHTML($html);
    libxml_use_internal_errors(false); // Enable libxml errors

    $images = $dom->getElementsByTagName('img');

    foreach ($images as $image) {
        $src = $image->getAttribute('src');

        // Check if the image is an external URL
        if (filter_var($src, FILTER_VALIDATE_URL)) {
            $cacheKey = 'image_' . md5($src);
            $imageSize = apc_fetch($cacheKey); // Use an appropriate caching mechanism (e.g., APC)

            if ($imageSize === false) {
                // If not found in cache, fetch and store the image size
                $imageSize = @getimagesize($src);
                if ($imageSize !== false) {
                    apc_store($cacheKey, $imageSize); // Store in cache for future use
                }
            }

            if ($imageSize !== false) {
                list($width, $height) = $imageSize;
                $image->setAttribute('width', $width);
                $image->setAttribute('height', $height);
            }
        }
    }

    return $dom->saveHTML();
}

// Example usage:
$html = 'Here are two images: <img src="http://example.com/image.png"> <img src="http://example.com/image2.png">';
$processedHtml = addImageAttributes($html);

echo $processedHtml;

This example uses the Alternative PHP Cache (APC) to store and retrieve image dimensions. Make sure to enable and configure APC on your server. You can replace APC with other caching mechanisms like Redis, Memcached, or even a simple file-based cache, depending on your server environment and requirements. Caching helps reduce the overhead of repeated getimagesize() calls and improves the performance of your function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文