Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg

PHP : Function Reference : iconv Functions : iconv


Convert string to requested character encoding (PHP 4 >= 4.0.5, PHP 5)
string iconv ( string in_charset, string out_charset, string str )

Example 966. iconv() example

echo iconv("ISO-8859-1", "UTF-8", "This is a test.");

Code Examples / Notes » iconv


To strip bogus characters from your input (such as data from an unsanitized or other source which you can't trust to necessarily give you strings encoded according to their advertised encoding set), use the same character set as both the input and the output, with //IGNORE on the output charcter set.
// assuming '†' is actually UTF8, htmlentities will assume it's iso-8859  
// since we did not specify in the 3rd argument of htmlentities.
// This generates "&acirc;[bad utf-8 character]"
// If passed to any libxml, it will generate a fatal error.
$badUTF8 = htmlentities('†');
// iconv() can ignore characters which cannot be encoded in the target character set
$goodUTF8 = iconv("utf-8", "utf-8//IGNORE", $badUTF8);
The result of the example does not give you back the dagger character which was the original input (it got lost when htmlentities was misused to encode it incorrectly, though this is common from people not accustomed to dealing with extended character sets), but it does at least give you data which is sane in your target character set.


The following are Microsoft encodings that are based on ISO-8859 but with the addition of those stupid control characters.
CP1250 is Eastern European (not ISO-8859-2)
CP1251 is Cyrillic (not ISO-8859-5)
CP1252 is Western European (not ISO-8859-1)
CP1253 is Greek (not ISO-8859-7)
CP1254 is Turkish (not ISO-8859-9)
CP1255 is Hebrew (not ISO-8859-8)
CP1256 is Arabic (not ISO-8859-6)
CP1257 is Baltic (not ISO-8859-4)
If you know you're getting input from a Windows machine with those encodings, use one of these as a parameter to iconv.

dead dot screamer

Ritchie's example
setlocale(LC_CTYPE, 'cs_CZ');
echo iconv('UTF-8', 'ASCII//TRANSLIT', "Žluťoučký kůň\n");
dasn't output `Zlutoucky kun`, but `Zlutouck'y kun`


Please note that iconv('UTF-8', 'ASCII//TRANSLIT', ...) doesn't work properly when locale category LC_CTYPE is set to C or POSIX. You must choose another locale otherwise all non-ASCII characters will be replaced with question marks. This is at least true with glibc 2.5.
setlocale(LC_CTYPE, 'POSIX');
echo iconv('UTF-8', 'ASCII//TRANSLIT', "Žluťoučký kůň\n");
// ?lu?ou?k? k??
setlocale(LC_CTYPE, 'cs_CZ');
echo iconv('UTF-8', 'ASCII//TRANSLIT', "Žluťoučký kůň\n");
// Zlutoucky kun


On some systems there may be no such function as iconv(); this is due to the following reason: a constant is defined named `iconv` with the value `libiconv`. So, the string PHP_FUNCTION(iconv) transforms to PHP_FUNCTION(libiconv), and you have to call libiconv() function instead of iconv().
I had seen this on FreeBSD, but I am sure that was a rather special build.
If you'd want not to be dependent on this behaviour, add the following to your script:
if (!function_exists('iconv') && function_exists('libiconv')) {
   function iconv($input_encoding, $output_encoding, $string) {
       return libiconv($input_encoding, $output_encoding, $string);
Thanks to tony2001 at for explaining this behaviour.


Maybe I was a fool in placing the charset definition string as ISO8859-1 instead of ISO-8859-1 (note the - after ISO) but it worked in PHP 4.3. When I ported the system back to 4.2.2 iconv gave back an empty string without error messages. So beware in PHP 4.2.2 use allways the ISO-88....  charset definition.

georgios papadakis

Many mail servers don't handle utf-8 correctly as they assume iso-8859-x encodings, so you would want to convert the headers, subject and body of an email prior to sending it out.
If iconv() and mb_convert_encoding() are missing the following function can be used to convert UTF8 to iso-8859-7 encoding. It discards all characters that are not 2-byte greek characters or single-byte (ascii).
function conv_utf8_iso8859_7($s) {
   $len = strlen($s);
   $out = "";
   $curr_char = "";
   for($i=0; $i < $len; $i++) {
    $curr_char .= $s[$i];
    if( ( ord($s[$i]) & (128+64) ) == 128) {
    //character end found
    if ( strlen($curr_char) == 2) {
    // 2-byte character check for it is greek one and convert
    if      (ord($curr_char[0])==205) $out .= chr( ord($curr_char[1])+16 );
    else if (ord($curr_char[0])==206) $out .= chr( ord($curr_char[1])+48 );
    else if (ord($curr_char[0])==207) $out .= chr( ord($curr_char[1])+112 );
    else ; // non greek 2-byte character, discard character
    } else ;// n-byte character, n>2, discard character
    $curr_char = "";
    } else if (ord($s[$i]) < 128) {
    // character is one byte (ascii)
    $out .= $curr_char;
    $curr_char = "";
   return $out;

gree:.. gree 4t grees d0t net

In my case, I had to change:
setlocale(LC_CTYPE, 'cs_CZ');
setlocale(LC_CTYPE, 'cs_CZ.UTF-8');
Otherwise it returns question marks.
When I asked my linux for locale (by locale command) it returns "cs_CZ.UTF-8", so there is maybe correlation between it.
iconv (GNU libc) 2.6.1
glibc 2.3.6


If you get this error message: "Notice: iconv(): Detected an illegal character in input string in file.php on line x", and your text or database is likely to contain text copied from Microsoft Word documents, it's very likely that the error is because of the evil 0x96 "long dash" character. MS Word as default converts all double hyphens into this illegal character. The solution is either to convert 0x96 (dash) into the regular 0x2d (hyphen/minus), or to append the //TRANSLIT or //IGNORE parameters (se above).


Here is how to convert UTF-8 numbers to UCS-2 numbers in hex:

function utf8toucs2($str)
      for ($i=0;$i<strlen($str);$i+=2)
               $substring1 = $str[$i].$str[$i+1];  
               $substring2 = $str[$i+2].$str[$i+3];
               if (hexdec($substring1) < 127)
                       $results = "00".$str[$i].$str[$i+1];
                       $results = dechex((hexdec($substring1)-192)*64 + (hexdec($substring2)-128));
                       if ($results < 1000) $results = "0".$results;
               $ucs2 .= $results;
       return $ucs2;

echo strtoupper(utf8toucs2("D985D8B1D8AD"))."\n";
echo strtoupper(utf8toucs2("456725"))."\n";



Here is an example how to convert windows-1251 (windows) or cp1251(Linux/Unix) encoded string to UTF-8 encoding.
function cp1251_utf8( $sInput )
   $sOutput = "";
   for ( $i = 0; $i < strlen( $sInput ); $i++ )
       $iAscii = ord( $sInput[$i] );
       if ( $iAscii >= 192 && $iAscii <= 255 )
           $sOutput .=  "&#".( 1040 + ( $iAscii - 192 ) ).";";
       else if ( $iAscii == 168 )
           $sOutput .= "&#".( 1025 ).";";
       else if ( $iAscii == 184 )
           $sOutput .= "&#".( 1105 ).";";
           $sOutput .= $sInput[$i];
   return $sOutput;


Here is a code to convert ISO 8859-1 to UTF-8 and vice versa without using iconv.
//Logic from
$str_iso8859_1 = 'foo in ISO 8859-1';
//ISO 8859-1 to UTF-8
$str_utf8 = preg_replace("/([\x80-\xFF])/e",
//UTF-8 to ISO 8859-1
$str_iso8859_1 = preg_replace("/([\xC2\xC3])([\x80-\xBF])/e",
R. Rajesh Jeba Anbiah


Great class to convert between charsets:


For those who have troubles in displaying UCS-2 data on browser, here's a simple function that convert ucs2 to html unicode entities :
function ucs2html($str) {
$str=trim($str); // if you are reading from file


Didn't know its a feature or not but its works for me (PHP 5.0.4)
iconv('', 'UTF-8', $str)
test it to convert from windows-1251 (stored in DB) to UTF-8 (which i use for web pages).
BTW i convert each array i fetch from DB with array_walk_recursive...

convert windows-1255 to utf-8 with the following code
$heb = 'put hebrew text here';
$utf = preg_replace("/([\xE0-\xFA])/e","chr(215).chr(ord(\${1})-80)",$heb);


//script from
//javascript unesape
function unescape($str) {
 $str = rawurldecode($str);
 $ar = $r[0];
 foreach($ar as $k=>$v) {
   if(substr($v,0,2) == "%u")
     $ar[$k] = iconv("UCS-2","UTF-8",pack("H4",substr($v,-4)));
   elseif(substr($v,0,3) == "&#x")
     $ar[$k] = iconv("UCS-2","UTF-8",pack("H4",substr($v,3,-1)));
   elseif(substr($v,0,2) == "&#") {
echo substr($v,2,-1)."
     $ar[$k] = iconv("UCS-2","UTF-8",pack("n",substr($v,2,-1)));
 return join("",$ar);


<? // it's only example
function CP1251toUTF8($string){
 $out = '';
 for ($i = 0; $i<strlen($string); ++$i){
   $ch = ord($string{$i});
   if ($ch < 0x80) $out .= chr($ch);
     if ($ch >= 0xC0)
       if ($ch < 0xF0)
            $out .= "\xD0".chr(0x90 + $ch - 0xC0); // &#1040;-&#1071;, &#1072;-&#1087; (A-YA, a-p)
       else $out .= "\xD1".chr(0x80 + $ch - 0xF0); // &#1088;-&#1103; (r-ya)
         case 0xA8: $out .= "\xD0\x81"; break; // YO
         case 0xB8: $out .= "\xD1\x91"; break; // yo
         // ukrainian
         case 0xA1: $out .= "\xD0\x8E"; break; // &#1038; (U)
         case 0xA2: $out .= "\xD1\x9E"; break; // &#1118; (u)
         case 0xAA: $out .= "\xD0\x84"; break; // &#1028; (e)
         case 0xAF: $out .= "\xD0\x87"; break; // &#1031; (I..)
         case 0xB2: $out .= "\xD0\x86"; break; // I (I)
         case 0xB3: $out .= "\xD1\x96"; break; // i (i)
         case 0xBA: $out .= "\xD1\x94"; break; // &#1108; (e)
         case 0xBF: $out .= "\xD1\x97"; break; // &#1111; (i..)
         // chuvashian
         case 0x8C: $out .= "\xD3\x90"; break; // &#1232; (A)
         case 0x8D: $out .= "\xD3\x96"; break; // &#1238; (E)
         case 0x8E: $out .= "\xD2\xAA"; break; // &#1194; (SCH)
         case 0x8F: $out .= "\xD3\xB2"; break; // &#1266; (U)
         case 0x9C: $out .= "\xD3\x91"; break; // &#1233; (a)
         case 0x9D: $out .= "\xD3\x97"; break; // &#1239; (e)
         case 0x9E: $out .= "\xD2\xAB"; break; // &#1195; (sch)
         case 0x9F: $out .= "\xD3\xB3"; break; // &#1267; (u)
 return $out;

Change Language

Follow Navioo On Twitter
eXTReMe Tracker