PHP介面:字元編碼和資料格式由請求方定義
阿新 • • 發佈:2018-11-04
根據一個老專案寫介面,發現專案檔案編碼為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("&","<",">","'","""); 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。