PHP Conference Japan 2024

utf8_encode

(PHP 4, PHP 5, PHP 7, PHP 8)

utf8_encode将字符串从 ISO-8859-1 转换为 UTF-8

警告

此函数自 PHP 8.2.0 起已弃用。强烈建议不要依赖此函数。

描述

#[\Deprecated]
utf8_encode(string $string): string

此函数将字符串 stringISO-8859-1 编码转换为 UTF-8

注意:

此函数不会尝试猜测提供的字符串的当前编码,它假设它被编码为 ISO-8859-1(也称为“Latin 1”)并转换为 UTF-8。由于每个字节序列都是有效的 ISO-8859-1 字符串,因此这永远不会导致错误,但如果打算使用其他编码,则不会产生有用的字符串。

许多标记为使用 ISO-8859-1 字符编码的网页实际上使用了类似的 Windows-1252 编码,并且 Web 浏览器会将 ISO-8859-1 网页解释为 Windows-1252Windows-1252 提供了额外的可打印字符,例如欧元符号 () 和弯引号 ( ),而不是某些 ISO-8859-1 控制字符。此函数不会正确转换此类 Windows-1252 字符。如果需要 Windows-1252 转换,请使用其他函数。

参数

string

一个 ISO-8859-1 字符串。

返回值

返回 string 的 UTF-8 翻译。

变更日志

版本 描述
8.2.0 此函数已被弃用。
7.2.0 此函数已从 XML 扩展移动到 PHP 的核心。在以前的版本中,只有在安装了 XML 扩展时才能使用它。

示例

示例 #1 基本示例

<?php
// 将字符串 'Zoë' 从 ISO 8859-1 转换为 UTF-8
$iso8859_1_string = "\x5A\x6F\xEB";
$utf8_string = utf8_encode($iso8859_1_string);
echo
bin2hex($utf8_string), "\n";
?>

以上示例将输出

5a6fc3ab

注释

注意弃用和替代方案

此函数自 PHP 8.2.0 起已弃用,将在未来版本中删除。应检查现有用法并替换为合适的替代方案。

可以使用 mb_convert_encoding() 实现类似的功能,它支持 ISO-8859-1 和许多其他字符编码。

<?php
$iso8859_1_string
= "\xEB"; // 'ë'(带分音符的 e)在 ISO-8859-1 中
$utf8_string = mb_convert_encoding($iso8859_1_string, 'UTF-8', 'ISO-8859-1');
echo
bin2hex($utf8_string), "\n";

$iso8859_7_string = "\xEB"; // ISO-8859-7 中的相同字符串表示 'λ'(希腊小写 lambda)
$utf8_string = mb_convert_encoding($iso8859_7_string, 'UTF-8', 'ISO-8859-7');
echo
bin2hex($utf8_string), "\n";

$windows_1252_string = "\x80"; // '€'(欧元符号)在 Windows-1252 中,但在 ISO-8859-1 中不存在
$utf8_string = mb_convert_encoding($windows_1252_string, 'UTF-8', 'Windows-1252');
echo
bin2hex($utf8_string), "\n";
?>

以上示例将输出

c3ab
cebb
e282ac

其他可用的选项(取决于安装的扩展)是 UConverter::transcode()iconv()

以下所有操作都产生相同的结果

<?php
$iso8859_1_string
= "\x5A\x6F\xEB"; // 'Zoë' 在 ISO-8859-1 中

$utf8_string = utf8_encode($iso8859_1_string);
echo
bin2hex($utf8_string), "\n";

$utf8_string = mb_convert_encoding($iso8859_1_string, 'UTF-8', 'ISO-8859-1');
echo
bin2hex($utf8_string), "\n";

$utf8_string = UConverter::transcode($iso8859_1_string, 'UTF8', 'ISO-8859-1');
echo
bin2hex($utf8_string), "\n";

$utf8_string = iconv('ISO-8859-1', 'UTF-8', $iso8859_1_string);
echo
bin2hex($utf8_string), "\n";
?>

以上示例将输出

5a6fc3ab
5a6fc3ab
5a6fc3ab
5a6fc3ab

参见

  • utf8_decode() - 将字符串从 UTF-8 转换为 ISO-8859-1,替换无效或无法表示的字符
  • mb_convert_encoding() - 将字符串从一种字符编码转换为另一种字符编码

  • UConverter::transcode() - 将字符串从一种字符编码转换为另一种
  • iconv() - 将字符串从一种字符编码转换为另一种

添加注释

用户贡献的注释 24 条注释

deceze at gmail dot com
13 年前
请注意,utf8_encode 仅将以 ISO-8859-1 编码的字符串转换为 UTF-8。更合适的名称应该是“iso88591_to_utf8”。如果您的文本未以 ISO-8859-1 编码,则不需要此函数。如果您的文本已采用 UTF-8 编码,则不需要此函数。实际上,将此函数应用于未以 ISO-8859-1 编码的文本很可能会使该文本变得乱码。

如果您需要将文本从任何编码转换为任何其他编码,请改用 iconv()。
Aidan Kehoe <php-manual at parhasard dot net>
20 年前
以下是一些代码,解决了 Steven 在上一条评论中描述的问题;

