调用webservice肯定需要验证来源方和接收方的数据合法性,只有对于合法的数据才处理。
本代码使用CI框架编写,主要有
1.生成响应内容的方法;
2.发送请求的方法;
3.包括将xml转化为array的方法;
4.验证签名是否正确的方法;
5.构造发送请求的xml字符串方法
签名主要根据内容和盐值生成,可以判断接收到的内容是否正确;判断发来的xml字符串是否被篡改,如果一旦被篡改就给出错误提示,不再后续处理。
<?php
class Basewebservice
{
/**
* 数字签名验证是否成功
* @param string $xmlContent xml字符串
* @return boolean
*/
public function checkSignIsValid($xmlContent)
{
$posSign = strpos($xmlContent, '<sign>');
$sign = substr($xmlContent, $posSign+6,32);
$pos1 = strpos($xmlContent, '<body>');
$pos2 = strpos($xmlContent, '</body>');
$content = substr($xmlContent, $pos1, $pos2-$pos1+7);
$this->load->config('security');
if (strtolower($sign) != md5($this->config->item('soap_salt_hash', 'security').$content)) {
$content = NULL;
return FALSE;
}
$content = NULL;
return TRUE;
}
/**
* the body string of the xml content for outputing
* @param string $strBody xml字符串body部分
* @return string 返回的xml字符串
*/
public function makeOutput($strBody)
{
$this->load->config('security');
$sign = md5($this->config->item('soap_salt_hash', 'security').$strBody);
$output = '<?xml version="1.0" encoding="UTF-8" ?><response><version>1</version>';
$output .= '<sign>'.$sign.'</sign>';
$output .= $strBody;
$output .= '</response>';
return $output;
}
/**
* XML转数组
* @param string $xmlstring XML字符串
* @return string 数组
*/
public function xml2Array($xmlstring)
{
$str_source = array('\\x00','\\x01','\\x02','\\x03','\\x04','\\x05','\\x06','\\x07','\\x08',
'\\x0b','\\x0c','\\x0e','\\x0f','\\x10','\\x11','\\x12','\\x13','\\x14','\\x15',
'\\x16','\\x17','\\x18','\\x19','\\x1a','\\x1b','\\x1c','\\x1d','\\x1e','\\x1f');
$xmlstring = str_replace($str_source, '', $xmlstring);
$str_source = ['&' , "'" ];//,'<','>','"',"'"
$str_target = ['&','''];//,'<','>','"','''
$xmlstring = str_replace($str_source, $str_target, $xmlstring);
return json_decode(json_encode((array)simplexml_load_string($xmlstring)),true);
}
/**
* 发送一个webservice请求
* @param string $xmlContent 完整的xml请求字符串
* @param string $method 服务器提供的webservice中的方法
* @return Maxed array or false
*/
public function sendRequest($xmlContent, $method)
{
ini_set("soap.wsdl_cache_enabled" , 0);
$errorLevel = error_reporting(); //先获取到系统的默认错误报告级别
error_reporting(E_ERROR);
ini_set('default_socket_timeout' , 3);
$receiveArr = [];
$this->load->config('biz');
$url = $this->config->item('targetWebServiceUrl', 'biz');
try
{
libxml_disable_entity_loader(false);
$client = new SoapClient($url,array('connection_timeout' => 3));
$params = array('parameters'=>array('xmlContent' => $xmlContent));
$res = $client->__soapCall($method, $params);
$this->load->library('bizlog');
// $this->bizlog->info('b2b_services', 'return res:['.$res->Result.']');
$result = $this->checkSignIsValid($res->Result);
if ( ! $result) {
$this->bizlog->info('b2b_services', '签名错误,具体收到的xml串为:['.$res->Result.']');
error_reporting($errorLevel);
return FALSE;
}
$receiveArr = $this->xml2Array($res->Result);
error_reporting($errorLevel);//恢复到以前的错误级别设置
return $receiveArr;
}
catch(Exception $e)
{
error_reporting($errorLevel);
throw $e;
}
return $receiveArr;
}
/**
* 构造发送请求的xml字符串
* @param string $xmlBody body部分xml字符串
* @return string 完整的xml请求字符串
*/
public function makeRequestXml($xmlBody)
{
$this->load->config('security');
$salt = $this->config->item('soap_salt_hash', 'security');
$output = '<?xml version="1.0" encoding="UTF-8" ?><request><version>1</version>';
$sign = md5($salt.$xmlBody);
$output .= '<sign>'.$sign.'</sign>';
$output .= $xmlBody;
$output .= '</request>';
return $output;
}
}
?>