DOMDocument and UTF-8 Problem

By  on  

A few weeks back I shared how I used PHP DOMDocument to reliably update all image URLs from standard HTTP to HTTPS.  DOMDocument made a difficult problem seem incredibly easy ... but with one side-effect that it took me a while to spot:  UTF-8 characters were being mutated into another set of characters.  I was seeing a bunch of odd characters like "ãç³" and"»ã®é" all over each blog post.

I knew the problem was happening during the DOMDocument parsing and that I need to find a fix quickly.  The solution was just a tiny bit of code:

// Create a DOMDocument instance 
$doc = new DOMDocument();

// The fix: mb_convert_encoding conversion
$doc->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));

After setting the character set with mb_convert_encoding, the odd characters vanished and the desired characters were back in place.  Phew!

Recent Features

  • By
    Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

Incredible Demos

Discussion

  1. Markus

    instead of converting the input string from your encoding into UTF8 you can also tell the DOMDocument with the 2nd arg in which encoding your string is.

    http://php.net/manual/en/domdocument.construct.php

    This should save you some cpu-cycles and reduce memory consumption.

  2. Whelping

    Actually I was already doing

    $html = new DOMDocument( null, 'UTF-8' );

    and still getting weird characters like  – adding your fix did the trick for me, thanks David!

    • Whelping

      It turns out that specifying the encoding argument when you instantiate a DOMDocument doesn’t encode the contents, just sets the document’s header – see this comment http://php.net/manual/en/domdocument.construct.php#78027. It probably wasn’t necessary to specify UTF-8 anyway, as that’s the default. So something like David’s fix is needed to change any unwanted encodings in the content.

  3. Raja Amer Khan

    Thanks for the tutorial. It really saved time.

  4. Dario

    Thank you very much you life saver

  5. Sam

    Thank you very for this :D
    Caught this bug too, even after instantiating it properly

  6. Rafael

    Awesome, character encoding has always been a pain the a.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!