PHP接口:字符编码和数据格式由请求方定义

根据一个老项目写接口,发现项目文件编码为gbk,而且数据库也是gbk,由于代码量巨大,不可能更改项目代码以及数据库的字符编码。

请求接口的也有好多个:
老客户一直用的gbk字符编码的数据来请求的,原来写的接口收到的数据格式为xml,
新客户要求用utf-8格式,接收数据为json。
看了前辈的代码,整理了一个类文件,可以实现由用户自己来决定传的数据字符集(gbk、utf-8),接收的数据的格式(json、xml、序列化字符串)。

下面是代码:

<?php
/**
*可实现数据的字符编码(gbk、utf-8)和数据格式(json、xml、序列化字符串)由请求方自由定义。
**/
class Response
{
	/**
	 *初始化数据,处理get、post请求的参数字符编码,并将这些参数统一放到request数组中
	 */
	public function __construct(){
		if(!isset($request_arr)){
			$request_arr = array();
		}
		$this->REQUEST_TIME = $_SERVER['REQUEST_TIME'] == '' ? time() : $_SERVER['REQUEST_TIME'];
		//将get、post传递过来的参数,放到$request_arr数组中
		if($_GET){
			foreach ($_GET as $key => $value) {
				$request_arr[strtolower($key)] = trim($value);
			}
		}
		if($_POST){
			foreach ($_POST as $key => $value) {
				$request_arr[strtolower($key)] = trim($value);
			}
		}
		//默认字符编码为gbk 数据格式为xml
		$this->request['data_coding'] = $request_arr['data_coding'] == '' ? 'gbk' : strtolower($request_arr['data_coding']);
		$this->request['data_format'] = !in_array($request_arr['data_format'], array('json','xml','php')) ? 'xml' : $request_arr['data_format'];
		if(count($request_arr) > 0){
			if($this->request['data_coding'] == 'gbk'){
				foreach ($request_arr as $key => $value) {
					$this->request[$key] = trim($value);
				}
			}
			//如果传递来的是utf8的数据,有data_coding参数值为utf-8,则默认转换为gbk格式处理
			if($this->request['data_coding'] == 'utf-8'){
				foreach ($request_arr as $key => $value) {
					$this->request[$key] = trim(gbk($value));
				}
			}
		}
		unset($_POST,$_GET);
	}
	/**
	 *@param string $code 错误码
	 *@param string $msg 错误信息
	 *@param array $data 返回值

	 请求方post数据中的两个参数:
	 $this->request['data_format'] 数据格式(json、xml、php字符串)
	 $this->request['data_coding'] 字符编码类型(gbk、utf-8)
	 */
	public static function printResult($code,$msg,$data = '')
	{
		switch ($this->request['data_format']) {
			case 'xml':
				header("Content-Type:text/xml; charset={$this->request['data_coding']}");
				self::printXml($code,$msg,$data);
				break;
			case 'json':
				self::printJson($code,$msg,$data);
				break;
			case 'php':
				self::printPhp($code,$msg,$data);
				break;
			default:
				self::printJson($code,$msg,$data);
				break;
		}
	}
	public static function printXml($code,$msg,$data = '')
	{
		$xml = '';
		$ymdhis = date('Y-m-d H:i:s',$this->REQUEST_TIME); //记录得到请求开始的时间
		if(!is_array($data)){
			self::printXml($code,$msg?$msg:"内容不存在",array());
		}else{
			$interfaceName = $this->request['interface_name'] == ''?'error':$this->request['interface_name']; //请求的接口名
			$msg = self::encode_xmlvalue($msg);
			$xml = "<?xml version=\"1.0\" encoding=\"{$this->request['data_coding']}\"?>\r\n<{$interfaceName}>\r\n";
			$xml .= "<ret code=\"$code\" msg=\"$msg\" system=\"$ymdhis\"/>\r\n";
			if(count($data) > 0){
				foreach ($data as $arrs) {
					$arr = '';
					foreach ($arrs as $key => $value) {
						$value = self::encode_xmlvalue($value);
						$arr .= " $key=\"$value\"";
					}
					if($arr){
						$xml .="<item$arr/>\r\n";
					}
				}
			}
			$xml .= "</interfaceName>";
		}
		if($this->request['data_coding'] == 'utf-8'){
			$xml = self::utf8($xml);
		}
		echo $xml;
		return;
	}
	public static function printPhp($code,$msg,$data = '') 
	{
//用此函数,字符集为gbk的时候,如果有汉字可能会出现问题。如果用的话,请最好保证字符集为utf-8
		$arr = array();
		$ymdhis = date('Y-m-d H:i:s',$this->REQUEST_TIME);
		if($this->request['data_coding'] == 'utf-8') 
			$msg = self::utf8($msg);
		$arr['code'] = $code;
		$arr['msg'] = $msg;
		$arr['system'] = $ymdhis;
		if($data != ''){
			if($this->request['data_coding'] == 'utf-8') 
				$data = self::utf8($data);
			$arr['data'] = $data;
		}
		echo serialize($arr);
		return;
	}
	public static function printJson($code,$msg,$data = '')
	{
		$arr = array();
		$ymdhis = date('Y-m-d H:i:s',$this->REQUEST_TIME);
		if ($this->request['data_coding'] == 'utf-8')
			$msg = self::utf8($msg);
		$arr['code'] = $code;
		$arr['msg'] = $msg;
		$arr['system'] = $ymdhis;
		if($data != ''){
			if($this->request['data_coding'] == 'utf-8') 
				$data = self::utf8($data);
			$arr['data'] = $data;
		}
		echo json_encode($arr);
		return;
	}
	public static function encode_xmlvalue($v)
	{
		$old_arr = array("&","<",">",'\'',"\"");
		$new_arr = array("&amp;","&lt;","&gt;","&apos;","&quot;");
		return str_replace($old_arr, $new_arr, rtrim($v));
	}
	public static function gbk($str)
	{
		if(is_array($str)){
			return array_map('gbk', $str);//遍历数组,数组的每个元素都执行"函数名"的函数
		}
		return iconv('utf-8', 'gbk//IGNORE' ,$str);
	}
	public static function utf8($str)
	{
		if(is_array($str)){
			return array_map('utf8', $str);
		}
		return iconv('gbk', 'utf-8//IGNORE' ,$str);
	}
}

以上代码为了适应更多的场景,博主修改了下,和项目中的代码是不一样的,由于种种原因是博主只能一点点的手敲出来,逻辑上应该没问题,但是代码手敲过程中可能会出现错误。望发现的小伙伴指正。

序列化的部分大多人应该用不到,而且当字符集为gbk的时候可能会出现问题。如果用的话,请最好保证字符集为utf-8。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值