请注意,utf8_encode 仅将以 ISO-8859-1 编码的字符串转换为 UTF-8。它更合适的名称应该是“iso88591_to_utf8”。如果您的文本不是以 ISO-8859-1 编码的,则不需要此函数。如果您的文本已经是 UTF-8,则不需要此函数。实际上,将此函数应用于不是以 ISO-8859-1 编码的文本很可能会简单地使该文本乱码。
如果您需要将文本从任何编码转换为任何其他编码,请查看 iconv()。
(PHP 4, PHP 5, PHP 7, PHP 8)
utf8_encode — 将字符串从 ISO-8859-1 转换为 UTF-8
此函数自 PHP 8.2.0 起已弃用。强烈建议不要依赖此函数。
此函数将字符串 string
从 ISO-8859-1
编码转换为 UTF-8
。
注意:
此函数不尝试猜测提供的字符串的当前编码,它假定它被编码为 ISO-8859-1(也称为“Latin 1”)并转换为 UTF-8。由于每个字节序列都是有效的 ISO-8859-1 字符串,因此这永远不会导致错误,但如果打算使用其他编码,则不会产生有用的字符串。
许多标记为使用
ISO-8859-1
字符编码的网页实际上使用类似的Windows-1252
编码,Web 浏览器将解释ISO-8859-1
网页为Windows-1252
。Windows-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"; // ISO-8859-1 中的 'ë'(带分音符的 e)
$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"; // ISO-8859-1 中的 'Zoë'
$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_encode 仅将以 ISO-8859-1 编码的字符串转换为 UTF-8。它更合适的名称应该是“iso88591_to_utf8”。如果您的文本不是以 ISO-8859-1 编码的,则不需要此函数。如果您的文本已经是 UTF-8,则不需要此函数。实际上,将此函数应用于不是以 ISO-8859-1 编码的文本很可能会简单地使该文本乱码。
如果您需要将文本从任何编码转换为任何其他编码,请查看 iconv()。
以下代码解决了 Steven 在上条评论中描述的问题;
<?php
/* 此结构编码了 ISO-8859-1 和 Windows-1252 之间的差异,
作为从一些 ISO-8859-1 控制字符的 UTF-8 编码到
Windows-1252 在等效代码点处放置的非控制字符的 UTF-8 编码的映射。 */
$cp1252_map = array(
"\xc2\x80" => "\xe2\x82\xac", /* 欧元符号 */
"\xc2\x82" => "\xe2\x80\x9a", /* 单个低 9 引号 */
"\xc2\x83" => "\xc6\x92", /* 拉丁小写字母 f 带钩 */
"\xc2\x84" => "\xe2\x80\x9e", /* 双低 9 引号 */
"\xc2\x85" => "\xe2\x80\xa6", /* 水平省略号 */
"\xc2\x86" => "\xe2\x80\xa0", /* 剑号 */
"\xc2\x87" => "\xe2\x80\xa1", /* 双剑号 */
"\xc2\x88" => "\xcb\x86", /* 修饰字母尖音符 */
"\xc2\x89" => "\xe2\x80\xb0", /* 千分号 */
"\xc2\x8a" => "\xc5\xa0", /* 拉丁大写字母 S 带抑扬音 */
"\xc2\x8b" => "\xe2\x80\xb9", /* 单个左指向的角度引号 */
"\xc2\x8c" => "\xc5\x92", /* 拉丁大写字母连字符 OE */
"\xc2\x8e" => "\xc5\xbd", /* 拉丁大写字母 Z 带抑扬音 */
"\xc2\x91" => "\xe2\x80\x98", /* 左单引号 */
"\xc2\x92" => "\xe2\x80\x99", /* 右单引号 */
"\xc2\x93" => "\xe2\x80\x9c", /* 左双引号 */
"\xc2\x94" => "\xe2\x80\x9d", /* 右双引号 */
"\xc2\x95" => "\xe2\x80\xa2", /* 项目符号 */
"\xc2\x96" => "\xe2\x80\x93", /* 短破折号 */
"\xc2\x97" => "\xe2\x80\x94", /* 长破折号 */
"\xc2\x98" => "\xcb\x9c", /* 小波浪号 */
"\xc2\x99" => "\xe2\x84\xa2", /* 商标符号 */
"\xc2\x9a" => "\xc5\xa1", /* 拉丁小写字母 S 带抑扬音 */
"\xc2\x9b" => "\xe2\x80\xba", /* 单个右指向的角度引号 */
"\xc2\x9c" => "\xc5\x93", /* 拉丁小写字母连字符 OE */
"\xc2\x9e" => "\xc5\xbe", /* 拉丁小写字母 Z 带抑扬音 */
"\xc2\x9f" => "\xc5\xb8" /* 拉丁大写字母 Y 带分音符 */
);
function cp1252_to_utf8($str) {
global $cp1252_map;
return strtr(utf8_encode($str), $cp1252_map);
}
?>
我的 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;
}
}
如果你需要一个函数将字符串数组转换为 UTF-8 编码的字符串数组,那么这个函数可能对你有用
<?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;
}
?>
作为参考,指出以下内容可能具有启发性
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 语句。
遍历嵌套的数组/对象,并将所有字符串编码为 UTF-8。
<?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 现在是 UTF-8 编码的
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);
}
}
}
?>
如果你正在寻找一个函数将特殊字符替换为十六进制 UTF-8 值(例如,用于 Web 服务安全/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öße"
我一直在寻找一个类似于 Javascript 的 unescape() 函数。 在大多数情况下,使用 url_decode() 函数是可以的,但如果你在字符串中包含 UTF 字符,则不行。 它们会被转换为 url_decode() 无法处理的 %uXXXX 实体。
我在网上搜索,找到了一个函数,它实际上将这些实体转换为浏览器可以正确显示的 HTML 实体 (&#xxx;)。 如果你可以接受,这个函数可以在以下链接找到: http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
但这对我来说并不合适,因为我需要一个在我指定的字符集中的字符串,以便进行一些比较和其他操作。 所以我修改了上面的函数,并结合了其他一些笔记中提到的 code2utf() 函数,最终实现了我的目标。
<?php
/**
* 该函数将一个用 Javascript 的 escape() 函数转义的字符串转换回一个具有指定字符集的字符串(默认值为 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 '';
}
?>
此函数可能对编码数组键和值 [并首先检查是否已在 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;
}
?>
希望这能有所帮助。
[注意:原始函数由 (cmyk777 AT gmail DOT com) 于 2009 年 1 月 28 日编写。]
我尝试了很多方法,但这似乎是将任何字符串转换为正确 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;
}
?>
// 读取一个名为 story.txt 的 ASCII 文件(与键盘上的输入相同)
// 使用 UTF-8 编码将其转换为格鲁吉亚字符
// 如果我没有理解错的话(?),这应该是在格鲁吉亚电脑上输入时呈现的效果
// 它将以 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>keys to unicode code</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 ' '; }
if ($character==10) { print "<BR>\n"; }
if ($character==32)
{
if ($spacestart==1) {print ' '; } 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);
如果 ($num < 2097152) 返回 chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
返回 '';
}
?>
</BODY>
</HTML>
// 验证 Unicode UTF-8 版本 4
// 此函数以 http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf 中的表格 3.6 为参考
// 它还将过长的字节标记为错误
函数 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);
如果 (!($aCnt = count($ups))) 返回 true; // 空字符串 *是* 有效的 UTF-8
对于 ($i = 1; $i <= $aCnt;)
{
如果 (!($tbytes = $trailing_bytes[($b1 = $ups[$i++])])) 继续;
如果 ($tbytes == -1) 返回 false;
$first = true;
当 ($tbytes > 0 && $i <= $aCnt)
{
$cbyte = $ups[$i++];
如果 (($cbyte & 0xC0) != 0x80) 返回 false;
如果 ($first)
{
根据 $b1 的值
{
case 0xE0
如果 ($cbyte < 0xA0) 返回 false;
跳过;
case 0xED
如果 ($cbyte > 0x9F) 返回 false;
跳过;
case 0xF0
如果 ($cbyte < 0x90) 返回 false;
跳过;
case 0xF4
如果 ($cbyte > 0x8F) 返回 false;
跳过;
默认
跳过;
}
$first = false;
}
$tbytes--;
}
如果 ($tbytes) 返回 false; // EOS 处的序列不完整
}
返回 true;
}
如果您还没有猜到:如果 UTF-8 字符在 ISO-8859-1 代码页中没有表示,则将返回 ?。您可能希望在此函数周围包装一个函数,以确保您不会将一大堆 ???? 保存到您的数据库中。
<?php
/**
* 将 ISO-8859-1 混合变量编码为 UTF-8 (PHP 4, PHP 5 兼容)
* @param mixed $input 数组,关联或简单
* @param boolean $encode_keys 可选
* @return mixed (UTF-8 编码的 $input)
*/
函数 utf8_encode_mix($input, $encode_keys=false)
{
如果(is_array($input))
{
$result = array();
对于($input 为 $k => $v)
{
$key = ($encode_keys)? utf8_encode($k) : $k;
$result[$key] = utf8_encode_mix( $v, $encode_keys);
}
}
否则
{
$result = utf8_encode($input);
}
返回 $result;
}
?>
我建议对每种语言使用此替代方法
$new=mb_convert_encoding($s,"UTF-8","auto");
不要忘记将所有页面设置为“utf-8”编码,否则只使用 HTML 实体。
jcn50。
避免使用 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);
?>
我使用此函数将泰语字体 (iso-8859-11) 转换为 UTF-8。就我而言,它能正常工作。如果您在将字符集 iso-8859-11 转换为 UTF-8 时遇到问题,请尝试使用此函数。
函数 iso8859_11toUTF8($string) {
如果 ( ! ereg("[\241-\377]", $string) )
返回 $string;
$iso8859_11 = array(
"\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
/*
迄今为止看到的每个函数都不完整或资源消耗过大。这里有两个——整数到 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
// 非严格:只取 DATA 位,存在或不存在;严格:长度和位检查
如果 ($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=array(0x7f,0x7ff,0xffff,0x1fffff,0x3ffffff,0x7fffffff);
foreach ($do as $ii) for ($i=$ii;$i<=$ii+1; $i++) {
$o=i3u($i);
for ($j=0;$j<strlen($o);$j++) print "O[$j]=" . sprintf('%08b',ord($o{$j})) . ", ";
print "c=$i, o=[$o].\n";
print "Back: [$o] => [" . u3i($o) . "]\n";
}
/**
* 将数组的所有值转换为 utf8_encode
* @author Marcelo Ratton
* @version 1.0
*
* @param array $arr 要编码值的数组
* @param bool $keys true 表示将键转换为 UTF8
* @return array 相同的数组,但所有值都编码为 UTF8
*/
function arrayEncodeToUTF8(array $arr, bool $keys= false) : array {
$ret= [];
foreach ($arr as $k=>$v) {
if (is_array($v)) {
$ret[$k]= arrayEncodeToUTF8($v);
} else {
if ($keys) {
$k= utf8_encode((string)$k);
}
$ret[$k]= utf8_encode((string)$v);
}
}
return $ret;
}
以下函数将 utf-8 编码 unicode 实体 &#nnn(nn); 其中 n={0..9}
/**
* 接受 unicode 实体字符串并将其转换为 utf-8 编码字符串
* 每个 unicode 实体都有 &#nnn(nn); n={0..9} 的形式,可以由支持 utf-8 的
* 浏览器显示。Ascii 将不会被修改。
* @param $source unicode 实体字符串 [STRING]
* @return utf-8 编码字符串 [STRING]
* @access public
*/
function utf8Encode ($source) {
$utf8Str = '';
$entityArray = explode ("&#", $source);
$size = count ($entityArray);
for ($i = 0; $i < $size; $i++) {
$subStr = $entityArray[$i];
$nonEntity = strstr ($subStr, ';');
if ($nonEntity !== false) {
$unicode = intval (substr ($subStr, 0, (strpos ($subStr, ';') + 1)));
// 确定表示此 unicode 字符需要多少个字符
if ($unicode < 128) {
$utf8Substring = chr ($unicode);
}
else if ($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;
}
else if ($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;
}
if (strlen ($nonEntity) > 1)
$nonEntity = substr ($nonEntity, 1); // 砍掉第一个字符 (';')
else
$nonEntity = '';
$utf8Str .= $utf8Substring . $nonEntity;
}
else {
$utf8Str .= $subStr;
}
}
return $utf8Str;
}
Ronen.
关于之前关于将 GB2312 代码转换为 Unicode 代码的帖子,该帖子显示了以下函数
<?
// 由 sadly (www.phpx.com) 编写的程序
function gb2unicode($gb)
{
if(!trim($gb))
return $gb;
$filename="gb2312.txt";
$tmp=file($filename);
$codetable=array();
while(list($key,$value)=each($tmp))
$codetable[hexdec(substr($value,0,6))]=substr($value,9,4);
$utf="";
while($gb)
{
if (ord(substr($gb,0,1))>127)
{
$this=substr($gb,0,2);
$gb=substr($gb,2,strlen($gb));
$utf.="&#x".$codetable[hexdec(bin2hex($this))-0x8080].";";
}
else
{
$gb=substr($gb,1,strlen($gb));
$utf.=substr($gb,0,1);
}
}
return $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
我经常需要将发送给我的多语言文本转换为 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 ENCODER PAGE</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"><?
for ($i = 0; $i < strlen($code); $i++) {
echo '&#'.ord(substr($code,$i,1));
}
?></textarea><br />
<input type="submit" value="encode">
</form>
</body>
</html>
以下 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 数据。
function is_utf8($string) {
return (preg_match('/[插入正则表达式此处]/', $string) === 1);
}