Php перекодировка windows 1251 в utf 8

Проблема кодировок часто возникает при написании парсеров, чтении данных из xml и CSV файлов. Ниже представлены способы эту проблему решить.

1

windows-1251 в UTF-8

$text = iconv('windows-1251//IGNORE', 'UTF-8//IGNORE', $text);
echo $text;

PHP

$text = mb_convert_encoding($text, 'UTF-8', 'windows-1251');
echo $text;

PHP

2

UTF-8 в windows-1251

$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text);
echo $text;

PHP

$text = mb_convert_encoding($text, 'windows-1251', 'utf-8');
echo $text;

PHP

3

Когда ни что не помогает

$text = iconv('utf-8//IGNORE', 'cp1252//IGNORE', $text);
$text = iconv('cp1251//IGNORE', 'utf-8//IGNORE', $text);
echo $text;

PHP

Иногда доходит до бреда, но работает:

$text = iconv('utf-8//IGNORE', 'windows-1251//IGNORE', $text);
$text = iconv('windows-1251//IGNORE', 'utf-8//IGNORE', $text);
echo $text;

PHP

4

File_get_contents / CURL

Бывают случаи когда file_get_contents() или CURL возвращают иероглифы (Алмазные борÑ) – причина тут не в кодировке, а в отсутствии BOM-метки.

$text = file_get_contents('https://example.com');
$text = "\xEF\xBB\xBF" .  $text;
echo $text;

PHP

Ещё бывают случаи, когда file_get_contents() возвращает текст в виде:

