分享
 
 
 

UTF8下的中文PHP编程

王朝php·作者佚名  2008-05-30
窄屏简体版  字體: |||超大  

前言:

说实话,

凉鞋也觉得 UTF8 是好东西……

毕竟同屏显示中日韩对东亚人的吸引力是不小的……

(当然好处不仅是这点啦……)

不仅是网页程式……

很多应用程式的内核都开始使用 Unicode 编码……

目的是显而易见的:支援多语言显示……

微软的所有软体都是 Unicode 内核……

所以日文软体拿到你的中文 XP 上是可以正常显示的……

而中文 98 就会因为 GB 内核安装其他语言软体时造成乱码……

至于 UTF8 ,

可以说是 Unicode 的一个分支,

它用三个字节保存一个汉字……

(Unicode 用四个字节)

应用软体都集体投奔 Unicode 了……

就不允许我们搞网页程式的用 UTF8?

本文中凉鞋就尽量多方位介绍一下 UTF8 编码下的 PHP 编程……

至于为什么单独介绍“中文”……

一来是因为英文这玩意实在不需要考虑 UTF8 ……

除非你准备做多语言系统……

(我要发些牢骚:现在的老外写程式时根本不重视这个问题……)

二来是中日韩等多字节语系在 UTF8 编码下的处理方式其实大同小异……

依葫芦画瓢即可……

好……先从数据库处理部分开始吧……

==========================================

连接数据库

很多人刚升级到 Mysql 4.1 时会发现数据乱掉了……

其实是因为 Mysql 从 4.1 开始支援字符集了……

而且默认字符集正是 UTF8 ……

(充分证明与国际接轨的重要性…… 嘿嘿……)

而以前我们大多使用 utf8 或是 GBK 编码……

这样以来输出的数据当然是乱码……

要解决乱码……

就得让程序知道该获取什么编码的数据……

我们假设你以前的数据库是 utf8 编码的……

那么你可以在查询前添加一句

mysql_query('SET CHARACTER SET utf8') or die("Query failed : " . mysql_error());

当然,由于 4.1 以上才需要这样处理,

因此我们可以加上判断:

$mysqlversion = $db->query_first("SELECT VERSION() AS version");

if ($mysqlversion['version'] >= '4.1')

{

mysql_query('SET CHARACTER SET utf8') or die("Query failed : " . mysql_error());

}

这样以来不管 Mysql 默认编码是什么都可以正常存取了……

(不论您是存活期,还是存定期,甚至是零存整取都没有问题鸟……)

但是,人家都国际化鸟……

您还在用 utf8 行么?

如何转码呢?

还有……

数据升级时出现乱码怎么办?

凉拌!

且听下回分解……

============================================

数据升级至 4.1

要升级……

就得先导出……

要说老外还真不负责……

以前的导出方式总是弄丢一些中文字符……

比如把“我爱你娘”弄成“我爱你”啦……

(通常是丢失一段数据最末尾的字)

整个儿差了一辈儿……

(用石榴姐的话说就是“这么大逆不道的事实在是太刺激了”……)

为了保护您脆弱的心脏……

也为了维护中国传统伦理道义……

您可以把数据包含中文字符的字段改为二进制(Binary)编码……

具体方法嘛……

可以运行这个语句:

ALTER TABLE `表名` CONVERT TO CHARACTER SET binary;

这样,那些字符类型字段,如:

CHAR、VARCHAR 和 TEXT

将转换为

BINARY、VARBINARY 和 BLOB

然后再导出并导入到 4.1 环境中……

当然,最后一项繁琐的工作是:

你需要把它们的类型再改回来……

有往 4.1 升级的……

当然也有往下降级的……

怎么降级???

凉鞋去上个厕所……

而您请翻下页……

=============================================

数据从 4.1 降级

有人发现从4.1导出的 SQL 文件无法导入低版本程序……

问题其实很简单……

而且 Mysql 已经为我们想好了一切……

导出时请添加 –compatible 参数……

我们假设您的数据库是 utf8 编码的……

而且目标数据库版本为 4.0 ……

