UTF8下的中文PHP编程
前言:
说实话,凉鞋也觉得 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.mypchelp.cn=============================================PHP 文件编码
是否所有 PHP 文件都必须转成 UTF8 编码呢?凉鞋告诉您是 NO ……
这么说吧……如果文件中包含需要显示出来的中文字符……就应该转为 UTF8 编码……举例子吧:
// 我是凉鞋echo time();上面的代码虽有代码……但是由于存在于注释中……不会输出……所以这个页面可以不用转换为 UTF8 格式……
再如:
echo '我是凉鞋';这个明显有中文字符输出……您还是老老实实转换为 UTF8 吧……
当然现在很多程式都采用模板(语言包)技术……程式(非语言包文件)里是看不到任何供输出的字符的……这样以来我们只需要将语言包文件转成 UTF8 编码即可……(语言包的优势就在这里啊…… 啊哈哈哈哈哈……)'http://www.mypchelp.cn==================================================
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 Stringecho 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