前两天做微信分账功能,遇到了xml错误,看着代码,怎么看怎么正确,可是,就是报错。
最后,退而求其次,换个方法,问题解决了。
1、首先,生成xml格式字符串
关键代码:
public function toXml($arr)
{
$xml = '<xml>';
$xml .= $this->array_to_xml($arr);
$xml .= '</xml>';
return $xml;
}
//array转xml
public function array_to_xml($arr) {
$xml = '';
foreach ($arr as $key => $val) {
if (is_array($val)) {
$xml .= '<' . $key . '>' . $this->array_to_xml($val) . '</' . $key . '>';
} else {
$xml .= '<' . $key . '>' . $val . '</' . $key . '>';
}
}
return $xml;
}
2、将这段文字写入xml文件
3、读取这个xml文件。代码如下:
//1.设置分账账号
$receivers = array();
foreach ($profitSharingAccounts as $profitSharingAccount)
{
$tmp = array(
'type'=>$profitSharingAccount['type'],
'account'=>$profitSharingAccount['account'],
'amount'=>intval($profitSharingAccount['amount']),
'description'=>$profitSharingAccount['description'],
);
$receivers[] = $tmp;
}
$receivers = json_encode($receivers);
$totalCount = count($profitSharingOrders);
$successCount = 0;
$failCount = 0;
$now = time();
//2.生成签名
$postArr = array(
'appid'=>$this->wxConfig['app_id'],
'mch_id'=>$this->wxConfig['mch_id'],
'nonce_str'=>md5(time() . rand(1000, 9999)),
'transaction_id'=>$profitSharingOrders['transaction_id'],
'out_order_no'=>$profitSharingOrders['out_trade_no'],
'receivers'=>$receivers,
);
$sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->wxConfig['md5_key']);
$postArr['sign'] = $sign;
//3.发送请求
$url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';
$postXML = $this->toXml($postArr);
//为了适应xml格式,先保存到文件,再取出,这样xml格式就能适应了。
$filename = dirname(__FILE__).'/xml/subledger.xml';
file_put_contents($filename, $postXML);
$postXML = file_get_contents($filename);
最后,调用post方法
$helper = new Common_util_pub();
$ret = $helper->postXmlSSLCurl($postXML, $url);
postXmlSSLCurl方法代码:
/**
* 作用:使用证书,以post方式提交xml到对应的接口url
*/
function postXmlSSLCurl($xml, $url, $second = 30) {
$ch = curl_init ();
//超时时间
curl_setopt ( $ch, CURLOPT_TIMEOUT, $second );
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
//设置header
curl_setopt ( $ch, CURLOPT_HEADER, FALSE );
//要求结果为字符串且输出到屏幕上
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE );
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt ( $ch, CURLOPT_SSLCERT, dirname(__FILE__).'/cacert/apiclient_cert.pem' );
curl_setopt ( $ch, CURLOPT_SSLKEY, dirname(__FILE__).'/cacert/apiclient_key.pem' );
//证书密码
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, WxPayConf_pub::KEY );
//post提交方式
curl_setopt ( $ch, CURLOPT_POST, true );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xml );
//启用时会汇报所有的信息,存放在STDERR或指定的 CURLOPT_STDERR 中。
curl_setopt($ch, CURLOPT_VERBOSE, '1');
$data = curl_exec ( $ch );
//返回结果
if ($data) {
curl_close ( $ch );
return $data;
} else {
$error = curl_errno ( $ch );
echo "curl出错,错误码:$error" . "<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close ( $ch );
return false;
}
}
其它代码,网上很多,就不贴出来了。