<?php

/* 此结构编码了 ISO-8859-1 和 Windows-1252 之间的差异,
作为从某些 ISO-8859-1 控制字符的 UTF-8 编码到
Windows-1252 在等效代码点处放置的非控制字符的 UTF-8 编码的映射。 */

$cp1252_map = array(
"\xc2\x80" => "\xe2\x82\xac", /* EURO SIGN */
"\xc2\x82" => "\xe2\x80\x9a", /* SINGLE LOW-9 QUOTATION MARK */
"\xc2\x83" => "\xc6\x92", /* LATIN SMALL LETTER F WITH HOOK */
"\xc2\x84" => "\xe2\x80\x9e", /* DOUBLE LOW-9 QUOTATION MARK */
"\xc2\x85" => "\xe2\x80\xa6", /* HORIZONTAL ELLIPSIS */
"\xc2\x86" => "\xe2\x80\xa0", /* DAGGER */
"\xc2\x87" => "\xe2\x80\xa1", /* DOUBLE DAGGER */
"\xc2\x88" => "\xcb\x86", /* MODIFIER LETTER CIRCUMFLEX ACCENT */
"\xc2\x89" => "\xe2\x80\xb0", /* PER MILLE SIGN */
"\xc2\x8a" => "\xc5\xa0", /* LATIN CAPITAL LETTER S WITH CARON */
"\xc2\x8b" => "\xe2\x80\xb9", /* SINGLE LEFT-POINTING ANGLE QUOTATION */
"\xc2\x8c" => "\xc5\x92", /* LATIN CAPITAL LIGATURE OE */
"\xc2\x8e" => "\xc5\xbd", /* LATIN CAPITAL LETTER Z WITH CARON */
"\xc2\x91" => "\xe2\x80\x98", /* LEFT SINGLE QUOTATION MARK */
"\xc2\x92" => "\xe2\x80\x99", /* RIGHT SINGLE QUOTATION MARK */
"\xc2\x93" => "\xe2\x80\x9c", /* LEFT DOUBLE QUOTATION MARK */
"\xc2\x94" => "\xe2\x80\x9d", /* RIGHT DOUBLE QUOTATION MARK */
"\xc2\x95" => "\xe2\x80\xa2", /* BULLET */
"\xc2\x96" => "\xe2\x80\x93", /* EN DASH */
"\xc2\x97" => "\xe2\x80\x94", /* EM DASH */

"\xc2\x98" => "\xcb\x9c", /* SMALL TILDE */
"\xc2\x99" => "\xe2\x84\xa2", /* TRADE MARK SIGN */
"\xc2\x9a" => "\xc5\xa1", /* LATIN SMALL LETTER S WITH CARON */
"\xc2\x9b" => "\xe2\x80\xba", /* SINGLE RIGHT-POINTING ANGLE QUOTATION*/
"\xc2\x9c" => "\xc5\x93", /* LATIN SMALL LIGATURE OE */
"\xc2\x9e" => "\xc5\xbe", /* LATIN SMALL LETTER Z WITH CARON */
"\xc2\x9f" => "\xc5\xb8" /* LATIN CAPITAL LETTER Y WITH DIAERESIS*/
);

function
cp1252_to_utf8($str) {
global
$cp1252_map;
return
strtr(utf8_encode($str), $cp1252_map);
}

?>
Pini
9 年前
我的 utf8_encode_deep 版本,
如果您需要一个不更改原始值的函数。

/**
* 将任何内容转换为 UTF-8
* @param mixed $var 要转换的变量。
* @param boolean $deep 深度转换?(*默认值:TRUE)。
* @return mixed
*/
function anything_to_utf8($var,$deep=TRUE){
if(is_array($var)){
foreach($var as $key => $value){
if($deep){
$var[$key] = anything_to_utf8($value,$deep);
}elseif(!is_array($value) && !is_object($value) && !mb_detect_encoding($value,'utf-8',true)){
$var[$key] = utf8_encode($var);
}
}
return $var;
}elseif(is_object($var)){
foreach($var as $key => $value){
if($deep){
$var->$key = anything_to_utf8($value,$deep);
}elseif(!is_array($value) && !is_object($value) && !mb_detect_encoding($value,'utf-8',true)){
$var->$key = utf8_encode($var);
}
}
return $var;
}else{
return (!mb_detect_encoding($var,'utf-8',true))?utf8_encode($var):$var;
}
}
a dot rueedlinger at gmail dot com
11 年前
如果您需要一个将字符串数组转换为 UTF8 编码的字符串数组的函数,那么此函数可能对您有用

<?php
function utf8_string_array_encode(&$array){
$func = function(&$value,&$key){
if(
is_string($value)){
$value = utf8_encode($value);
}
if(
is_string($key)){
$key = utf8_encode($key);
}
if(
is_array($value)){
utf8_string_array_encode($value);
}
};
array_walk($array,$func);
return
$array;
}
?>
bisqwit at iki dot fi
19 年前
作为参考,指出以下内容可能会有启发性
utf8_encode($s)
实际上等同于
recode_string('latin1..utf8', $s)
以及
iconv('iso-8859-1', 'utf-8', $s)
也就是说,utf8_encode 是字符集转换的一种特殊情况。

