最近调了一个Soap请求C# webservice的项目。网上坑不少。

使用原生的SoapClient库请求也是失败。只好用post来进行模拟了。代码贴出来,给大家参考一下。

 

<?php

namespace App\Services\Proxy;

use Log;
use Cache;

class Crm
{
    private $host;

    private $namespace;

    private $app_secret;
    
    private $username;

    private $values;

    public function __construct()
    {
        $this->host          = config('crm.host');
        $this->namespace     = config('crm.namespace');
        $this->app_secret    = config('crm.app_secret');
        $this->username      = config('crm.username');
        $this->values        = [];
    }

    /**
     * 通过mobile和open_id获取用户信息
     */
    public function getVipInfoByMobileOpenID($mobile, $openid)
    {
        $this->values = [
            'mobile' => $mobile,
            'openid' => $openid,
        ];

        return $this->response('GetVipInfoByMobileOpenID');
    }
    
    /**
     * 以post方式提交xml到对应的接口url
     */
    private function postXml($action, $sign_index = null)
    {
        $body = $this->toCRMXml($action, $sign_index);

        // Get cURL resource
        $ch = curl_init();

        // Set url
        curl_setopt($ch, CURLOPT_URL, $this->host);

        // Set method
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

        // Set options
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // Set headers
        curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: text/xml"]);


        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

        // Send the request & save response to $resp
        $resp = curl_exec($ch);

        if ($resp === false) {
            $error = curl_error($ch);
            curl_close($ch);

            Log::info('CRM请求错误:' . json_encode($error));
            return false;
        }

        curl_close($ch);
        return $resp;
    }


    /**
     * 输出CRM soap xml字符
     */
    private function toCRMXml($action, $sign_index = null)
    {
        $soap_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
        
        $soap_xml .= "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:tech=\"{$this->namespace}\">\r\n";
        $soap_xml .= "<soap:Body>\r\n";
        $soap_xml .= "<$action xmlns=\"{$this->namespace}\">\r\n";
        $soap_xml .= "<request>\r\n";

        // header
        $soap_xml .= $this->setHeader($soap_xml, $sign_index);

        // data
        $soap_xml .= "<Data>\r\n";
        $soap_xml .= $this->arrayToXml($this->values);
        $soap_xml .= "</Data>\r\n";
        $soap_xml .= "</request>\r\n";


        $soap_xml .= "</$action>\r\n";

        $soap_xml .= "</soap:Body>\r\n";
        $soap_xml .= "</soap:Envelope>";

        return $soap_xml;
    }

    /**
     * 生成Header
     */
    private function setHeader($xml, $sign_index= null)
    {
        list($date, $time) = explode(' ', date('Ymd His'));
        $sign = $this->setSign($date, $time, $sign_index);

        $xml  = "";
        $xml .= "<Header>\r\n";
        $xml .= "<SIGN>$sign</SIGN>\r\n";
        $xml .= "<REQDATE>$date</REQDATE>\r\n";
        $xml .= "<REQTIME>$time</REQTIME>\r\n";
        $xml .= "<USER>{$this->username}</USER>\r\n";
        $xml .= "</Header>\r\n";

        return $xml;
    }

    /**
     * 生成sign
     */
    private function setSign($date, $time, $sign_index= null)
    {
        if ($sign_index) {
            if (strpos($sign_index, '.')) {
                list($stuct_index, $index) = explode('.', $sign_index);
                $seeder = $date . $time . $this->values[$stuct_index][$index] . $this->app_secret;
            } else {
                $seeder = $date . $time . $this->values[$sign_index] . $this->app_secret;
            }
        } else {
            $seeder = $date . $time . $this->app_secret;
        }


        return md5($seeder);
    }

    /**
     * 数组转换成xml
     */
    private function arrayToXml($params)
    {
        $xml = "";
        foreach ($params as $name => $value) {
            if (is_array($value)) {
                $xml .= "<$name>" . $this->arrayToXml($value) . "</$name>\r\n";
            } else {
                $xml .= "<$name>$value</$name>\r\n";
            }
        }

        return $xml;
    }

    /**
     * 将xml结果转化为对象
     */
    public function response($action, $sign_index = null)
    {
        $result = str_ireplace('soap:', '', $this->postXml($action, $sign_index));
        return $this->objectToArray(simplexml_load_string($result, 'SimpleXMLIterator', LIBXML_NOCDATA));
    }

    /**
     * 将对象转化为数组
     */
    public function objectToArray($obj)
    {
        $_arr = is_object($obj) ? get_object_vars($obj) : $obj;

        $arr = [];
        foreach ($_arr as $key => $val) {
            $val = (is_array($val) || is_object($val)) ? $this->objectToArray($val) : $val;
            $arr[$key] = $val;
        }

        return $arr;
    }
}

 

 
 
 posted on 2017-07-11 21:51  瀚海  阅读(1334)  评论(0编辑  收藏  举报