iconv º¯Êý
ÔÚÏßÊֲ᣺ÖÐÎÄ Ó¢ÎÄ
PHPÊÖ²á

iconv

(PHP 4 >= 4.0.5, PHP 5)

iconvConvert string to requested character encoding

˵Ã÷

string iconv ( string $in_charset , string $out_charset , string $str )

Performs a character set conversion on the string str from in_charset to out_charset.

²ÎÊý

in_charset

The input charset.

out_charset

The output charset.

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.

str

The string to be converted.

·µ»ØÖµ

Returns the converted string »òÕßÔÚʧ°Üʱ·µ»Ø FALSE.

·¶Àý

Example #1 iconv() example

<?php
$text 
"This is the Euro symbol '€'.";

echo 
'Original : '$textPHP_EOL;
echo 
'TRANSLIT : 'iconv("UTF-8""ISO-8859-1//TRANSLIT"$text), PHP_EOL;
echo 
'IGNORE   : 'iconv("UTF-8""ISO-8859-1//IGNORE"$text), PHP_EOL;
echo 
'Plain    : 'iconv("UTF-8""ISO-8859-1"$text), PHP_EOL;

?>

ÒÔÉÏÀý³ÌµÄÊä³öÀàËÆÓÚ£º

Original : This is the Euro symbol '€'.
TRANSLIT : This is the Euro symbol 'EUR'.
IGNORE   : This is the Euro symbol ''.
Plain    :
Notice: iconv(): Detected an illegal character in input string in .\iconv-example.php on line 7
This is the Euro symbol '


iconv º¯Êý
ÔÚÏßÊֲ᣺ÖÐÎÄ Ó¢ÎÄ
PHPÊÖ²á
PHPÊÖ²á - N: Convert string to requested character encoding

Óû§ÆÀÂÛ:

daniel dot rhodes at warpasylum dot co dot uk (23-Aug-2011 04:22)

Interestingly, setting different target locales results in different, yet appropriate, transliterations. For example:

<?php
//some German
$utf8_sentence = 'Wei?, Goldmann, G?bel, Weiss, G?the, Goethe und G?tz';

//UK
setlocale(LC_ALL, 'en_GB');

//transliterate
$trans_sentence = iconv('UTF-8', 'ASCII//TRANSLIT', $utf8_sentence);

//gives [Weiss, Goldmann, Gobel, Weiss, Gothe, Goethe und Gotz]
//which is our original string flattened into 7-bit ASCII as
//an English speaker would do it (ie. simply remove the umlauts)
echo $trans_sentence . PHP_EOL;

//Germany
setlocale(LC_ALL, 'de_DE');

$trans_sentence = iconv('UTF-8', 'ASCII//TRANSLIT', $utf8_sentence);

//gives [Weiss, Goldmann, Goebel, Weiss, Goethe, Goethe und Goetz]
//which is exactly how a German would transliterate those
//umlauted characters if forced to use 7-bit ASCII!
//(because really ? = ae, ? = oe and ¨¹ = ue)
echo $trans_sentence . PHP_EOL;

?>

wembaster at mp3s dot pl (06-Jun-2011 09:21)

If you want to export some utf-8 data into csv/tsv that will be readable by excel with correct encoding you must add special non vissable characters at the begining of file

<?php

$data
= "Some utf-8 characters ??????"

header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
header('Content-Disposition: attachment; filename = "Export '.date("Y-m-d").'.tsv"');
header('Pragma: no-cache');

//these characters will make correct encoding to excel
echo chr(255).chr(254).iconv("UTF-8", "UTF-16LE//IGNORE", $data);

?>

marc at NOSPAM dot leftek dot com (07-May-2011 06:02)

A simple cleaning function [eg: iconv("UTF-8","UTF-8//IGNORE", $s)] may not be enough when receiving UTF8 input that needs to be saved in MySQL.  Prior to MySQL v5.5 four byte sequences were not supported so a function is needed to strip these out as well:

<?php
           
for($pos=strlen($strUtf8)-1; $pos >= 0 ; $pos--){
               
$char = substr($strUtf8, $pos, 1);
                if (
ord($char) > 0xEF) $strUtf8 = substr($strUtf8, 0, $pos).substr($strUtf8, $pos+1);
            }
?>

perhydrol dot pl at gmail dot com (18-Jan-2011 10:20)

I needed a method for recursive iconv. I didn't find one, so wrote it myself and I'd like to share it. Mabye someone will need it.

