phphtmlhtml-sanitizinggetimagesize

Automatically adding width and height attributes to <img> tags with a PHP function


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?


Solution

  • 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();
    ?>