�mw�Ƒ0�����&IkAI��f��j4/{�</�&�h�� ��({�񌝷o�����:/��<g���g��(�=�9�Paɭ

Это сжатый текст в GZIP, т.к. функция не отправляет правильные заголовки. Решение проблемы через CURL:

function getcontents($url){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
	$output = curl_exec($ch);
	curl_close($ch);
	return $output;
}

echo getcontents('https://example.com');

PHP

12.01.2017, обновлено 02.11.2021

Другие публикации

Отправка e-mail в кодировке UTF-8 с вложенными файлами и возможные проблемы.

JSON (JavaScript Object Notation) – текстовый формат обмена данными, основанный на JavaScript, который представляет собой набор пар {ключ: значение}. Значение может быть массивом, числом, строкой и…

Описание значений глобального массива $_SERVER с примерами.

Так как Instagram и Fasebook ограничили доступ к API, а фото с открытого аккаунта всё же нужно периодически получать и…

В статье представлены различные PHP-расширения для чтения файлов XLS, XLSX, описаны их плюсы и минусы, а также примеры…

Примеры как зарегистрировать бота в Телеграм, описание и взаимодействие с основными методами API.

iconv

(PHP 4 >= 4.0.5, PHP 5, PHP 7, PHP 8)

iconvПреобразовывает строку из одной кодировки символов в другую

Описание

Список параметров

from_encoding

Текущая кодировка, используемая для интерпретации параметра string.

to_encoding

Требуемая на выходе кодировка.

Если к параметру to_encoding добавлена строка
//TRANSLIT, включается режим транслитерации.
Это значит, что в случае, если символ не может быть представлен в требуемой кодировке,
он может быть заменён одним или несколькими похожими символами.
Если добавлена строка //IGNORE, то символы,
которые не могут быть представлены в требуемой кодировке, будут
удалены.
В случае отсутствия вышеуказанных параметров
будет сгенерирована ошибка уровня E_NOTICE,
а функция вернёт false.

Предостережение

Как будет работать //TRANSLIT и будет ли вообще, зависит от
системной реализации iconv() (ICONV_IMPL).
Известны некоторые реализации, которые просто игнорируют
//TRANSLIT, так что конвертация для символов некорректных
для to_encoding скорее всего закончится ошибкой.

string

Строка (string) для преобразования.

Возвращаемые значения

Возвращает преобразованную строку или false, если возникла ошибка.

Примеры

Пример #1 Пример использования iconv()

<?php
$text
= "Это символ евро - '€'.";

echo

'Исходная строка : ', $text, PHP_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
'Обычное преобразование : ', iconv("UTF-8", "ISO-8859-1", $text), PHP_EOL;?>

Вывод приведённого примера будет похож на:

Исходная строка        : Это символ евро - '€'.
С добавлением TRANSLIT : Это символ евро - 'EUR'.
С добавлением IGNORE   :Это символ евро - ''.
Обычное преобразование :
Notice: iconv(): Detected an illegal character in input string in .\iconv-example.php on line 7

Примечания

Замечание:

Доступные кодировки и опции зависят от установленной реализации iconv.
Если параметр from_encoding или from_encoding
не поддерживается в текущей системе, будет возвращено значение false.

Смотрите также

  • mb_convert_encoding() — Преобразовывает строку из одной кодировки символов в другую
  • UConverter::transcode() — Преобразовывает строку из одной кодировки символов в другую

Нашли ошибку?

Ritchie

18 years ago

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

orrd101 at gmail dot com

13 years ago

The "//ignore" option doesn't work with recent versions of the iconv library. So if you're having trouble with that option, you aren't alone.


That means you can't currently use this function to filter invalid characters. Instead it silently fails and returns an empty string (or you'll get a notice but only if you have E_NOTICE enabled).


This has been a known bug with a known solution for at least since 2009 years but no one seems to be willing to fix it (PHP must pass the -c option to iconv). It's still broken as of the latest release 5.4.3.


https://bugs.php.net/bug.php?id=48147

https://bugs.php.net/bug.php?id=52211

https://bugs.php.net/bug.php?id=61484


[UPDATE 15-JUN-2012]

Here's a workaround...


ini_set('mbstring.substitute_character', "none");

$text= mb_convert_encoding($text, 'UTF-8', 'UTF-8');


That will strip invalid characters from UTF-8 strings (so that you can insert it into a database, etc.). Instead of "none" you can also use the value 32 if you want it to insert spaces in place of the invalid characters.

daniel dot rhodes at warpasylum dot co dot uk

13 years ago

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

annuaireehtp at gmail dot com

15 years ago

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.

Daniel Klein

5 years ago

If you want to convert to a Unicode encoding without the byte order mark (BOM), add the endianness to the encoding, e.g. instead of "UTF-16" which will add a BOM to the start of the string, use "UTF-16BE" which will convert the string without adding a BOM.

i.e.

<?php
iconv
('CP1252', 'UTF-16', $text); // with BOM
iconv('CP1252', 'UTF-16BE', $text); // without BOM

zhawari at hotmail dot com

20 years ago

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

jessiedeer at hotmail dot com

11 years ago

iconv with //IGNORE works as expected: it will skip the character if this one does not exist in the $out_charset encoding.

If a character is missing from the $in_charset encoding (eg byte \x81 from CP1252 encoding), then iconv will return an error, whether with //IGNORE or not.

manuel at kiessling dot net

16 years ago

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');?>

jorortega at gmail dot com

11 years ago

Be aware that iconv in PHP uses system implementations of locales and languages, what works under linux, normally doesn't in windows.

Also, you may notice that recent versions of linux (debian, ubuntu, centos, etc) the //TRANSLIT option doesn't work. since most distros doesn't include the intl packages (example: php5-intl and icuxx (where xx is a number) in debian) by default. And this because the intl package conflicts with another package needed for international DNS resolution.

Problem is that configuration is dependent of the sysadmin of the machine where you're hosted, so iconv is pretty much useless by default, depending on what configuration is used by your distro or the machine's admin.

Leigh Morresi

16 years ago

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");
?>

nikolai-dot-zujev-at-gmail-dot-com

20 years ago

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

gree:.. (gree 4T grees D0T net)

17 years ago

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

atelier at degoy dot com

10 years ago

There may be situations when a new version of a web site, all in UTF-8, has to display some old data remaining in the database with ISO-8859-1 accents. The problem is iconv("ISO-8859-1", "UTF-8", $string) should not be applied if $string is already UTF-8 encoded.

I use this function that does'nt need any extension :

function convert_utf8( $string ) {
if ( strlen(utf8_decode($string)) == strlen($string) ) {
// $string is not UTF-8
return iconv("ISO-8859-1", "UTF-8", $string);
} else {
// already UTF-8
return $string;
}
}

I have not tested it extensively, hope it may help.

anton dot vakulchik at gmail dot com

17 years ago

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

ameten

14 years ago

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.

phpnet at dariosulser dot ch

5 years ago

ANSI = Windows-1252 = CP1252
So UTF-8 -> ANSI:

<?php
$string
= "Winkel γ=200 für 1€"; //"γ"=HTML:&gamma;
$result = iconv('UTF-8', 'CP1252//IGNORE', $string);
echo
$result;
?>

Note1
<?php
$string
= "Winkel γ=200 für 1€";
$result = iconv('UTF-8', 'CP1252', $string);
echo
$result; //"conv(): Detected an illegal character in input string"
?>

Note2 (ANSI is better than decode in ISO 8859-1 (ISO-8859-1==Latin-1)
<?php
$string
= "Winkel γ=200 für 1€";
$result = utf8_decode($string);
echo
$result; //"Winkel ?=200 für 1?"
?>

Note3 of used languages on Websites:
93.0% = UTF-8;
3.5% = Latin-1;
0.6% = ANSI <----- you shoud use (or utf-8 if your page is in Chinese or has Maths)

nilcolor at gmail dot coom

19 years ago

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

jessie at hotmail dot com

11 years ago

Provided that there is no invalid code point in the character chain for the input encoding, the //IGNORE option works as expected. No bug here.

Nopius

10 years ago

As orrd101 said, there is a bug with //IGNORE in recent PHP versions (we use 5.6.5) where we couldn't convert some strings (i.e. "∙" from UTF8 to CP1251 with //IGNORE).
But we have found a workaround and now we use both //TRANSLIT and //IGNORE flags:
$text="∙";
iconv("UTF8", "CP1251//TRANSLIT//IGNORE", $text);

ng4rrjanbiah at rediffmail dot com

20 years ago

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

zhawari at hotmail dot com

20 years ago

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

<?phpfunction 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

rasmus at mindplay dot dk

10 years ago

Note an important difference between iconv() and mb_convert_encoding() - if you're working with strings, as opposed to files, you most likely want mb_convert_encoding() and not iconv(), because iconv() will add a byte-order marker to the beginning of (for example) a UTF-32 string when converting from e.g. ISO-8859-1, which can throw off all your subsequent calculations and operations on the resulting string.

In other words, iconv() appears to be intended for use when converting the contents of files - whereas mb_convert_encoding() is intended for use when juggling strings internally, e.g. strings that aren't being read/written to/from files, but exchanged with some other media.

vitek at 4rome dot ru

20 years ago

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.

mightye at gmail dot com

17 years ago

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.

Daniel Klein

9 years ago

I just found out today that the Windows and *NIX versions of PHP use different iconv libraries and are not very consistent with each other.

Here is a repost of my earlier code that now works on more systems. It converts as much as possible and replaces the rest with question marks:

<?php
if (!function_exists('utf8_to_ascii')) {
setlocale(LC_CTYPE, 'en_AU.utf8');
if (@
iconv("UTF-8", "ASCII//IGNORE//TRANSLIT", 'é') === false) {
// PHP is probably using the glibc library (*NIX)
function utf8_to_ascii($text) {
return
iconv("UTF-8", "ASCII//TRANSLIT", $text);
}
}
else {
// PHP is probably using the libiconv library (Windows)
function utf8_to_ascii($text) {
if (
is_string($text)) {
// Includes combinations of characters that present as a single glyph
$text = preg_replace_callback('/\X/u', __FUNCTION__, $text);
}
elseif (
is_array($text) && count($text) == 1 && is_string($text[0])) {
// IGNORE characters that can't be TRANSLITerated to ASCII
$text = iconv("UTF-8", "ASCII//IGNORE//TRANSLIT", $text[0]);
// The documentation says that iconv() returns false on failure but it returns ''
if ($text === '' || !is_string($text)) {
$text = '?';
}
elseif (
preg_match('/\w/', $text)) { // If the text contains any letters...
$text = preg_replace('/\W+/', '', $text); // ...then remove all non-letters
}
}
else {
// $text was not a string
$text = '';
}
return
$text;
}
}
}

anyean at gmail dot com

19 years ago

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

kikke

16 years ago

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

phpmanualspam at netebb dot com

15 years ago

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

Daniel Klein

12 years ago

You can use 'CP1252' instead of 'Windows-1252':
<?php
// These two lines are equivalent
$result = iconv('Windows-1252', 'UTF-8', $string);
$result = iconv('CP1252', 'UTF-8', $string);
?>
Note: The following code points are not valid in CP1252 and will cause errors.
129 (0x81)
141 (0x8D)
143 (0x8F)
144 (0x90)
157 (0x9D)
Use the following instead:
<?php
// Remove invalid code points, convert everything else
$result = iconv('CP1252', 'UTF-8//IGNORE', $string);
?>

chicopeste at gmail dot com

11 years ago

iconv also support CP850.
I used iconv("CP850", "UTF-8//TRANSLIT", $var);
to convert from SQL_Latin1_General_CP850_CI_AI to UTF-8.

Locoluis

18 years ago

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.

Anonymous

15 years ago

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

Andries Seutens

15 years ago

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

vb (at) bertola.eu

14 years ago

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 :-/

berserk220 at mail dot ru

17 years ago

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")); ?>

mirek at burkon dot org

16 years ago

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!

admin at iecw dot net

12 years ago

aissam at yahoo dot com

20 years ago

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

<?phpfunction 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);
}
?>

martin at front of mind dot co dot uk

15 years ago

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

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

  • Home
  • /
  • Windows-1251

  • /
  • Windows-1251 Encoding : PHP

Welcome to our comprehensive guide on Windows-1251 encoding in PHP! If you’re working with Cyrillic characters or need to ensure proper data representation in your web applications, understanding Windows-1251 encoding is essential. In this article, we’ll explore what Windows-1251 encoding is, how it works with PHP, and practical tips for implementing it in your projects. Whether you’re dealing with legacy systems or modern applications, you’ll discover valuable insights and examples to help you effectively manage character encoding in PHP. Join us as we demystify Windows-1251 encoding and enhance your programming skills!

Introduction to Windows-1251

Windows-1251 is a character encoding that is widely used for representing Cyrillic characters in digital formats. Developed by Microsoft, this encoding is designed to support languages that use the Cyrillic script, such as Russian, Bulgarian, and Serbian. It encompasses 256 different characters, which include standard Latin characters, control characters, and specific Cyrillic characters. As a single-byte encoding system, Windows-1251 is popular in legacy systems and applications where text needs to be displayed or processed in Cyrillic languages.

In PHP, encoding text to Windows-1251 can be achieved using the iconv() function or the mb_convert_encoding() function. These functions allow developers to convert strings from one character encoding to another, making it easier to handle text data that includes Cyrillic characters.

Example of Encoding

// Original string in UTF-8
$originalString = "Привет, мир!"; // Hello, World!
// Convert the string to Windows-1251 encoding
$encodedString = iconv("UTF-8", "Windows-1251//IGNORE", $originalString);
// Output the encoded string
echo $encodedString; // Displays the string in Windows-1251 encoding

In this example, the iconv() function takes the original UTF-8 string and converts it to Windows-1251 encoding, ignoring any characters that cannot be represented.

Decoding with Windows-1251 in PHP

Decoding text from Windows-1251 back to a more universal encoding such as UTF-8 is also straightforward in PHP. The same iconv() function can be used for this purpose.

Example of Decoding

// A Windows-1251 encoded string
$windows1251String = "\xCF\xF0\xE8\xE2\xE5\xF2, \xEC\xE8\xF0!"; // Привет, мир!
// Convert the string back to UTF-8
$decodedString = iconv("Windows-1251", "UTF-8//IGNORE", $windows1251String);
// Output the decoded string
echo $decodedString; // Displays "Привет, мир!" in UTF-8

This code snippet illustrates how to decode a string from Windows-1251 back to UTF-8, allowing for proper display and manipulation of text.

Advantages and Disadvantages of Windows-1251

Advantages

  1. Compatibility: Windows-1251 is widely supported in many applications and systems, making it a reliable choice for legacy software that requires Cyrillic support.
  2. Simplicity: As a single-byte encoding, Windows-1251 is straightforward to implement and requires less memory compared to multi-byte encodings.

Disadvantages

  1. Limited Character Set: Windows-1251 can only accommodate 256 characters, which may not be sufficient for all Cyrillic languages or specialized symbols.
  2. Obsolescence: With the rise of Unicode (UTF-8), which supports a much broader range of characters, Windows-1251 is becoming less common in modern applications.

Key Applications of Windows-1251

Windows-1251 is primarily used in systems and applications that require the display and processing of text in Cyrillic languages. Common applications include:

  • Legacy Databases: Many older databases still utilize Windows-1251 for storing and retrieving text data.
  • Email Clients: Some email clients support Windows-1251, allowing users to read and send messages in Cyrillic.
  • Web Applications: Certain web applications and sites still use Windows-1251 encoding for compatibility with older browsers and systems.

Popular Frameworks and Tools for Windows-1251

Several frameworks and tools support Windows-1251 encoding, making integration easier for developers:

  • PHP: As demonstrated, PHP provides built-in functions like iconv() and mb_convert_encoding() for encoding and decoding.
  • MySQL: MySQL databases can be configured to use Windows-1251 character sets, facilitating storage and retrieval of Cyrillic text.
  • Java: The Java programming language offers support for Windows-1251 through its Charset class, enabling easy manipulation of encoded strings.

By leveraging these frameworks and tools, developers can effectively manage Windows-1251 encoded text in their applications, ensuring compatibility and proper display across different platforms.

  1. Home
  2. Coding
  3. php
  4. Как в php изменить кодировку строки, функция iconv

Поговорим о том, как преобразовывать строки из одной кодировки в другую, используя для этого замечательную php функцию iconv.

iconv(«текущая_кодировка», «новая_кодировка», «текстовая_строка»)

В случае успеха вернет строку в новой кодировке иле в случае ошибки вернет FALSE.

Также можно использовать дополнительные параметры, добавляя их после «новой_кодировки».

1.
//TRANSLIT - заменит символы, которых нет в новой кодировке их аналогами.
iconv("ISO-8859-1", "UTF-8//TRANSLIT", $text-string)
2.
//IGNORE - пропустит символы, которых нет в новой кодировке.
iconv("UTF-8", "KOI8-U//IGNORE", $text-string)

Пример использования в коде php.

<?php
echo iconv("windows-1251", "UTF-8", "теперь я умею перекодировать строки");
?> 

На этом знакомство с функцией iconv закончено. Всем пока.

Добрый день!

Есть немаленький, старый движок. Чистый код весит около 3 Мб. Около полугода назад успешно перенес его с PHP 5.3 на версию 7.1 — документации по этому делу много. Изучил рекомендации 4-5 хороших статей. И то была пара моментов, которые не были там описаны. В принципе, все прошло достаточно гладко.

Теперь стоит другая задача. Движок настолько старый, что работает с кодировкой Windows-1251. Нужно переделать все под UTF-8. Сколько не искал — ничего толкового из советов не нашел. Большинство хорошей инфы идет из-за бугра, а для них Win-1251 не актуальна. :)

По сути единственное, что опишут — это заменить все функции работы со строками на их «mb_» аналоги. Я так понимаю, речь идет об этом списке аналогов: php.net/manual/ru/ref.mbstring.php ?

Насколько я понимаю, по части PHP нужно будет еще как минимум задать нужную кодировку в конфиге. Перекодировать сами PHP файлы в UTF-8. БД — то уже отдельные пляски. Еще из нюансов — на сайте есть AJAX, с перекодировкой результатов (т.к. такие запросы, если не ошибаюсь, отправляются только в UTF-8).

Все, этого достаточно? Что еще может быть, у кого есть опыт в подобном деле? И самое главное — нельзя ли просто в настройках PHP указать что «работаем с UTF-8» и точка. Чтобы не менять все функции?

Да и по самим функциям непоняточки. Например, есть preg_replace, но нет mb_preg_replace. Хотя в то же время есть и ereg_replace, и в то же время mb_ereg_replace. Хоть ereg_replace уже устаревшая / удаленная (в зависимости от версии PHP) функция. Как это понимать?

Запутался в конец.

2019.03.07 обновляю: узнал за эти дни много нового и интересного. :) думаю, многие очень поверхностно относятся к пониманию кодировок. Не знаю, актуальна ли тема на 2019 год. Но если что, в принципе, после всего этого могу сделать большой чек-лист что и как надо делать. Третий день переделываю движок под UTF-8. Реально исправлять код действительно не во многих местах надо. Но точек проверок очень много.

А теперь маленький вопрос-уточнение к знающим людям. Везде про preg_* функции пишут в стиле «используйте модификатор u чтобы работать с юникодом». А когда он реально необходим? По моим наблюдениям, функциям все равно со строками в каких кодировках работать. В PHP отношение ко строкам как к набору байт, а не символов. И походу модификатор u необходимо использовать только когда само регулярное выражение содержит символы за пределами US-ASCII. В противном случае любые UTF-8 строки корректно обрабатываются без модификатора u. Что скажите?

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Не запускается windows server backup
  • Какая версия антивируса касперского подходит для windows 10
  • Windows api с помощью powershell
  • Как открыть доступ к сетевому диску windows 10
  • Как узнать свой домен на windows xp