<?php
public function recursive_iconv(string $in_charset, string $out_charset, $arr){
        if (!
is_array($arr)){
            return
iconv($in_charset, $out_charset, $arr);
        }
       
$ret = $arr;
        function
array_iconv(&$val, $key, $userdata){
           
$val = iconv($userdata[0], $userdata[1], $val);
        }
       
array_walk_recursive($ret, "array_iconv", array($in_charset, $out_charset));
        return
$ret;
    }
?>

ameten (15-Jan-2011 12:17)

I have used iconv to convert from cp1251 into UTF-8. I spent a day to investigate why a string with Russian capital '§²' (sounds similar to 'r') at the end cannot be inserted into a database.

The problem is not in iconv. But '§²' in cp1251 is chr(208) and '§²' in UTF-8 is chr(208).chr(106). chr(106) is one of the space symbol which match '\s' in regex. So, it can be taken by a greedy '+' or '*' operator. In that case, you loose '§²' in your string.

For example, '§¤§²   ' (Russian, UTF-8). Function preg_match. Regex is '(.+?)[\s]*'. Then '(.+?)' matches '§¤'.chr(208) and '[\s]*' matches chr(106).'   '.

Although, it is not a bug of iconv, but it looks like it very much. That's why I put this comment here.

OsamaBinLogin (15-Oct-2010 05:47)

I was trying to convert utf8 to ascii like everybody else.  It worked fine in PHP5.3 on mac, but something was wrong on PHP5.2.6 on Linux, our server.  iConv refused to generate, eg e for ¨º and stuff; I always got ?.   This is of course the fault of the underlying iconv in the system.  I finally just made my own UTF8 untangler and lookup table; it's only 96 chars and I typed it in.  Didn't need anything past Latin 1.  No iconv needed, no test is this mac/linux, simple for my simple purposes.

vb (at) bertola.eu (15-Jul-2010 02:35)

On my system, according to tests, and also as reported by other people elsewhere, you can combine TRANSLIT and IGNORE only by appending

//IGNORE//TRANSLIT

strictly in that order, but NOT by appending //TRANSLIT//IGNORE, which would lead to //IGNORE being ignored ( :) ).

Anyway, it's hard to understand how one could devise a system of passing options that does not allow to couple both options in a neat manner, and also to understand why the default behaviour should be the less useful and most dangerous one (throwing away most of your data at the first unexpected character). Software design FAIL :-/

Anonymous (18-Jan-2010 07:37)

For text with special characters such as (¨¦) &eacute; which appears at 0xE9 in the ISO-8859-1 and at 0x82 in IBM-850. The correct output character set is 'IBM850' as:
('ISO-8859-1', 'IBM850', 'Qu¨¦bec')

Dmitri Snytkine cms.lampcms.com (24-Dec-2009 06:32)

Be careful with //TRANSLIT//IGNORE option.

While it may have worked for some people, it failed miserably in my situation. The iconv() stopped at the first illegar char, cutting off the string right there, which is the default behaviour of iconv(), so it did not respect the //IGNORE switch after the //TRANSLIT

When I used only the //IGNORE switch, it did work properly, just the illegal characters were dropped.

It may be the case when the result depends on the version of iconv or maybe even version of php

Just don't assume that //TRANSLIT//IGNORE will work together all the time because it does not.

finster at gmail dot com (03-Dec-2009 09:48)

I had a situation where I needed some characters transliterated, but the others ignored (for weird diacritics like ayn or hamza).

Adding //TRANSLIT//IGNORE seemed to do the trick for me.

It transliterates everything that is able to be transliterated, but then throws out stuff that can't be.

So:

<?php
$string
= "?ABB?S?B?D";

echo
iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $string);
// output: [nothing, and you get a notice]

echo iconv('UTF-8', 'ISO-8859-1//IGNORE', $string);
// output: ABBSBD

echo iconv('UTF-8', 'ISO-8859-1//TRANSLIT//IGNORE', $string);
// output: ABBASABAD
// Yay! That's what I wanted!

?>

Andries Seutens (07-Nov-2009 07:38)

When doing transliteration, you have to make sure that your LC_COLLATE is properly set, otherwise the default POSIX will be used.

To transform "ren¨¦" into "rene" we could use the following code snippet:

<?php

setlocale
(LC_CTYPE, 'nl_BE.utf8');

$string = 'ren¨¦';
$string = iconv('UTF-8', 'ASCII//TRANSLIT', $string);