那么命令行下这么写:

shell>mysqldump --user=username --password=password --compatible=mysql40 --default-character-set=utf8 database > db.sql

这样导出的 SQL 文件就能够顺利导入低版本数据库了……

数据库部分算是搞定了……

但 PHP 编程方面要如何注意呢?

还得劳您翻下页……

http://www.knowsky.com

=============================================

PHP 文件编码

是否所有 PHP 文件都必须转成 UTF8 编码呢?

凉鞋告诉您是 NO ……

这么说吧……

如果文件中包含需要显示出来的中文字符……

就应该转为 UTF8 编码……

举例子吧:

// 我是凉鞋

echo time();

上面的代码虽有代码……

但是由于存在于注释中……

不会输出……

所以这个页面可以不用转换为 UTF8 格式……

再如:

echo "我是凉鞋";

这个明显有中文字符输出……

您还是老老实实转换为 UTF8 吧……

当然现在很多程式都采用模板(语言包)技术……

程式(非语言包文件)里是看不到任何供输出的字符的……

这样以来我们只需要将语言包文件转成 UTF8 编码即可……

(语言包的优势就在这里啊…… 啊哈哈哈哈哈……)

'http://www.knowsky.com

==================================================

UTF8 中文截取

由于 UTF8 使用三个字节……

所以传统的 substr 函数就没辙了……

很多高手都写了 UTF8 中文字符截取函数……

这里送上几种:

1.先算再取

/**

* Author : Dummy | Zandy

* Email : lianxiwoo@gmail.com | hotmail.com

* Create : 200512

* Usage : echo join('', String::subString_UTF8('汉字', 0, 1));

*/

ini_set('display_errors', 1);

error_reporting(E_ALL ^ E_NOTICE);

class String {

function subString_UTF8($str, $start, $lenth)

{

$len = strlen($str);

$r = array();

$n = 0;

$m = 0;

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

$x = substr($str, $i, 1);

$a = base_convert(ord($x), 10, 2);

$a = substr('00000000'.$a, -8);

if ($n < $start){

if (substr($a, 0, 1) == 0) {

}elseif (substr($a, 0, 3) == 110) {

$i += 1;

}elseif (substr($a, 0, 4) == 1110) {

$i += 2;

}

$n++;

}else{

if (substr($a, 0, 1) == 0) {

$r[] = substr($str, $i, 1);

}elseif (substr($a, 0, 3) == 110) {

$r[] = substr($str, $i, 2);

$i += 1;

}elseif (substr($a, 0, 4) == 1110) {

$r[] = substr($str, $i, 3);

$i += 2;

}else{

$r[] = '';

}

if (++$m >= $lenth){

break;

}

}

}

return $r;

} // End subString_UTF8

}// End String

echo join('', String::subString_UTF8('汉字', 0, 1));

2.先截后取

这种方式凉鞋觉得很巧妙……

用传统截取函数先截断……

然后判断中文单个字符是否被分割开……

如果是……则处理之……

要特别注意的是 substr 函数的第三个参数必须大于 3 ……

至于为什么不用凉鞋解释了吧?

// A trim function to remove the last character of a utf-8 string

// by following instructions on http://en.wikipedia.org/wiki/UTF-8

// dotann

// usage: $str = utf8_trim(substr($str,0,50));

function utf8_trim($str) {

$len = strlen($str);

for ($i=strlen($str)-1; $i>=0; $i-=1){

$hex .= ' '.ord($str[$i]);

$ch = ord($str[$i]);

if (($ch & 128)==0) return(substr($str,0,$i));

if (($ch & 192)==192) return(substr($str,0,$i));

}

return($str.$hex);

}

$str = '汉字';

echo utf8_trim(substr($str,0,3));

3.还有其它方法,

比如 007pig 为我们 vBulletin 中文版里所写的函数……

短小精悍……

源码不便放出……

对不住鸟……

今天就写到这里吧……

还有转码等问题没有写……

最近忙……

有空继续整理……

http://www.quchao.com/?p=6&pp=1

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有