PHP用post来进行Soap请求

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

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

<?php

namespace AppServicesProxy;

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"?>
";
        
        $soap_xml .= "<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tech="{$this->namespace}">
";
        $soap_xml .= "<soap:Body>
";
        $soap_xml .= "<$action xmlns="{$this->namespace}">
";
        $soap_xml .= "<request>
";

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

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


        $soap_xml .= "</$action>
";

        $soap_xml .= "</soap:Body>
";
        $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>
";
        $xml .= "<SIGN>$sign</SIGN>
";
        $xml .= "<REQDATE>$date</REQDATE>
";
        $xml .= "<REQTIME>$time</REQTIME>
";
        $xml .= "<USER>{$this->username}</USER>
";
        $xml .= "</Header>
";

        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>
";
            } else {
                $xml .= "<$name>$value</$name>
";
            }
        }

        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;
    }
}
 
 
原文地址:https://www.cnblogs.com/xuhuaiqu/p/7152808.html