如果要转换为 utf-8 的字符串不是 iso-8859-1(例如 iso-8859-2(波兰语/克罗地亚语)),则应使用 recode_string() 或 iconv(),而不是尝试设计复杂的 str_replace 语句。
Oscar Broman
12 年前
遍历嵌套数组/对象并对所有字符串进行 utf8 编码。



<?php
// 用法
class Foo {
public
$somevar = 'whoop whoop';
}

$structure = array(
'object' => (object) array(
'entry' => 'hello wörld',
'another_array' => array(
'string',
1234,
'another string'
)
),
'string' => 'foo',
'foo_object' => new Foo
);

utf8_encode_deep($structure);

// $structure 现在已编码为 utf8
print_r($structure);

// 函数
function utf8_encode_deep(&$input) {
if (
is_string($input)) {
$input = utf8_encode($input);
} else if (
is_array($input)) {
foreach (
$input as &$value) {
utf8_encode_deep($value);
}

unset(
$value);
} else if (
is_object($input)) {
$vars = array_keys(get_object_vars($input));

foreach (
$vars as $var) {
utf8_encode_deep($input->$var);
}
}
}
?>
rocketman
18 年前
如果您正在寻找一个函数来将特殊字符替换为十六进制 UTF-8 值(例如,为了符合 Webservice 安全性/WSS4J 规范),您可以使用此函数

$textstart = "Größe";
$utf8 ='';
$max = strlen($txt);

for ($i = 0; $i < $max; $i++) {

if ($txt{i} == "&"){
$neu = "&x26;";
}
elseif ((ord($txt{$i}) < 32) or (ord($txt{$i}) > 127)){
$neu = urlencode(utf8_encode($txt{$i}));
$neu = preg_replace('#\%(..)\%(..)\%(..)#','&#x\1;&#x\2;&#x\3;',$neu);
$neu = preg_replace('#\%(..)\%(..)#','&#x\1;&#x\2;',$neu);
$neu = preg_replace('#\%(..)#','&#x\1;',$neu);
}
else {
$neu = $txt{$i};
}

$utf8 .= $neu;
} // for $i

$textnew = $utf8;

