1.类的实现
<?php
/**
* 概念
* 全角字符unicode编码从65281~65374 (十六进制 0xFF01 ~ 0xFF5E)
* 半角字符unicode编码从33~126 (十六进制 0x21~ 0x7E)
* 空格比较特殊,全角为 12288(0x3000),半角为 32 (0x20)
* 而且除空格外,全角/半角按unicode编码排序在顺序上是对应的
* 所以可以直接通过用+-法来处理非空格数据,对空格单独处理
*
* 实现思路
* 1. 找到目标unicode的字符,可以使用正则表达式解决
* 2. 修改unicode编码
*
* @url https://www.cnblogs.com/365star/p/5213963.html
*/
class SbcDbcFormat
{
/**
* 将unicode转换成字符
*
* @param int $unicode
* @return string UTF-8字符
**/
public function unicode2Char($unicode)
{
if($unicode < 128)
return chr($unicode);
if($unicode < 2048)
return chr(($unicode >> 6) + 192) . chr(($unicode & 63) + 128);
if($unicode < 65536)
return chr(($unicode >> 12) + 224) . chr((($unicode >> 6) & 63) + 128) . chr(($unicode & 63) + 128);
if($unicode < 2097152)
return chr(($unicode >> 18) + 240) . chr((($unicode >> 12) & 63) + 128) . chr((($unicode >> 6) & 63) + 128) . chr(($unicode & 63) + 128);
return false;
}
/**
* 将字符转换成unicode
*
* @param string $char 必须是UTF-8字符
* @return int
**/
public function char2Unicode($char)
{
switch (strlen($char))
{
case 1 :
return ord($char);
case 2 :
return (ord($char{1}) & 63) | ((ord($char{0}) & 31) << 6);
case 3 :
return (ord($char{2}) & 63) | ((ord($char{1}) & 63) << 6) | ((ord($char{0}) & 15) << 12);
case 4 : return (ord($char{3}) & 63) | ((ord($char{2}) & 63) << 6) | ((ord($char{1}) & 63) << 12) | ((ord($char{0}) & 7) << 18);
default :
trigger_error('Character is not UTF-8!', E_USER_WARNING);
return false;
}
}
/**
* 全角转半角
*
* @param string $str
* @return string
**/
public function sbc2Dbc($str)
{
return preg_replace_callback(
'/[\x{3000}\x{ff01}-\x{ff5f}]/u',
function($matches){
$unicode=$this->char2Unicode($matches[0]);
if($unicode == 0x3000){
return " ";
}
$code = $unicode-0xfee0;
if($code > 256){
return $this->unicode2Char($code);
}else{
return chr($code);
}
},
$str);
}
/**
* 半角转全角
*
* @param string $str
* @return string
**/
public function dbc2Sbc($str)
{
return preg_replace_callback(
// 半角字符
'/[\x{0020}\x{0020}-\x{7e}]/u',
// 编码转换
// 0x0020是空格,特殊处理,其他半角字符编码+0xfee0即可以转为全角
function ($matches){
$unicode=$this->char2Unicode($matches[0]);
if($unicode == 0x0020){
return $this->unicode2Char(0x3000);
}
$code=$unicode+0xfee0;
if($code >256){
return $this->unicode2Char($code);
}else{
return chr($code);
}
},
$str);
}
}
2.使用示例
$str = 'xxxxxxx';
$sbcDbcFormat = new SbcDbcFormat();
$str = $sbcDbcFormat->sbc2Dbc($str);