1. 程式人生 > >PHP介面:字元編碼和資料格式由請求方定義

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。