echo
$string; // outputs rene

?>

annuaireehtp at gmail dot com (14-Oct-2009 12:53)

to test different combinations of convertions between charsets (when we don't know the source charset and what is the convenient destination charset) this is an example :

<?php
$tab
= array("UTF-8", "ASCII", "Windows-1252", "ISO-8859-15", "ISO-8859-1", "ISO-8859-6", "CP1256");
$chain = "";
foreach (
$tab as $i)
    {
        foreach (
$tab as $j)
        {
           
$chain .= " $i$j ".iconv($i, $j, "$my_string");
        }
    }

echo
$chain;
?>

then after displaying, you use the $i$j that shows good displaying.
NB: you can add other charsets to $tab  to test other cases.

phpmanualspam at netebb dot com (18-Sep-2009 07:53)

mirek code, dated 16-May-2008 10:17, added the characters `^~'" to the output.
This function will strip out these extra characters:
<?php
setlocale
(LC_ALL, 'en_US.UTF8');
function
clearUTF($s)
{
   
$r = '';
   
$s1 = @iconv('UTF-8', 'ASCII//TRANSLIT', $s);
   
$j = 0;
    for (
$i = 0; $i < strlen($s1); $i++) {
       
$ch1 = $s1[$i];
       
$ch2 = @mb_substr($s, $j++, 1, 'UTF-8');
        if (
strstr('`^~\'"', $ch1) !== false) {
            if (
$ch1 <> $ch2) {
                --
$j;
                continue;
            }
        }
       
$r .= ($ch1=='?') ? $ch2 : $ch1;
    }
    return
$r;
}
?>

martin at front of mind dot co dot uk (29-May-2009 11:33)

For transcoding values in an Excel generated CSV the following seems to work:

<?php
$value
= iconv('Windows-1252', 'UTF-8//TRANSLIT', $value);
?>

manuel at kiessling dot net (16-Apr-2009 05:33)

Like many other people, I have encountered massive problems when using iconv() to convert between encodings (from UTF-8 to ISO-8859-15 in my case), especially on large strings.

