Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18672830
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-04-14 21:36:42

前言:
  
  说实话,
  凉鞋也觉得 UTF8 是好东西……
  毕竟同屏显示中日韩对东亚人的吸引力是不小的……
  (当然好处不仅是这点啦……)
  不仅是网页程式……
  很多应用程式的内核都开始使用 Unicode 编码……
  目的是显而易见的:支援多语言显示……
  微软的所有软体都是 Unicode 内核……
  所以日文软体拿到你的中文 XP 上是可以正常显示的……
  而中文 98 就会因为 GB 内核安装其他语言软体时造成乱码……
  
  至于 UTF8 ,
  可以说是 Unicode 的一个分支,
  它用三个字节保存一个汉字……
  (Unicode 用四个字节)
  应用软体都集体投奔 Unicode 了……
  就不允许我们搞网页程式的用 UTF8?
  
  本文中凉鞋就尽量多方位介绍一下 UTF8 编码下的 编程……
  至于为什么单独介绍“中文”……
  一来是因为英文这玩意实在不需要考虑 UTF8 ……
  除非你准备做多语言系统……
  (我要发些牢骚:现在的老外写程式时根本不重视这个问题……)
  二来是中日韩等多字节语系在 UTF8 编码下的处理方式其实大同小异……
  依葫芦画瓢即可……
  好……先从处理部分开始吧……
  
  
  ==========================================
  连接数据库
  
  很多人刚升级到 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://
  =============================================
  PHP 文件编码
  
  是否所有 PHP 文件都必须转成 UTF8 编码呢?
  凉鞋告诉您是 NO ……
  
  这么说吧……
  如果文件中包含需要显示出来的中文字符……
  就应该转为 UTF8 编码……
  举例子吧:
  
  // 我是凉鞋
  echo time();
  上面的虽有代码……
  但是由于存在于注释中……
  不会输出……
  所以这个页面可以不用转换为 UTF8 格式……
  
  再如:
  
  echo "我是凉鞋";
  这个明显有中文字符输出……
  您还是老老实实转换为 UTF8 吧……
  
  当然现在很多程式都采用模板(语言包)……
  程式(非语言包文件)里是看不到任何供输出的字符的……
  这样以来我们只需要将语言包文件转成 UTF8 编码即可……
  (语言包的优势就在这里啊…… 啊哈哈哈哈哈……)
  'http://
  ==================================================
  
  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
  // 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 中文版里所写的函数……
  短小精悍……
  源码不便放出……
  对不住鸟……
  
  今天就写到这里吧……
  还有转码等问题没有写……
  最近忙……
  有空继续整理……
阅读(430) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~