zoukankan      html  css  js  c++  java
  • PHP使用WSDL格式Soap通信

    近期在搞一个项目,甲方只给了一个WSDL文件,让我们实现响应接口。

    于是研究了WSDL和SOAP通信相关知识,获益甚深,把我的理解写下来,希望对PHP新手有帮助。

    1.基本概念

    soap是简单对象访问协议的缩写是一种可以基于HTTP协议的访问方式。客户端发送请求,然后调用带参数的服务端函数得到服务端的数据;服务端编写处理函数并响应客户端。

    wsdl是网络服务者动态语言的缩写,这里面定义了双方通信时包含的东西。客户端把wsdl文件给服务端,服务端分析wsdl并写出里面的函数,这样两者无论是什么平台、什么语言都可以通信。

    我对soap的理解就是类似于POST请求的一种传递参数的方式,只是要求格式比POST更严格。

    我认为wsdl也仅仅是一种xml标记文本,跟html文本没有什么区别。

    但是两者结合起来就很头疼了。

    我是第一次接触soap和wsdl,这两者同时出现,我把他们俩混在一起搞不清。

    参看了很多文档才清楚这两者到底是什么。

    soap结合wsdl,其实就是把soap通信方式限制的更死,死到你服务端里只能按照wsdl里面规定的函数来写,并严格限制参数和返回结果。

    2.我走的弯路

    一开始我拿到这个wsdl文档,打开来看密密麻麻的,一共将近200行。

    我没搞清是什么东西,连里面的标记符都没有搞懂,就开始在网上搜php与wsdl有关的博客。

    搜到一个SoapDiscovery.class.php文件,说可以创建wsdl文件。

    我就开始盲目的想创建wsdl文件,并使这个wsdl文件和甲方的一样。

    我错误的认为客户端发送wsdl文件给我,我来解析里面是什么,然后我处理后再次封装成wsdl文件发送给客户端。

    其实,这个wsdl根本就不用创建,它甚至都不是重点。

    这个wsdl文件是双方通信前就规定好的,双方都按照这个wsdl里面的规定访问函数或返回函数等内容。

    所以重点不是解析、构建wsdl文件,而是根据这个wsdl写好服务端的函数和返回值。

    3.解决问题阶段一

    理解wsdl的几个网站:http://staff.ustc.edu.cn/~shizhu/DotNet/WSDLxj.htm  【Web Service描述语言 WSDL 详解】

    https://www.ibm.com/developerworks/cn/education/webservices/ws-dewsdl/ws-dewsdl.html 【描述 Web 服务:WSDL】

    认真看完上面两个网站,基本就知道wsdl里面讲的是什么了。

    我在网上下载了很多关于php与wsdl的实例,

    感觉这个例子很好:http://www.cnblogs.com/VipBin/archive/2011/12/07/2279927.html   【在PHP中利用wsdl创建标准webservice

    有了以上的基础。

    我开始理解wsdl工作原理了。

    客户端client就是发送请求的,服务端service就是接收请求的,再来一个class类处理函数(这里我叫它Robot类),就行了。

    上面怎么写客户端与服务端用到了SoapClient,SoapServer两个类。

    怎么写Robot类的函数用到了wsdl文件里规定的函数,也就是wsdl知识。

    4.解决问题阶段二

    通过上面的例子,我可以成功运行。但已加上我Robot类就直接http 500错误,没有任何提示信息,调试及其麻烦。

    还好网上有两款很好的软件。

    一款是让wsdl文件直观化,直接看到里面定义函数的规则,叫XMLSpy软件。

    另一款是SoapUI,不需要写客户端,可以直接加入wsdl文件,访问服务端。

    从这两个软件中,我认识到wsdl文件虽然很乱,但只有几个是重点。

      一个是wsdl里的soap:address,要定义好访问的服务端的地址。

      一个是wsdl里的portType的operation,每一个operation的name就是Robot类中必须写的函数名,

      最后一个是wsdl里operation的out,也就是每个函数的返回值的规定。

    通过SoapUI,我可以清晰的看到客户端发送和服务端返回的到底是什么内容。

    其实里面没有任何wsdl的标记,都是正规的soap标记,所以wsdl根本就没有在通信过程用到,只在通信两端用到。

    我们就不需要管wsdl了,只要能实现里面的函数就行了。

    5.解决问题阶段三

    到了这个阶段,客户端与服务端的函数访问什么的都有了,唯一有问题的就是来回的参数格式问题。

    这时不会报http500错误,而是200 OK,但页面不会显示任何东西。因为参数是有问题的。

    先说怎么知道参数的格式的。

    1 //下面两个看懂,输出就是你要写的类
    2 var_dump($client->__getFunctions());//打印暴露的方法
    3 print("<br/>");
    4 var_dump($client->__getTypes());//打印对应方法的参数和参数类型
    5 print("<br/>");

    然后打印出来的参数是下面这样的:

    array(7) { [0]=> string(97) "struct standPointInfo { string POINTDES; string STANDPOINT; string STOR_TYPE; string WH_NO; }" [1]=> string(57) "struct webServiceResult { string INFO; string STATUS; }" [2]=> string(79) "struct taskResultInfo { string EXEC_STATE; string PICTURE; string TASK_NO; }" [3]=> string(265) "struct inventoryResultInfo { string CCDD; string CCLX; string CKH; string CW; string GC; string KCLX; double KCSL; string PC; double PDCY; string PDSJ; double PDSL; string RWH; string TSKCBH; string TSKCLX; string WLBH; string WZSFM; string ZHXM; }" [4]=> string(52) "struct standPointInfoArray { standPointInfo item; }" [5]=> string(62) "struct inventoryResultInfoArray { inventoryResultInfo item; }" [6]=> string(37) "struct Exception { string message; }" } 

    看到上面的参数格式,然后找到合适的php数据类型就行了。

    里面有struct类型,但php没有,不用怕,直接当array来用就行了,比如构建参数standPointInfoArray :

     1         $standPointInfoArray = array(
     2             array(
     3             'POINTDES' => 'hujun', 
     4             'STANDPOINT' => 'standPoint',
     5             'STOR_TYPE' => 'storType',
     6             'WH_NO' => 'whNo1',
     7             ),
     8             array(
     9             'POINTDES' => 'hujun', 
    10             'STANDPOINT' => 'standPoint',
    11             'STOR_TYPE' => 'storType',
    12             'WH_NO' => 'whNo2',
    13             ),
    14         );

    这个参数在wsdl里定义为二维数组,所以我用php也构建了一个二维数组,键名不能改要与wsdl名字一模一样而其必须加上,不然没法传参数。

    然后把这个参数扔到客户端的访问函数参数里就行了,不用转什么stdClass和json之类的,多余,直接用array就行了。

    客户端参数搞定了,下面看看服务端形参怎么搞。

    下面是我得到的wsdl规定的函数:

    array(3) { [0]=> string(76) "webServiceResult receiveStandPointInfo(standPointInfoArray $StandPointInfos)" [1]=> string(82) "webServiceResult receiveInventoryResult(inventoryResultInfoArray $InventoryResult)" [2]=> string(66) "webServiceResult receiveTaskResult(taskResultInfo $TaskResultInfo)" } 

    以receiveStandPointInfo函数为例。

    在Robot类里必须写这个函数,而且函数名必须一模一样,不能有一点改变。

    然后看形参是standPointInfoArray $StandPointInfos,这个standPointInfoArray类型在PHP很难自定义,但PHP的好处就是可以不用写类型。

    所以直接在形成里写变量名就行了,把前面的类型去掉。

    函数名如下:

    public function receiveStandPointInfo($standPointInfoArray)

    这样形参就好了,$standPointInfoArray可以被客户端赋值。

    这个时候是最折磨人的,因为你没法知道这个$standPointInfoArray是什么东西。服务端不给打印信息。

    只能先猜测为数组,然后用数组的方式调用,直接报错。

    Fatal error: Cannot use object of type stdClass as array

    上面讲的很清楚,这是个stdClass的类型。

    要是一维数组还好访问,直接用$standPointInfo->POINTDES就可以访问了。

    但是刚才客户端传递的是二维数组呀,这怎么访问呢?

    所以必须知道$standPointInfoArray到底是什么东西。

    在网上找到了stdClass的打印信息示例如下:

    stdClass Object (
    [item] => Array
        (
            [0] => stdClass Object
                (
                    [date] => 2008-07-17T01:23:06Z
                    [directory] => 1
                    [downloadCount] => 0
    
                )
            [1] => stdClass Object
                (
                    [date] => 2009-11-03T23:03:15Z
                    [directory] => 2
                    [downloadCount] => 5
    
                )
      ) )

    这下明朗了,原理这个键名叫item,是Soap协议传输多个复杂类型规定的。

    所以可以使用$standPointInfoArray->item[0]->data来访问日期等等。

    到这里,参数传递就完成了。

    返回的参数构造与发送的参数一样,这里就不写了。

    6.源代码

    客户端的client.php

     1 <?php
     2 $client = new SoapClient("robot_origin.wsdl", array('trace'=>true));
     3 try { 
     4         $parms = array(
     5             'EXEC_STATE' => "hujun",
     6             'PICTURE' => 'pictures',
     7             'TASK_NO' => 'task_nos',
     8             );
     9         $result = $client->receiveTaskResult($parms);
    10         var_dump($result);
    11         print("<br/>=======================<br/>");
    12 
    13         $standPointInfo = array(
    14             'POINTDES' => 'hujun', 
    15             'STANDPOINT' => 'standPoint',
    16             'STOR_TYPE' => 'storType',
    17             'WH_NO' => 'whNo',
    18         );
    19         $standPointInfoArray = array(
    20             array(
    21             'POINTDES' => 'hujun', 
    22             'STANDPOINT' => 'standPoint',
    23             'STOR_TYPE' => 'storType',
    24             'WH_NO' => 'whNo1',
    25             ),
    26             array(
    27             'POINTDES' => 'hujun', 
    28             'STANDPOINT' => 'standPoint',
    29             'STOR_TYPE' => 'storType',
    30             'WH_NO' => 'whNo2',
    31             ),
    32         );
    33         $result = $client->receiveStandPointInfo($standPointInfoArray);
    34         var_dump($result);
    35         print("<br/>=======================<br/>");
    36 
    37         //下面两个看懂,输出就是你要写的类
    38         var_dump($client->__getFunctions());//打印暴露的方法
    39         print("<br/>");
    40         var_dump($client->__getTypes());//打印对应方法的参数和参数类型
    41         print("<br/>");
    42         echo("
    Dumping request headers:
    ");
    43         var_dump($client->__getLastRequestHeaders());
    44         echo "<br>";
    45         echo("
    Dumping request:
    ");
    46         var_dump($client->__getLastRequest());
    47         echo "<br>";
    48         echo("
    Dumping response headers:
    ");
    49         var_dump($client->__getLastResponseHeaders());
    50         echo "<br>";
    51         echo("
    Dumping response:
    ");
    52         var_dump($client->__getLastResponse());
    53 }
    54 catch (SoapFault $f){
    55         echo "Error Message: {$f->getMessage()}";
    56 }
    57 ?>

    服务端的service.php

    1 <?php
    2        include("robot.class.php");
    3     ini_set('soap.wsdl_cache_enabled','0');    //关闭WSDL缓存
    4        $objSoapServer = new SoapServer("robot_origin.wsdl");//person.wsdl是刚创建的wsdl文件
    5     
    6     $objSoapServer->setClass("Robot");//注册person类的所有方法
    7     $objSoapServer->handle();//处理请求

    服务端处理类Robot.class.php

     1 <?php
     2 class Robot{
     3   public function receiveInventoryResult($inventoryResultInfoArray){
     4     $webServiceResult = array(
     5       'INFO' => 'info',
     6       'STATUS' => 'status',
     7       );
     8 
     9     $webServiceResult['INFO'] = $inventoryResultInfoArray->item[0]->KCSL;
    10 
    11     return $webServiceResult;
    12   }
    13   public function receiveStandPointInfo($standPointInfoArray){
    14     $webServiceResult = array(
    15       'INFO' => 'info',
    16       'STATUS' => 'status',
    17       );
    18     if($standPointInfoArray->item[0]->POINTDES){
    19       $webServiceResult['INFO'] = 'we can change it';
    20     }
    21     return $webServiceResult;
    22   }
    23 
    24   public function receiveTaskResult($taskResultInfo){
    25     $EXEC_STATE = $taskResultInfo->EXEC_STATE;
    26     $PICTURE = $taskResultInfo->PICTURE;
    27     $TASK_NO = $taskResultInfo->TASK_NO;
    28 
    29         $webServiceResult = array(
    30           'INFO' => 'info',
    31           'STATUS' => $PICTURE,
    32           );
    33         $webServiceResult['INFO'] = $EXEC_STATE;
    34     return $webServiceResult;
    35   }
    36 
    37   public function Exception($exception){
    38     $this->exception = $exception;
    39     return $this->exception;
    40   }
    41 }

    一直是电脑在用的wsdl文件

    <?xml version='1.0' encoding='utf-8'?><wsdl:definitions name="RobotWebServiceImplService" targetNamespace="http://robot.server.webService/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://robot.server.webService/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <wsdl:types>
    <!------schema才是关键,注意类型的寻址,下面是xs开头的,意思是这些类型到xmlns:xs=里面找------------>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://robot.server.webService/" xmlns:tns="http://robot.server.webService/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    //------------------------------------------------------------------------------------------------------------
    <!--设计一个复杂的数据类型standPointInfo-->
      <xs:complexType name="standPointInfo">
      <!--sequence是顺序限制-->
      <!--<minOccurs> 指示器可规定某个元素能够出现的最小次数-->
        <xs:sequence>
          <xs:element minOccurs="0" name="POINTDES" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="STANDPOINT" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="STOR_TYPE" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="WH_NO" type="xs:string"></xs:element>
        </xs:sequence>
      </xs:complexType>
      //-------------------------------1.1.1 output
      <xs:complexType name="webServiceResult">
        <xs:sequence>
          <xs:element minOccurs="0" name="INFO" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="STATUS" type="xs:string"></xs:element>
        </xs:sequence>
      </xs:complexType>
      //--------------------------------不需要
      <xs:complexType name="taskResultInfo">
        <xs:sequence>
          <xs:element minOccurs="0" name="EXEC_STATE" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="PICTURE" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="TASK_NO" type="xs:string"></xs:element>
        </xs:sequence>
      </xs:complexType>
      //----------------------------------1.2.1 input
      <xs:complexType name="inventoryResultInfo">
        <xs:sequence>
          <xs:element minOccurs="0" name="CCDD" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="CCLX" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="CKH" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="CW" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="GC" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="KCLX" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="KCSL" type="xs:double"></xs:element>
          <xs:element minOccurs="0" name="PC" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="PDCY" type="xs:double"></xs:element>
          <xs:element minOccurs="0" name="PDSJ" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="PDSL" type="xs:double"></xs:element>
          <xs:element minOccurs="0" name="RWH" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="TSKCBH" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="TSKCLX" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="WLBH" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="WZSFM" type="xs:string"></xs:element>
          <xs:element minOccurs="0" name="ZHXM" type="xs:string"></xs:element>
        </xs:sequence>
      </xs:complexType>
      //------------------------------------arrary
      <xs:complexType final="#all" name="standPointInfoArray">
        <xs:sequence>
          <xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="tns:standPointInfo"></xs:element>
        </xs:sequence>
      </xs:complexType>
      //-------------------------------------arrary
      <xs:complexType final="#all" name="inventoryResultInfoArray">
        <xs:sequence>
          <xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="tns:inventoryResultInfo"></xs:element>
        </xs:sequence>
      </xs:complexType>
      //--------------------------------------异常
      <xs:element name="Exception" type="tns:Exception"></xs:element>
      <xs:complexType name="Exception">
        <xs:sequence>
          <xs:element minOccurs="0" name="message" type="xs:string"></xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
    </wsdl:types>
    //---------------------------------------message是operation的参数
    <!--<message> 元素将数据(数据类型在 <types> 元素中进行定义)分组成一个用于逻辑网络传输的特征符,并将数据绑定到一个名称上-->
    <!--上面的name用于operation引用,下面的name是声明的实例-->
      <wsdl:message name="receiveInventoryResult">
        <wsdl:part name="InventoryResult" type="tns:inventoryResultInfoArray">
        </wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="receiveTaskResult">
        <wsdl:part name="TaskResultInfo" type="tns:taskResultInfo">
        </wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="receiveStandPointInfoResponse">
        <wsdl:part name="return" type="tns:webServiceResult">
        </wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="receiveInventoryResultResponse">
        <wsdl:part name="return" type="tns:webServiceResult">
        </wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="receiveTaskResultResponse">
        <wsdl:part name="return" type="tns:webServiceResult">
        </wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="receiveStandPointInfo">
        <wsdl:part name="StandPointInfos" type="tns:standPointInfoArray">
        </wsdl:part>
      </wsdl:message>
    
      <wsdl:message name="Exception">
        <wsdl:part element="tns:Exception" name="Exception">
        </wsdl:part>
      </wsdl:message>
    //--------------------------------------------------------------
    <!---相当于 Java 中的接口-->
    <!---它将对 <message> 元素的引用分组成逻辑操作,一个进程可以对另一个进程执行这些操作,并将它们绑定到一个名称-->
      <wsdl:portType name="RobotWebService">
    //---------------------------------------------------------------
    <!---<input> 元素声明客户机向 Web 服务请求传输的需求。<output> 声明 Web 服务响应的内容。<fault> 元素描述当 Web 服务设法响应客户机的请求时所发生的任何消息级异常-->
        <wsdl:operation name="receiveStandPointInfo">
          <wsdl:input message="tns:receiveStandPointInfo" name="receiveStandPointInfo"></wsdl:input>
          <wsdl:output message="tns:receiveStandPointInfoResponse" name="receiveStandPointInfoResponse"></wsdl:output>
          <wsdl:fault message="tns:Exception" name="Exception"></wsdl:fault>
        </wsdl:operation>
        //-----------------------------
        <wsdl:operation name="receiveTaskResult">
          <wsdl:input message="tns:receiveTaskResult" name="receiveTaskResult"></wsdl:input>
          <wsdl:output message="tns:receiveTaskResultResponse" name="receiveTaskResultResponse"></wsdl:output>
          <wsdl:fault message="tns:Exception" name="Exception"></wsdl:fault>
        </wsdl:operation>
        //------------------------------
        <wsdl:operation name="receiveInventoryResult">
          <wsdl:input message="tns:receiveInventoryResult" name="receiveInventoryResult">
        </wsdl:input>
          <wsdl:output message="tns:receiveInventoryResultResponse" name="receiveInventoryResultResponse">
        </wsdl:output>
          <wsdl:fault message="tns:Exception" name="Exception">
        </wsdl:fault>
        </wsdl:operation>
      </wsdl:portType>
      //----------------------------------------------------------------
      <!--到这里,上面的定义什么的都是抽象的,binding将这些抽象的钩接点与 Web 协议束缚起来-->
      <!--描述绑定的元素嵌套在 <binding> 元素的这些子元素之中,这是为了将消息传递协议的详细内容链接到目标 portType 中所提到的通则上。-->
      <wsdl:binding name="RobotWebServiceImplServiceSoapBinding" type="tns:RobotWebService">
        <!--创建 SOAP 绑定-->
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"></soap:binding> 
        <wsdl:operation name="receiveStandPointInfo">
        <!--soapAction,在 SOAP 1.2 中,不赞成使用这个头,而赞成将请求中的请求目的声明为一个参数,称作“action”。因而通常就让这个头空着。-->
          <soap:operation soapAction="" style="rpc"></soap:operation>
          <!--输入值中,除了出错数据应当包含在 SOAP <Fault> 元素中之外,其它所有消息都将包含在常规的 SOAP <Body> 元素中-->
          <wsdl:input name="receiveStandPointInfo"><soap:body namespace="http://robot.server.webService/" use="literal"></soap:body></wsdl:input>
          <wsdl:output name="receiveStandPointInfoResponse"><soap:body namespace="http://robot.server.webService/" use="literal"></soap:body></wsdl:output>
          <wsdl:fault name="Exception"><soap:fault name="Exception" use="literal"></soap:fault></wsdl:fault>
        </wsdl:operation>
        //---
        <wsdl:operation name="receiveInventoryResult">
          <soap:operation soapAction="" style="rpc"></soap:operation>
          <wsdl:input name="receiveInventoryResult">
            <soap:body namespace="http://robot.server.webService/" use="literal"></soap:body>
          </wsdl:input>
          <wsdl:output name="receiveInventoryResultResponse">
            <soap:body namespace="http://robot.server.webService/" use="literal"></soap:body>
          </wsdl:output>
          <wsdl:fault name="Exception">
            <soap:fault name="Exception" use="literal"></soap:fault>
          </wsdl:fault>
        </wsdl:operation>
        //--
        <!--literal 编码的优点是没有对正在传输的 XML 文档作任何限制。它的编码依赖于模式,因此是完全可扩展的。-->
        <wsdl:operation name="receiveTaskResult">
          <soap:operation soapAction="" style="rpc"></soap:operation>
          <wsdl:input name="receiveTaskResult">
            <soap:body namespace="http://robot.server.webService/" use="literal"></soap:body>
          </wsdl:input>
          <wsdl:output name="receiveTaskResultResponse">
            <soap:body namespace="http://robot.server.webService/" use="literal"></soap:body>
          </wsdl:output>
          <wsdl:fault name="Exception">
            <soap:fault name="Exception" use="literal"></soap:fault>
          </wsdl:fault>
        </wsdl:operation>
        //--
      </wsdl:binding>
      //----------------------------------------------------------服务器地址
      <!--将某个具体的绑定与网络上的一个或多个进程相关联,这些进程可以根据绑定所实现的 portType 来处理请求-->
      <!--文档样式的消息传递表示 SOAP <Body> 元素的内容是任意的 XML 文档。-->
      <!--尽管可以在请求-响应类型的通信方案中使用文档样式的消息传递,但是在异步通信中使用它非常理想,因为这个自包含的 XML 文档可以放入队列等待处理。-->
      <wsdl:service name="RobotWebServiceImplService">
        <wsdl:port binding="tns:RobotWebServiceImplServiceSoapBinding" name="RobotWebServiceImplPort">
          <soap:address location="http://soap.cn/service.php"></soap:address>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>

    ==

    参阅的网站:

    使用 PHP 开发基于 Web 服务的应用程序

    SOAP-ERROR: Parsing WSDL: Couldn't load from - but works on WAMP

    php soap连接https的wsdl报错SOAP-ERROR: Parsing WSDL:Couldn't load from

    PHP 生成WSDL 以及 提供SOAP服务

    Soap data gives Fatal error: Cannot use object of type stdClass as array in

  • 相关阅读:
    c语言寒假大作战02
    C语言寒假大作战01
    C语言I作业12
    C语言I博客作业11
    C语言I博客作业10
    C语言ll作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
  • 原文地址:https://www.cnblogs.com/hujun1992/p/wsdl.html
Copyright © 2011-2022 走看看