The main problem here is that when your string contains illegal UTF-8 characters, there is no really straight forward way to handle those. iconv() simply (and silently!) terminates the string when encountering the problematic characters (also if using //IGNORE), returning a clipped string. The

<?php

$newstring
= html_entity_decode(htmlentities($oldstring, ENT_QUOTES, 'UTF-8'), ENT_QUOTES , 'ISO-8859-15');

?>

workaround suggested here and elsewhere will also break when encountering illegal characters, at least dropping a useful note ("htmlentities(): Invalid multibyte sequence in argument in...")

I have found a lot of hints, suggestions and alternative methods (it's scary and in my opinion no good sign how many ways PHP natively provides to convert the encoding of strings), but none of them really worked, except for this one:

<?php

$newstring
= mb_convert_encoding($oldstring, 'ISO-8859-15', 'UTF-8');

?>

wulf dot kaiser at mpimf-heidelberg dot mpg dot de (03-Apr-2009 10:57)

Here a very small but useful way to handle text files before further using them:

<?php

$in
= file("/tmp/myfile.txt");
$out = fopen("/tmp/myfile.txt", "w");

foreach (
$in as $line) {

 
fputs($out, iconv("UTF-8","ISO-8859-1", $line));}

?>

kikke (20-Feb-2009 12:50)

You can use native iconv in Linux via passthru if all else failed.
Use the -c parameter to suppress error messages.

admin at studio-gepard dot pl (12-Feb-2009 11:20)

I noticed that iconv might return not entire string, and no error. It happens when iconv encounters characters it doesn't know how to convert to certain encoding.
Simplest way to check how it works is:
<?php
$text
=iconv('utf-8','iso-8859-2',$text);
$text=iconv('utf-8','iso-8859-2',$text);
?>
the result will be $text till first encounter of iso-8859-2 -specific char (such as ? / ? which already was converted to ¡À / ? ). It's quite hard to catch this error and brings a lot of trouble. I got it with converting greek alpha into iso-8859-2 (should be &alpha; but causes the error)

zoe at monkeehouse dot com (13-Nov-2008 10:08)

If you have problems using iconv() for the simple conversion of UTF-8 European (extended Latin) characters to their Windows CP1252 equivalents, here's a quick hack that does the job:

// Zoe's iconv() replacement.  See http://en.wikipedia.org/wiki/Windows-1252
function translateUTF8ToWindowsCP1252($string) {
    $utf8 = array(
        '??¡§', // ??¡§
        '???', // ???
        '??', // ??
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¨¢', // ¡Ì¨¢
        '¡Ì¨¤', // ¡Ì¨¤
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¨¦', // ¡Ì¨¦
        '¡Ì¨¨', // ¡Ì¨¨
        '¡Ì¨º', // ¡Ì¨º
        '¡Ì?', // ¡Ì?
        '¡Ì¨ª', // ¡Ì¨ª
        '¡Ì¨¬', // ¡Ì¨¬
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¨®', // ¡Ì¨®
        '¡Ì¨°', // ¡Ì¨°
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¨²', // ¡Ì¨²
        '¡Ì¨´', // ¡Ì¨´
        '¡Ì?', // ¡Ì?
        '¡Ì¨¹', // ¡Ì¨¹
        '¡Ì?', // ¡Ì?
        '¡Ì¡ã', // ¡Ì¡ã
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¡ì', // ¡Ì¡ì
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¡§', // ¡Ì¡§
        '¡Ì¡Ù', // ¡Ì¡Ù
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¡Þ', // ¡Ì¡Þ
        '¡Ì¡À', // ¡Ì¡À
        '¡Ì¡Ü', // ¡Ì¡Ü
        '¡Ì¡Ý', // ¡Ì¡Ý
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¡Æ', // ¡Ì¡Æ
        '¡Ì¡Ç', // ¡Ì¡Ç
        '¡Ì¦Ð', // ¡Ì¦Ð
        '¡Ì¡Ò', // ¡Ì¡Ò
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
        '¡Ì¦¸', // ¡Ì¦¸
        '¡Ì?', // ¡Ì?
        '¡Ì?', // ¡Ì?
    );

    $cp1252 = array(
        chr(128), // ??¡§
        chr(146), // ???
        chr(163), // ??
        chr(192), // ¡Ì?
        chr(193), // ¡Ì?
        chr(194), // ¡Ì?
        chr(195), // ¡Ì?
        chr(196), // ¡Ì?
        chr(197), // ¡Ì?
        chr(198), // ¡Ì?
        chr(199), // ¡Ì¨¢
        chr(200), // ¡Ì¨¤
        chr(201), // ¡Ì?
        chr(202), // ¡Ì?
        chr(203), // ¡Ì?
        chr(204), // ¡Ì?
        chr(205), // ¡Ì?
        chr(206), // ¡Ì¨¦
        chr(207), // ¡Ì¨¨
        chr(208), // ¡Ì¨º
        chr(209), // ¡Ì?
        chr(210), // ¡Ì¨ª
        chr(211), // ¡Ì¨¬
        chr(212), // ¡Ì?
        chr(213), // ¡Ì?
        chr(214), // ¡Ì?
        chr(215), // ¡Ì¨®
        chr(216), // ¡Ì¨°
        chr(217), // ¡Ì?
        chr(218), // ¡Ì?
        chr(219), // ¡Ì?
        chr(220), // ¡Ì¨²
        chr(221), // ¡Ì¨´
        chr(222), // ¡Ì?
        chr(223), // ¡Ì¨¹
        chr(224), // ¡Ì?
        chr(225), // ¡Ì¡ã
        chr(226), // ¡Ì?
        chr(227), // ¡Ì?
        chr(228), // ¡Ì¡ì
        chr(229), // ¡Ì?
        chr(230), // ¡Ì?
        chr(231), // ¡Ì?
        chr(232), // ¡Ì?
        chr(233), // ¡Ì?
        chr(234), // ¡Ì?
        chr(235), // ¡Ì?
        chr(236), // ¡Ì¡§
        chr(237), // ¡Ì¡Ù
        chr(238), // ¡Ì?
        chr(239), // ¡Ì?
        chr(240), // ¡Ì¡Þ
        chr(241), // ¡Ì¡À
        chr(242), // ¡Ì¡Ü
        chr(243), // ¡Ì¡Ý
        chr(244), // ¡Ì?
        chr(245), // ¡Ì?
        chr(246), // ¡Ì?
        chr(247), // ¡Ì¡Æ
        chr(248), // ¡Ì¡Ç
        chr(249), // ¡Ì¦Ð
        chr(250), // ¡Ì¡Ò
        chr(251), // ¡Ì?
        chr(252), // ¡Ì?
        chr(253), // ¡Ì¦¸
        chr(254), // ¡Ì?
        chr(255), // ¡Ì?
    );

    return str_replace($utf8, $cp1252, $string);
}

ToS (10-Nov-2008 02:35)

I used to have problems with Latin characters in UTF-8 while exporting text to PEAR xls writer.
This little conmbination solved my problem, you might want to try something like that:

<?php
function convert_locale_for_xls ($text) {
 
$return = iconv('UTF-8', 'cp1250', $text);
  return
preg_replace("/([\xC2\xC4])([\x80-\xBF])/e""chr(ord('\\1')<<6&0xC0|ord('\\2')&0x3F)", $return);
}
?>

Leigh Morresi (02-Oct-2008 07:10)

If you are getting question-marks in your iconv output when transliterating, be sure to 'setlocale' to something your system supports.

Some PHP CMS's will default setlocale to 'C', this can be a problem.

use the "locale" command to find out a list..

$ locale -a
C
en_AU.utf8
POSIX

<?php
  setlocale
(LC_CTYPE, 'en_AU.utf8');
 
$str = iconv('UTF-8', 'ASCII//TRANSLIT', "C?te d'Ivoire");
?>

mirek at burkon dot org (16-May-2008 11:17)

If you need to strip as many national characters from UTF-8 as possible and keep the rest of input unchanged (i.e. convert whatever can be converted to ASCII and leave the rest), you can do it like this:

<?php
setlocale
(LC_ALL, 'en_US.UTF8');

function
clearUTF($s)
{
   
$r = '';
   
$s1 = iconv('UTF-8', 'ASCII//TRANSLIT', $s);
    for (
$i = 0; $i < strlen($s1); $i++)
    {
       
$ch1 = $s1[$i];
       
$ch2 = mb_substr($s, $i, 1);

       
$r .= $ch1=='?'?$ch2:$ch1;
    }
    return
$r;
}

echo
clearUTF('?¨ªlen¨§ ?lu?ou?k? Va?ek ¨²p¨§l olol! This will remain untranslated: ??????');
//outputs Silene zlutoucky Vasek upel olol! This will remain untranslated: ??????
?>

Just remember you HAVE TO set locale to some unicode encoding to make iconv handle //TRANSLIT correctly!

berserk220 at mail dot ru (01-Mar-2008 02:44)

So, as iconv() does not always work correctly, in most cases, much easier to use htmlentities().
Example: <?php $content=htmlentities(file_get_contents("incoming.txt"), ENT_QUOTES, "Windows-1252");  file_put_contents("outbound.txt", html_entity_decode($content, ENT_QUOTES , "utf-8")); ?>

anton dot vakulchik at gmail dot com (02-Feb-2008 06:40)

function detectUTF8($string)
{
        return preg_match('%(?:
        [\xC2-\xDF][\x80-\xBF]        # non-overlong 2-byte
        |\xE0[\xA0-\xBF][\x80-\xBF]               # excluding overlongs
        |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}      # straight 3-byte
        |\xED[\x80-\x9F][\x80-\xBF]               # excluding surrogates
        |\xF0[\x90-\xBF][\x80-\xBF]{2}    # planes 1-3
        |[\xF1-\xF3][\x80-\xBF]{3}                  # planes 4-15
        |\xF4[\x80-\x8F][\x80-\xBF]{2}    # plane 16
        )+%xs', $string);
}

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 ).";";
        else
            $sOutput .= $sInput[$i];
    }
   
    return $sOutput;
}