在此示例中,$textnew 将为 "Gr&#xC3;&#xB6;&#xC3;&#x9F;e"
Janci
19 年前
我一直在搜索一个类似于 Javascript 的 unescape() 函数的函数。在大多数情况下,使用 url_decode() 函数是可以的,但如果您在字符串中包含 UTF 字符则不行。它们会被转换为 url_decode() 无法处理的 %uXXXX 实体。
我在网上搜索并找到一个函数,该函数实际上将这些实体转换为 HTML 实体(&#xxx;),您的浏览器可以正确显示它们。如果您对此感到满意,则可以在此处找到该函数: http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps

但我不满意,因为我需要一个以我的字符集表示的字符串来进行一些比较和其他操作。因此,我修改了上述函数,并结合此处其他注释中提到的 code2utf() 函数,成功实现了我的目标

<?php
/**
* 函数将 Javascript 编码的字符串转换回指定字符集的字符串(默认值为 UTF-8)。
* 从 http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps 修改的函数
*
* @param string $source 使用 Javascript 的 escape() 函数进行编码的字符串
* @param string $iconv_to 目标字符集将用作 iconv 函数的第二个参数。默认值为 UTF-8。
* @return string
*/
function unescape($source, $iconv_to = 'UTF-8') {
$decodedStr = '';
$pos = 0;
$len = strlen ($source);
while (
$pos < $len) {
$charAt = substr ($source, $pos, 1);
if (
$charAt == '%') {
$pos++;
$charAt = substr ($source, $pos, 1);
if (
$charAt == 'u') {
// 我们得到一个 Unicode 字符
$pos++;
$unicodeHexVal = substr ($source, $pos, 4);
$unicode = hexdec ($unicodeHexVal);
$decodedStr .= code2utf($unicode);
$pos += 4;
}
else {
// 我们有一个转义的 ASCII 字符
$hexVal = substr ($source, $pos, 2);
$decodedStr .= chr (hexdec ($hexVal));
$pos += 2;
}
}
else {
$decodedStr .= $charAt;
$pos++;
}
}

if (
$iconv_to != "UTF-8") {
$decodedStr = iconv("UTF-8", $iconv_to, $decodedStr);
}

return
$decodedStr;
}

/**
* 函数将 utf 字符的编号转换为该字符。
* 函数取自: http://sk2.php.net/manual/en/function.utf8-encode.php#49336
*
* @param int $num
* @return utf8char
*/
function code2utf($num){
if(
$num<128)return chr($num);
if(
$num<2048)return chr(($num>>6)+192).chr(($num&63)+128);
if(
$num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
if(
$num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
return
'';
}
?>
rogeriogirodo at gmail dot com
15 年前
此函数可能对编码数组键和值很有用[并首先检查它是否已采用 UTF 格式]

<?php
public static function to_utf8($in)
{
if (
is_array($in)) {
foreach (
$in as $key => $value) {
$out[to_utf8($key)] = to_utf8($value);
}
} elseif(
is_string($in)) {
if(
mb_detect_encoding($in) != "UTF-8")
return
utf8_encode($in);
else
return
$in;
} else {
return
$in;
}
return
$out;
}
?>

希望这能有所帮助。

[由 danbrown AT php DOT net 注:原始函数由 (cmyk777 AT gmail DOT com) 于 2009 年 1 月 28 日编写。]
powtac 4t gmx d0t de
13 年前
我尝试了很多方法,但这似乎是将任何字符串转换为正确的 UTF-8 的最终保险方法。

<?php
function _convert($content) {
if(!
mb_check_encoding($content, 'UTF-8')
OR !(
$content === mb_convert_encoding(mb_convert_encoding($content, 'UTF-32', 'UTF-8' ), 'UTF-8', 'UTF-32'))) {

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

if (
mb_check_encoding($content, 'UTF-8')) {
// log('Converted to UTF-8');
} else {
// log('Could not converted to UTF-8');
}
}
return
$content;
}
?>
匿名用户
19 年前
// 读取文件 story.txt ascii(如在键盘上键入)
// 使用 utf8 编码将其转换为格鲁吉亚字符
// 如果我理解正确(?)就像在格鲁吉亚电脑上键入时一样
// 它将其输出为 html 文件
//
// http://www.comweb.nl/keys_to_georgian.html
// http://www.comweb.nl/keys_to_georgian.php
// http://www.comweb.nl/story.txt

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<HTML>
<HEAD>
<TITLE>键入 Unicode 代码</TITLE>

// 此元标记是必需的
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >

// 请注意,sylfean 字体似乎是 Windows XP 上的标准安装字体
// 它支持格鲁吉亚语

<style TYPE="text/css">
<!--
body {font-family:sylfaen; }
-->
</style>
</HEAD>

<BODY>

<?
$eng=array(97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,87,82,84,83,
67,74,90);
$geo=array(4304,4305,4330,4307,4308,4324,4306,4336,4312,4335,4313,
4314,4315,4316,4317,4318,4325,4320,4321,4322,4323,4309,
4332,4334,4327,4310,4333,4326,4311,4328,4329,4319,4331,
91,93,59,39,44,46,96);

$fc=file("story.txt");
foreach($fc as $line)
{
$spacestart=1;
for ($i=0; $i<strlen($line); $i+=1)
{
$character=ord(substr($line,$i,1));
$found=0;
for ($k=0; $k<count($eng); $k+=1)
{
if ($eng[$k]==$character)
{
print code2utf( $geo[$k] );
$found=1;
}
}
if ($found==0)
{
if ($character==126 || $character==32 || $character==10 || $character==9)
{
if ($character==9) { print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'; }
if ($character==10) { print "<BR>\n"; }
if ($character==32)
{
if ($spacestart==1) {print '&nbsp;'; } else { print " "; }
}
if ($character==126){ print "~"; }
} else
{
print substr($line,$i,1);
}
}
if ($character!=32) { $spacestart=0; }
}
}

/**
* 函数将 utf 字符的数字转换为该字符。
* 函数取自:http://sk2.php.net/manual/en/function.utf8-encode.php#49336
*
* @param int $num
* @return utf8char
*/
function code2utf($num)
{
if($num<128)return chr($num);
if($num<2048)return chr(($num>>6)+192).chr(($num&63)+128);
if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
return '';
}
?>

</BODY>
</HTML>
hrpeters (at) gmx (dot) net
19 年前
// 验证 Unicode UTF-8 版本 4
// 此函数参考了 http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf 中的表 3.6
// 它还将过长的字节标记为错误

function is_validUTF8($str)
{
// -1 的值表示当前 UTF-8 中第一个字节的禁用值
static $trailing_bytes = array (
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
);

$ups = unpack('C*', $str);
if (!($aCnt = count($ups))) return true; // 空字符串 *是* 有效的 UTF-8
for ($i = 1; $i <= $aCnt;)
{
if (!($tbytes = $trailing_bytes[($b1 = $ups[$i++])])) continue;
if ($tbytes == -1) return false;

$first = true;
while ($tbytes > 0 && $i <= $aCnt)
{
$cbyte = $ups[$i++];
if (($cbyte & 0xC0) != 0x80) return false;

if ($first)
{
switch ($b1)
{
case 0xE0
if ($cbyte < 0xA0) return false;
break;
case 0xED
if ($cbyte > 0x9F) return false;
break;
case 0xF0
if ($cbyte < 0x90) return false;
break;
case 0xF4
if ($cbyte > 0x8F) return false;
break;
default
break;
}
$first = false;
}
$tbytes--;
}
if ($tbytes) return false; // EOS 处的序列不完整
}
return true;
}
Mark AT modernbill DOT com
20 年前
如果您还没有猜到:如果 UTF-8 字符在 ISO-8859-1 代码页中没有表示形式,则将返回“?”。您可能希望围绕此函数包装一个函数,以确保您不会将一堆“????”保存到数据库中。
www.tricinty.com
16 年前
<?php
/**
* 将 ISO-8859-1 混合变量编码为 UTF-8(PHP 4、PHP 5 兼容)
* @param mixed $input 数组,关联或简单
* @param boolean $encode_keys 可选
* @return mixed(utf-8 编码的 $input)
*/

function utf8_encode_mix($input, $encode_keys=false)
{
if(
is_array($input))
{
$result = array();
foreach(
$input as $k => $v)
{
$key = ($encode_keys)? utf8_encode($k) : $k;
$result[$key] = utf8_encode_mix( $v, $encode_keys);
}
}
else
{
$result = utf8_encode($input);
}

return
$result;
}
?>
mailing at jcn50 dot com
18 年前
我建议对每种语言都使用此替代方案

$new=mb_convert_encoding($s,"UTF-8","auto");

不要忘记将所有页面设置为“utf-8”编码,否则只需使用 HTML 实体。

jcn50。
Yumok
14 年前
避免使用 preg_match 来检测是否需要 utf8_encode



<?php
$string
= $string_input; // 避免破坏性操作

$string = preg_replace("#[\x09\x0A\x0D\x20-\x7E]#" ,"",$string); // ASCII
$string = preg_replace("#[\xC2-\xDF][\x80-\xBF]#" ,"",$string); // 非超长2字节
$string = preg_replace("#\xE0[\xA0-\xBF][\x80-\xBF]#" ,"",$string); // 排除超长字符
$string = preg_replace("#[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}#","",$string); // 直接3字节
$string = preg_replace("#\xED[\x80-\x9F][\x80-\xBF]#" ,"",$string); // 排除代理项
$string = preg_replace("#\xF0[\x90-\xBF][\x80-\xBF]{2}#","",$string); // 平面1-3
$string = preg_replace("#[\xF1-\xF3][\x80-\xBF]{3}#" ,"",$string); // 平面4-15
$string = preg_replace("#\xF4[\x80-\x8F][\x80-\xBF]{2}#","",$string); // 平面16

$rc = ($string == ""?true:false);
?>
[email protected]
19 年前
此函数用于将泰语字体(iso-8859-11)转换为UTF-8。在我的案例中,它运行良好。如果您在将字符集iso-8859-11转换为UTF-8时遇到问题,请尝试使用此函数。

函数 iso8859_11toUTF8($string) {

如果 ( ! ereg("[\241-\377]", $string) )
返回 $string;

$iso8859_11 = 数组(
"\xa1" => "\xe0\xb8\x81",
"\xa2" => "\xe0\xb8\x82",
"\xa3" => "\xe0\xb8\x83",
"\xa4" => "\xe0\xb8\x84",
"\xa5" => "\xe0\xb8\x85",
"\xa6" => "\xe0\xb8\x86",
"\xa7" => "\xe0\xb8\x87",
"\xa8" => "\xe0\xb8\x88",
"\xa9" => "\xe0\xb8\x89",
"\xaa" => "\xe0\xb8\x8a",
"\xab" => "\xe0\xb8\x8b",
"\xac" => "\xe0\xb8\x8c",
"\xad" => "\xe0\xb8\x8d",
"\xae" => "\xe0\xb8\x8e",
"\xaf" => "\xe0\xb8\x8f",
"\xb0" => "\xe0\xb8\x90",
"\xb1" => "\xe0\xb8\x91",
"\xb2" => "\xe0\xb8\x92",
"\xb3" => "\xe0\xb8\x93",
"\xb4" => "\xe0\xb8\x94",
"\xb5" => "\xe0\xb8\x95",
"\xb6" => "\xe0\xb8\x96",
"\xb7" => "\xe0\xb8\x97",
"\xb8" => "\xe0\xb8\x98",
"\xb9" => "\xe0\xb8\x99",
"\xba" => "\xe0\xb8\x9a",
"\xbb" => "\xe0\xb8\x9b",
"\xbc" => "\xe0\xb8\x9c",
"\xbd" => "\xe0\xb8\x9d",
"\xbe" => "\xe0\xb8\x9e",
"\xbf" => "\xe0\xb8\x9f",
"\xc0" => "\xe0\xb8\xa0",
"\xc1" => "\xe0\xb8\xa1",
"\xc2" => "\xe0\xb8\xa2",
"\xc3" => "\xe0\xb8\xa3",
"\xc4" => "\xe0\xb8\xa4",
"\xc5" => "\xe0\xb8\xa5",
"\xc6" => "\xe0\xb8\xa6",
"\xc7" => "\xe0\xb8\xa7",
"\xc8" => "\xe0\xb8\xa8",
"\xc9" => "\xe0\xb8\xa9",
"\xca" => "\xe0\xb8\xaa",
"\xcb" => "\xe0\xb8\xab",
"\xcc" => "\xe0\xb8\xac",
"\xcd" => "\xe0\xb8\xad",
"\xce" => "\xe0\xb8\xae",
"\xcf" => "\xe0\xb8\xaf",
"\xd0" => "\xe0\xb8\xb0",
"\xd1" => "\xe0\xb8\xb1",
"\xd2" => "\xe0\xb8\xb2",
"\xd3" => "\xe0\xb8\xb3",
"\xd4" => "\xe0\xb8\xb4",
"\xd5" => "\xe0\xb8\xb5",
"\xd6" => "\xe0\xb8\xb6",
"\xd7" => "\xe0\xb8\xb7",
"\xd8" => "\xe0\xb8\xb8",
"\xd9" => "\xe0\xb8\xb9",
"\xda" => "\xe0\xb8\xba",
"\xdf" => "\xe0\xb8\xbf",
"\xe0" => "\xe0\xb9\x80",
"\xe1" => "\xe0\xb9\x81",
"\xe2" => "\xe0\xb9\x82",
"\xe3" => "\xe0\xb9\x83",
"\xe4" => "\xe0\xb9\x84",
"\xe5" => "\xe0\xb9\x85",
"\xe6" => "\xe0\xb9\x86",
"\xe7" => "\xe0\xb9\x87",
"\xe8" => "\xe0\xb9\x88",
"\xe9" => "\xe0\xb9\x89",
"\xea" => "\xe0\xb9\x8a",
"\xeb" => "\xe0\xb9\x8b",
"\xec" => "\xe0\xb9\x8c",
"\xed" => "\xe0\xb9\x8d",
"\xee" => "\xe0\xb9\x8e",
"\xef" => "\xe0\xb9\x8f",
"\xf0" => "\xe0\xb9\x90",
"\xf1" => "\xe0\xb9\x91",
"\xf2" => "\xe0\xb9\x92",
"\xf3" => "\xe0\xb9\x93",
"\xf4" => "\xe0\xb9\x94",
"\xf5" => "\xe0\xb9\x95",
"\xf6" => "\xe0\xb9\x96",
"\xf7" => "\xe0\xb9\x97",
"\xf8" => "\xe0\xb9\x98",
"\xf9" => "\xe0\xb9\x99",
"\xfa" => "\xe0\xb9\x9a",
"\xfb" => "\xe0\xb9\x9b"
);

$string=strtr($string,$iso8859_11);
返回 $string;
}

Suttichai Mesaard - www.ceforce.com
[email protected]
17年前
/*
到目前为止看到的每个函数都不完整或消耗资源。这里有两个——整数到utf序列(i3u)和utf序列到整数(u3i)。以下是一个代码片段,它在范围边界处检查良好的行为。

总有一天它们可能会被硬编码到PHP中……
*/

函数 i3u($i) { // 从整数返回UCS-16或UCS-32到UTF-8
$i=(int)$i; // 整数?
如果 ($i<0) 返回 false; // 正数?
如果 ($i<=0x7f) 返回 chr($i); // 范围0
如果 (($i & 0x7fffffff) <> $i) 返回 '?'; // 31位?
如果 ($i<=0x7ff) 返回 chr(0xc0 | ($i >> 6)) . chr(0x80 | ($i & 0x3f));
如果 ($i<=0xffff) 返回 chr(0xe0 | ($i >> 12)) . chr(0x80 | ($i >> 6) & 0x3f)
. chr(0x80 | $i & 0x3f);
如果 ($i<=0x1fffff) 返回 chr(0xf0 | ($i >> 18)) . chr(0x80 | ($i >> 12) & 0x3f)
. chr(0x80 | ($i >> 6) & 0x3f) . chr(0x80 | $i & 0x3f);
如果 ($i<=0x3ffffff) 返回 chr(0xf8 | ($i >> 24)) . chr(0x80 | ($i >> 18) & 0x3f)
. chr(0x80 | ($i >> 12) & 0x3f) . chr(0x80 | ($i >> 6) & 0x3f) . chr(0x80 | $i & 0x3f);
返回 chr(0xfc | ($i >> 30)) . chr(0x80 | ($i >> 24) & 0x3f) . chr(0x80 | ($i >> 18) & 0x3f)
. chr(0x80 | ($i >> 12) & 0x3f) . chr(0x80 | ($i >> 6) & 0x3f) . chr(0x80 | $i & 0x3f);
}

函数 u3i($s,$strict=1) { // 在有效的UTF-8序列上返回整数,在空时返回NULL,否则返回FALSE
// 非严格:仅获取数据位,存在或不存在;严格:长度和位检查
如果 ($s=='') 返回 NULL;
$l=strlen($s); $o=ord($s{0});
如果 ($o <= 0x7f && $l==1) 返回 $o;
如果 ($l>6 && $strict) 返回 false;
如果 ($strict) 对于 ($i=1;$i<$l;$i++) 如果 (ord($s{$i}) > 0xbf || ord($s{$i})< 0x80) 返回 false;
如果 ($o < 0xc2) 返回 false; // 无论strict是否为0,都不可行
如果 ($o <= 0xdf && ($l=2 && $strict)) 返回 (($o & 0x1f) << 6 | (ord($s{1}) & 0x3f));
如果 ($o <= 0xef && ($l=3 && $strict)) 返回 (($o & 0x0f) << 12 | (ord($s{1}) & 0x3f) << 6
| (ord($s{2}) & 0x3f));
如果 ($o <= 0xf7 && ($l=4 && $strict)) 返回 (($o & 0x07) << 18 | (ord($s{1}) & 0x3f) << 12
| (ord($s{2}) & 0x3f) << 6 | (ord($s{3}) & 0x3f));
如果 ($o <= 0xfb && ($l=5 && $strict)) 返回 (($o & 0x03) << 24 | (ord($s{1}) & 0x3f) << 18
| (ord($s{2}) & 0x3f) << 12 | (ord($s{3}) & 0x3f) << 6 | (ord($s{4}) & 0x3f));
如果 ($o <= 0xfd && ($l=6 && $strict)) 返回 (($o & 0x01) << 30 | (ord($s{1}) & 0x3f) << 24
| (ord($s{2}) & 0x3f) << 18 | (ord($s{3}) & 0x3f) << 12
| (ord($s{4}) & 0x3f) << 6 | (ord($s{5}) & 0x3f));
返回 false;
}

// 边界行为检查
$do=数组(0x7f,0x7ff,0xffff,0x1fffff,0x3ffffff,0x7fffffff);
foreach ($do as $ii) 对于 ($i=$ii;$i<=$ii+1; $i++) {
$o=i3u($i);
对于 ($j=0;$j<strlen($o);$j++) 打印 "O[$j]=" . sprintf('%08b',ord($o{$j})) . ", ";
打印 "c=$i, o=[$o].\n";
打印 "返回: [$o] => [" . u3i($o) . "]\n";
}
[email protected]
3年前
/**
* 将数组的所有值转换为utf8_encode
* @author Marcelo Ratton
* @version 1.0
*
* @param 数组 $arr 要编码值的数组
* @param 布尔 $keys 是否将键转换为UTF8
* @return 数组 与之前相同的数组,但所有值都已编码为UTF8
*/
函数 arrayEncodeToUTF8(数组 $arr, 布尔 $keys= false) : 数组 {
$ret= [];
foreach ($arr as $k=>$v) {
如果 (is_array($v)) {
$ret[$k]= arrayEncodeToUTF8($v);
} 否则 {
如果 ($keys) {
$k= utf8_encode((字符串)$k);
}
$ret[$k]= utf8_encode((字符串)$v);
}
}

返回 $ret;
}
[email protected]
22年前
以下函数将使用utf-8编码unicode实体&#nnn(nn);,其中n={0..9}

/**
* 获取unicode实体字符串并将其转换为utf-8编码的字符串
* 每个unicode实体都具有形式&#nnn(nn); n={0..9},并且可以通过支持utf-8的
* 浏览器显示。ASCII字符将不会被修改。
* @param $source unicode实体字符串 [字符串]
* @return utf-8编码的字符串 [字符串]
* @access 公共
*/
函数 utf8Encode ($source) {
$utf8Str = '';
$entityArray = explode ("&#", $source);
$size = count ($entityArray);
对于 ($i = 0; $i < $size; $i++) {
$subStr = $entityArray[$i];
$nonEntity = strstr ($subStr, ';');
如果 ($nonEntity !== false) {
$unicode = intval (substr ($subStr, 0, (strpos ($subStr, ';') + 1)));
// 确定表示此unicode字符需要多少个字符
如果 ($unicode < 128) {
$utf8Substring = chr ($unicode);
}
否则如果 ($unicode >= 128 && $unicode < 2048) {
$binVal = str_pad (decbin ($unicode), 11, "0", STR_PAD_LEFT);
$binPart1 = substr ($binVal, 0, 5);
$binPart2 = substr ($binVal, 5);

$char1 = chr (192 + bindec ($binPart1));
$char2 = chr (128 + bindec ($binPart2));
$utf8Substring = $char1 . $char2;
}
否则如果 ($unicode >= 2048 && $unicode < 65536) {
$binVal = str_pad (decbin ($unicode), 16, "0", STR_PAD_LEFT);
$binPart1 = substr ($binVal, 0, 4);
$binPart2 = substr ($binVal, 4, 6);
$binPart3 = substr ($binVal, 10);

$char1 = chr (224 + bindec ($binPart1));
$char2 = chr (128 + bindec ($binPart2));
$char3 = chr (128 + bindec ($binPart3));
$utf8Substring = $char1 . $char2 . $char3;
}
else {
$binVal = str_pad (decbin ($unicode), 21, "0", STR_PAD_LEFT);
$binPart1 = substr ($binVal, 0, 3);
$binPart2 = substr ($binVal, 3, 6);
$binPart3 = substr ($binVal, 9, 6);
$binPart4 = substr ($binVal, 15);

$char1 = chr (240 + bindec ($binPart1));
$char2 = chr (128 + bindec ($binPart2));
$char3 = chr (128 + bindec ($binPart3));
$char4 = chr (128 + bindec ($binPart4));
$utf8Substring = $char1 . $char2 . $char3 . $char4;
}

如果 (strlen ($nonEntity) > 1)
$nonEntity = substr ($nonEntity, 1); // 去掉第一个字符 (';')
否则
$nonEntity = '';

$utf8Str .= $utf8Substring . $nonEntity;
}
else {
$utf8Str .= $subStr;
}
}

返回 $utf8Str;
}

罗宁。
凯伦
21 年前
关于之前关于将 GB2312 代码转换为 Unicode 代码的帖子,其中显示了以下函数

<?
// 程序作者:sadly (www.phpx.com)

函数 gb2unicode($gb)
{
如果(!trim($gb))
返回 $gb;
$filename="gb2312.txt";
$tmp=file($filename);
$codetable=array();
当 (list($key,$value)=each($tmp))
$codetable[hexdec(substr($value,0,6))]=substr($value,9,4);
$utf="";
当 ($gb)
{
如果 (ord(substr($gb,0,1))>127)
{
$this=substr($gb,0,2);
$gb=substr($gb,2,strlen($gb));
$utf.="&#x".$codetable[hexdec(bin2hex($this))-0x8080].";";
}
否则
{
$gb=substr($gb,1,strlen($gb));
$utf.=substr($gb,0,1);
}
}
返回 $utf;
}
?>

我发现代码中需要进行一个小小的更改才能正确处理嵌入在 GB2312 文本中间的拉丁字符,例如当文本包含 URL 或电子邮件地址时。只需反转上面处理 ord 值!>127 的语句部分中的这两行。

更改

$gb=substr($gb,1,strlen($gb));
$utf.=substr($gb,0,1);



$utf.=substr($gb,0,1);
$gb=substr($gb,1,strlen($gb));

在原始函数中,第一个拉丁字符被删除,并且它没有转换拉丁文本后的第一个非拉丁字符(所有内容都向右移动了一个字符)。反转这两行使它在我的所有测试示例中都能正常工作。

此外,此功能所需的 gb2312.txt 文件的来源已更改。您可以在几个地方找到它

http://tcl.apache.org/sources/tcl/tools/encoding/gb2312.txt
ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/GB/GB2312.TXT
网络乌鸦
20 年前
我经常需要将发送给我的多语言文本转换为 UTF8 编码,以便将其插入源代码和数据库中以供网站和其他应用程序使用。

我制作了一个小型网页,其字符集设置为 UTF8,然后对其进行设置,以便我可以从原始文档(例如 Word 或 Excel)粘贴,并让页面返回 UTF8 编码版本。

当然,浏览器会将 unicode 转换为 UTF8 作为提交的一部分(我为此使用 IE5 或更高版本),然后您只需在 PHP 中对 UTF8 进行编码,浏览器就会以其原始形式显示它。

它有点笨拙,但我只是将所有字符转换为 html 数字实体(蛮力与无知再次奏效)。

我已经使用它对从希伯来语到日语的所有内容进行编码,没有任何问题

<?
header("Content-Type: text/plain; charset=utf-8");
$code = (get_magic_quotes_gpc())?stripslashes($GLOBALS[code]):$GLOBALS[code];
?>
<html>
<head>
<title>UTF8 编码页面</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<form method=post action="?seed=<?=time()?>">
原始 Unicode<br />
<textarea name="code" cols="80" rows="10"><?=$code?></textarea><br />
编码后的 UTF8<br />
<textarea name="encd" cols="80" rows="10"><?
对于 ($i = 0; $i < strlen($code); $i++) {
echo '&#'.ord(substr($code,$i,1));
}
?></textarea><br />
<input type="submit" value="编码">
</form>
</body>
</html>
艾伦
1 年前
我想从 PHP 8.2 开始,我们需要使用 <?php iconv('ISO-8859-1', 'UTF-8', $string) ?> 来代替。
JF 塞巴斯蒂安
19 年前
以下 Perl 正则表达式测试字符串是否为格式良好的 Unicode UTF-8(在每个 | 后中断,因为此处不允许使用长行。请在使用前将其连接为一行,无空格。)

^([\x00-\x7f]|
[\xc2-\xdf][\x80-\xbf]|
\xe0[\xa0-\xbf][\x80-\xbf]|
[\xe1-\xec][\x80-\xbf]{2}|
\xed[\x80-\x9f][\x80-\xbf]|
[\xee-\xef][\x80-\xbf]{2}|
f0[\x90-\xbf][\x80-\xbf]{2}|
[\xf1-\xf3][\x80-\xbf]{3}|
\xf4[\x80-\x8f][\x80-\xbf]{2})*$

注意:这严格遵循 Unicode 标准 4.0,如第 3.9 章、表 3-6“格式良好的 UTF-8 字节序列”中所述(http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G31703)。

ISO-10646(Unicode 的超集)使用 UTF-8(在那里称为“UCS”,请参阅http://www.unicode.org/faq/utf_bom.html#1)在一个宽松的变体中,该变体支持编码为最多六个字节的 31 位空间,而不是 Unicode 的最多四个字节的 21 位。要检查 ISO-10646 UTF-8,请使用以下 Perl 正则表达式(同样,已分解,请参见上文)

^([\x00-\x7f]|
[\xc0-\xdf][\x80-\xbf]|
[\xe0-\xef][\x80-\xbf]{2}|
[\xf0-\xf7][\x80-\xbf]{3}|
[\xf8-\xfb][\x80-\xbf]{4}|
[\xfc-\xfd][\x80-\xbf]{5})*$

以下函数可与上述表达式一起用于快速 UTF-8 测试,例如,如果从 <form accept-charset="utf-8,iso-8859-1" method=..> 提交,则区分 ISO-8859-1 数据与 UTF-8 数据。

函数 is_utf8($string) {
返回 (preg_match('/[在此处插入正则表达式]/', $string) === 1);
}
To Top