• 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;
        }
    }
     
     
  • 相关阅读:
    Android 学习笔记之WebService实现远程调用+内部原理分析...
    Android学习笔记之Json的使用....
    Android学习笔记之DocumentBuilder的使用....
    Android学习笔记之ExecutorService线程池的应用....
    Android学习笔记之SoftReference软引用...
    windows系统获取进程的pid号并终止
    Linux系统的时间比北京时间慢12个小时的处理方案(将EDT时区改为CST)
    将java的jar包作为windows的服务来启动
    linux初始化shell脚本
    linux中网络部分的总结
  • 原文地址:https://www.cnblogs.com/xuhuaiqu/p/7152808.html
Copyright © 2020-2023  润新知