function encoding($string){
    if (function_exists('iconv')) {   
        if (@!iconv('utf-8', 'cp1251', $string)) {
            $string = iconv('cp1251', 'utf-8', $string);
        }
        return $string;
    } else {
        if (detectUTF8($string)) {
            return $string;       
        } else {
            return cp1251_utf8($string);
        }
    }
}
echo encoding($string);

mightye at gmail dot com (05-Nov-2007 01:01)

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.
<?php
// 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.

gree:.. (gree 4T grees D0T net) (24-Aug-2007 10:19)

In my case, I had to change:
<?php
setlocale
(LC_CTYPE, 'cs_CZ');
?>
to
<?php
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

dead dot screamer at seznam dot cz (14-Jun-2007 05:08)

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`

Ritchie (25-Mar-2007 12:11)

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.

Example:
<?php
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
?>

Georgios Papadakis (08-Mar-2007 08:28)

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).

<?php
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;
}
?>

Locoluis (15-Nov-2006 08:36)

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.

sire at acc dot umu dot se (14-Dec-2005 09:17)

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).

nilcolor at gmail dot coom (24-Nov-2005 11:29)

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...

anyean at gmail dot com (30-May-2005 11:23)

<?php
//script from http://zizi.kxup.com/
//javascript unesape
function unescape($str) {
 
$str = rawurldecode($str);
 
preg_match_all("/(?:%u.{4})|&#x.{4};|&#\d+;|.+/U",$str,$r);
 
$ar = $r[0];
print_r($ar);
  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)."<br>";
     
$ar[$k] = iconv("UCS-2","UTF-8",pack("n",substr($v,2,-1)));
    }
  }
  return
join("",$ar);
}
?>

zhawari at hotmail dot com (01-Feb-2005 11:27)

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

<?php
 
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];
                else
                {
                       
$results = dechex((hexdec($substring1)-192)*64 + (hexdec($substring2)-128));
                        if (
$results < 1000) $results = "0".$results;
                       
$i+=2;
                }
               
$ucs2 .= $results;
        }
        return
$ucs2;
}
 
echo
strtoupper(utf8toucs2("D985D8B1D8AD"))."\n";
echo
strtoupper(utf8toucs2("456725"))."\n";
 
?>

Input:
D985D8B1D8AD
Output:
06450631062D

Input:
456725
Output:
004500670025

PHANTOm <phantom at nix dot co dot il> (27-Jan-2005 08:49)

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

zhawari at hotmail dot com (18-Jan-2005 11:02)

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

<?php
function ucs2toutf8($str)
{
        for (
$i=0;$i<strlen($str);$i+=4)
        {
               
$substring1 = $str[$i].$str[$i+1];
               
$substring2 = $str[$i+2].$str[$i+3];
 
                if (
$substring1 == "00")
                {
                       
$byte1 = "";
                       
$byte2 = $substring2;
                }
                else
                {
                       
$substring = $substring1.$substring2;
                       
$byte1 = dechex(192+(hexdec($substring)/64));
                       
$byte2 = dechex(128+(hexdec($substring)%64));
                }
               
$utf8 .= $byte1.$byte2;
        }
        return
$utf8;
}
 
echo
strtoupper(ucs2toutf8("06450631062D0020"));

?>

Input:
06450631062D
Output:
D985D8B1D8AD

regards,
Ziyad

SiMM (10-Dec-2004 07:15)

<?php // 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);
    else
      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)
     
else
        switch(
$ch){
          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;
}
?>

aissam at yahoo dot com (30-Nov-2004 04:20)

For those who have troubles in displaying UCS-2 data on browser, here's a simple function that convert ucs2 to html unicode entities :

<?php

 
function ucs2html($str) {
   
$str=trim($str); // if you are reading from file
   
$len=strlen($str);
   
$html='';
    for(
$i=0;$i<$len;$i+=2)
       
$html.='&#'.hexdec(dechex(ord($str[$i+1])).
                  
sprintf("%02s",dechex(ord($str[$i])))).';';
    return(
$html);
 }
?>

nikolai-dot-zujev-at-gmail-dot-com (18-Nov-2004 09:14)

Here is an example how to convert windows-1251 (windows) or cp1251(Linux/Unix) encoded string to UTF-8 encoding.

<?php
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 ).";";
        else
           
$sOutput .= $sInput[$i];
    }
   
    return
$sOutput;
}
?>

vitek at 4rome dot ru (16-Nov-2004 07:53)

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:
<?php
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 phpclub.net for explaining this behaviour.

ng4rrjanbiah at rediffmail dot com (22-Jun-2004 04:10)

Here is a code to convert ISO 8859-1 to UTF-8 and vice versa without using iconv.

<?php
//Logic from http://twiki.org/cgi-bin/view/Codev/InternationalisationUTF8
$str_iso8859_1 = 'foo in ISO 8859-1';
//ISO 8859-1 to UTF-8
$str_utf8 = preg_replace("/([\x80-\xFF])/e",
           
"chr(0xC0|ord('\\1')>>6).chr(0x80|ord('\\1')&0x3F)",
            
$str_iso8859_1);
//UTF-8 to ISO 8859-1
$str_iso8859_1 = preg_replace("/([\xC2\xC3])([\x80-\xBF])/e",
               
"chr(ord('\\1')<<6&0xC0|ord('\\2')&0x3F)",
                
$str_utf8);
?>

HTH,
R. Rajesh Jeba Anbiah