title: Removing invalid/incomplete multibyte characters
body: <p>I'm having some issues using the following code on user input:</p>
  
  <pre><code>htmlentities($string, ENT_COMPAT, 'UTF-8');
  </code></pre>
  
  <p>When an invalid multibyte character is detected PHP throws a notice:</p>
  
  <blockquote>
    <p>PHP Warning: htmlentities(): Invalid multibyte sequence in argument in /path/to/file.php on line 123</p>
  </blockquote>
  
  <p>My first thought was to supress the error, but this is slow and poor practice:
  <a href="http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html">http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html</a></p>
  
  <p>My second thought was to use the ENT_IGNORE flag, but even the PHP manual suggests not to use this:</p>
  
  <blockquote>
    <p>Silently discard invalid code unit sequences instead of returning an empty string. Using this flag is discouraged as it » <a href="http://unicode.org/reports/tr36/#Deletion_of_Noncharacters">may have security implications</a>.</p>
  </blockquote>
  
  <p>A bit of further reason led me to the following piece of code:</p>
  
  <pre><code>    // detect encoding
  $encoding =  mb_detect_encoding($query);
  if($encoding != 'UTF-8') {
      $query = mb_convert_encoding($query, 'UTF-8', $encoding);
  } else {
      // strip out invalid utf8 sequences
      $query = iconv('UTF-8', 'UTF-8//IGNORE', $query);
  }
  </code></pre>
  
  <p>Unfortunately iconv <em>also</em> throws an E_NOTICE when it removes/ignores invalid characters:</p>
  
  <blockquote>
    <p>If you append the string //TRANSLIT to out_charset transliteration is activated. This means that when a character can't be represented in the target charset, it can be approximated through one or several similarly looking characters. If you append the string //IGNORE, characters that cannot be represented in the target charset are silently discarded. Otherwise, str is cut from the first illegal character and an E_NOTICE is generated.</p>
  </blockquote>
  
  <p>So I'm basically out of options here. I'd rather use a tried and tested library to handle this kind of stuff than attempting it with a few of the regular expression based solutions I've seen floated around.</p>
  
  <p>So that leads me to my final question:
  <strong>How can I remove invalid multibyte characters, efficiently, securely, without notices/warnings/errors?</strong></p>