{"id":1045,"date":"2012-08-03T11:29:48","date_gmt":"2012-08-03T11:29:48","guid":{"rendered":"http:\/\/leonardocotta.com.br\/blog\/?p=1045"},"modified":"2012-08-03T11:29:48","modified_gmt":"2012-08-03T11:29:48","slug":"convertendo-iso-8859-1-para-utf-8-de-forma-segura","status":"publish","type":"post","link":"https:\/\/leonardocotta.com.br\/?p=1045","title":{"rendered":"Convertendo ISO-8859-1 para UTF-8 de forma segura"},"content":{"rendered":"<div style=\"color:#4c4c4c;font-family:'Trebuchet MS', Trebuchet, Verdana, sans-serif;line-height:normal;background-color:#f6f6f6;\">\n<h3 style=\"margin:0;\">Introdu\u00e7\u00e3o<\/h3>\n<p style=\"text-align:justify;\">J\u00e1 falamos v\u00e1rias vezes sobre Unicode, desde a\u00a0<a style=\"color:#de7008;\" href=\"http:\/\/rubsphp.blogspot.com.br\/2010\/10\/unicode.html\">defini\u00e7\u00e3o de unicode<\/a>,\u00a0<a style=\"color:#de7008;\" href=\"http:\/\/rubsphp.blogspot.com.br\/2011\/02\/codigos-e-simbolos-unicode.html\">fun\u00e7\u00f5es para manupular unicode<\/a>,\u00a0<a style=\"color:#de7008;\" href=\"http:\/\/rubsphp.blogspot.com.br\/2011\/07\/problemas-dom-charset-nunca-mais.html\">como utilizar unicode em todas camadas do sistema<\/a>\u00a0e\u00a0<a style=\"color:#de7008;\" href=\"http:\/\/rubsphp.blogspot.com.br\/2011\/02\/html-entities.html\">como representar os s\u00edmbolos na forma de html entities<\/a>.<\/p>\n<p style=\"text-align:justify;\">Sabemos que ISO-8859-1 foi uma codifica\u00e7\u00e3o muito utilizada antes do surgimento do Unicode, mas que a tend\u00eancia \u00e9 que tudo seja migrado para Unicode e, no caso do ISO-8859-1, preferencialmente migrado para UTF-8. Por\u00e9m, aplica\u00e7\u00f5es web est\u00e3o sujeitas a situa\u00e7\u00f5es das mais adversas, quando se trata de dados enviados pelo usu\u00e1rio. Existem casos em que um usu\u00e1rio consegue colar um texto em que parte dele deveria ser ISO-8859-1 e parte dele deveria ser UTF-8. Isso pode ocorrer ao copiar e colar trechos de aplica\u00e7\u00f5es para aplica\u00e7\u00f5es em sistemas de &#8220;origem duvidosa&#8221;, que acabam gerando uma bagun\u00e7a de bytes que, por acaso, acabam sendo enviadas para nossa aplica\u00e7\u00e3o.<\/p>\n<p style=\"text-align:justify;\">Para resolver este problema, elaborei uma fun\u00e7\u00e3o parecida com\u00a0<tt style=\"font-family:Inconsolata, Monaco, Consolas, 'Lucida Console', 'Courier New', monospace;color:#000000;\">utf8_encode<\/tt>, ou seja, converte os caracteres de ISO-8859-1 para UTF-8, por\u00e9m, caso a fun\u00e7\u00e3o identifique um caractere UTF-8 no texto, ela o mantem intacto. Portanto, ela \u00e9 \u00fatil para garantir que o texto final seja 100% UTF-8 v\u00e1lido.<\/p>\n<\/div>\n<p><a style=\"color:#de7008;font-family:'Trebuchet MS', Trebuchet, Verdana, sans-serif;line-height:normal;background-color:#f6f6f6;\" name=\"more\"><\/a><\/p>\n<div style=\"color:#4c4c4c;font-family:'Trebuchet MS', Trebuchet, Verdana, sans-serif;line-height:normal;background-color:#f6f6f6;\">\n<p style=\"text-align:justify;\">Copyright 2012 Rubens Takiguti Ribeiro<\/p>\n<p style=\"text-align:justify;\">Licen\u00e7a:\u00a0<a style=\"color:#de7008;\" href=\"http:\/\/www.gnu.org\/licenses\/lgpl-3.0.txt\">LGPL 3<\/a>\u00a0ou superior<\/p>\n<pre style=\"font-family:Inconsolata, Monaco, Consolas, 'Lucida Console', 'Courier New', monospace;background-color:#eeeeff;border-image:initial;clear:both;color:#404070;width:auto;max-height:400px;overflow-x:auto;overflow-y:auto;box-shadow:#ff0000 2px 2px 10px;-webkit-box-shadow:#ff0000 2px 2px 10px;-webkit-transition-property:background-color, color, -webkit-box-shadow;-webkit-transition-duration:1s, 1s, 1s;-webkit-transition-timing-function:initial, initial, initial;-webkit-transition-delay:initial, initial, initial;border-width:1px;border-color:#000000;border-style:solid;padding:1em;\">\/**\n * Fun\u00e7\u00e3o que converte caracteres ISO-8859-1 para UTF-8, mantendo os caracteres UTF-8 intactos.\n * @param string $texto\n * @return string\n *\/\nfunction sanitizar_utf8($texto) {\n    $saida = '';\n\n    $i = 0;\n    $len = strlen($texto);\n    while ($i &lt; $len) {\n        $char = $texto[$i++];\n        $ord  = ord($char);\n\n        \/\/ Primeiro byte 0xxxxxxx: simbolo ascii possui 1 byte\n        if (($ord &amp; 0x80) == 0x00) {\n\n            \/\/ Se e' um caractere de controle\n            if (($ord &gt;= 0 &amp;&amp; $ord &lt;= 31) || $ord == 127) {\n\n                \/\/ Incluir se for: tab, retorno de carro ou quebra de linha\n                if ($ord == 9 || $ord == 10 || $ord == 13) {\n                    $saida .= $char;\n                }\n\n            \/\/ Simbolo ASCII\n            } else {\n                $saida .= $char;\n            }\n\n        \/\/ Primeiro byte 110xxxxx ou 1110xxxx ou 11110xxx: simbolo possui 2, 3 ou 4 bytes\n        } else {\n\n            \/\/ Determinar quantidade de bytes analisando os bits da esquerda para direita\n            $bytes = 0;\n            for ($b = 7; $b &gt;= 0; $b--) {\n                $bit = $ord &amp; (1 &lt;&lt; $b);\n                if ($bit) {\n                    $bytes += 1;\n                } else {\n                    break;\n                }\n            }\n\n            switch ($bytes) {\n            case 2: \/\/ 110xxxxx 10xxxxxx\n            case 3: \/\/ 1110xxxx 10xxxxxx 10xxxxxx\n            case 4: \/\/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n                $valido = true;\n                $saida_padrao = $char;\n                $i_inicial = $i;\n                for ($b = 1; $b &lt; $bytes; $b++) {\n                    if (!isset($texto[$i])) {\n                        $valido = false;\n                        break;\n                    }\n                    $char_extra = $texto[$i++];\n                    $ord_extra  = ord($char_extra);\n\n                    if (($ord_extra &amp; 0xC0) == 0x80) {\n                        $saida_padrao .= $char_extra;\n                    } else {\n                        $valido = false;\n                        break;\n                    }\n                }\n                if ($valido) {\n                    $saida .= $saida_padrao;\n                } else {\n                    $saida .= ($ord &lt; 0x7F || $ord &gt; 0x9F) ? utf8_encode($char) : '';\n                    $i = $i_inicial;\n                }\n                break;\n            case 1:  \/\/ 10xxxxxx: ISO-8859-1\n            default: \/\/ 11111xxx: ISO-8859-1\n                $saida .= ($ord &lt; 0x7F || $ord &gt; 0x9F) ? utf8_encode($char) : '';\n                break;\n            }\n        }\n    }\n    return $saida;\n}<\/pre>\n<\/div>\n<p>Fonte,\u00a0<a href=\"http:\/\/feedproxy.google.com\/~r\/PhpWebECoisasAssim\/~3\/e57FA4QXDTY\/convertendo-iso88591-para-utf8-de-forma-segura.html\">Convertendo ISO-8859-1 para UTF-8 de forma segura<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introdu\u00e7\u00e3o J\u00e1 falamos v\u00e1rias vezes sobre Unicode, desde a\u00a0defini\u00e7\u00e3o de unicode,\u00a0fun\u00e7\u00f5es para manupular unicode,\u00a0como utilizar unicode em todas camadas do sistema\u00a0e\u00a0como representar os s\u00edmbolos na forma de html entities. Sabemos que ISO-8859-1 foi uma codifica\u00e7\u00e3o muito utilizada antes do surgimento do Unicode, mas que a tend\u00eancia \u00e9 que tudo seja migrado para Unicode e, no &hellip; <a href=\"https:\/\/leonardocotta.com.br\/?p=1045\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Convertendo ISO-8859-1 para UTF-8 de forma segura<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[42],"tags":[89,102,150,267],"class_list":["post-1045","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-como-utilizar-unicode-em-todas-camadas-do-sistema-e-como-representar-os-simbolos-na-forma-de-html-entities","tag-definicao-de-unicode","tag-iso-8859-1","tag-utf8_encode"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/posts\/1045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1045"}],"version-history":[{"count":0,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=\/wp\/v2\/posts\/1045\/revisions"}],"wp:attachment":[{"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/leonardocotta.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}