解决php soap webservice 用c++ soap调用的问题[转]
php是弱数据类型语言,而c++对语言又非常注重数据类型,因此,最近在研究php的soap webservice时遇到很大的问题,目前已经解决。
研究的目标是利用php 搭建webservice, 输入和输出参数都是array类型,元素为string类型。client为c++。
问题伊始,查阅了大量资料,这种模式貌似没有人使用。只有自己跟踪摸索,并且还有个php的bug(SOAP server return Procedure ' ' not present),还好,php team 在最新的5.2.5中已经修复了。
环境:winxp Apache/2.2.8 (Win32) PHP/5.2.5
程序如下:
PHP SOAP SERVER
<?php
class server {
/**
* run for webservice
*
* @param string[] $inputParam//
* @return string[]
*/
public function run($inputParam){
$Param=$inputParam->param->string;//关键点,获取stdClass对象内容
$obj=new stdClass;//关键点,设置stdClass对象内容作为返回参数
$obj->runResult->string=array($Param[0],'b','c','d','e');
return $obj;
}
}
$server = new SoapServer('ws.wsdl', array('soap_version' => SOAP_1_2,'encoding'=>'UTF-8'));
$server->setClass("server");
if (isset($HTTP_RAW_POST_DATA)) {
$request = $HTTP_RAW_POST_DATA;
} else {
$request = file_get_contents('php://input');
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$server->handle($request);
} else {
echo "This Webservice can handle following functions: <br>";
$functions = $server->getFunctions();
foreach($functions as $k=>$func) {
echo ($k+1).". ".$func . " <br>";
}
}
?>
class server {
/**
* run for webservice
*
* @param string[] $inputParam//
* @return string[]
*/
public function run($inputParam){
$Param=$inputParam->param->string;//关键点,获取stdClass对象内容
$obj=new stdClass;//关键点,设置stdClass对象内容作为返回参数
$obj->runResult->string=array($Param[0],'b','c','d','e');
return $obj;
}
}
$server = new SoapServer('ws.wsdl', array('soap_version' => SOAP_1_2,'encoding'=>'UTF-8'));
$server->setClass("server");
if (isset($HTTP_RAW_POST_DATA)) {
$request = $HTTP_RAW_POST_DATA;
} else {
$request = file_get_contents('php://input');
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$server->handle($request);
} else {
echo "This Webservice can handle following functions: <br>";
$functions = $server->getFunctions();
foreach($functions as $k=>$func) {
echo ($k+1).". ".$func . " <br>";
}
}
?>
WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn:some.com" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="urn:some.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="urn:some.com">
<s:complexType name="ArrayOfString">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="run">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="param" type="tns:ArrayOfString" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="runResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="runResult" type="tns:ArrayOfString" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="runSoapIn">
<wsdl:part name="parameters" element="tns:run" />
</wsdl:message>
<wsdl:message name="runSoapOut">
<wsdl:part name="parameters" element="tns:runResponse"/>
</wsdl:message>
<wsdl:portType name="Service1Soap">
<wsdl:operation name="run">
<wsdl:input message="tns:runSoapIn" />
<wsdl:output message="tns:runSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Service1Soap" type="tns:Service1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="run">
<soap:operation soapAction="urn:some.com/run" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="Service1Soap12" type="tns:Service1Soap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="run">
<soap12:operation soapAction="urn:some.com/run" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service1">
<wsdl:port name="Service1Soap" binding="tns:Service1Soap">
<soap:address location="http://localhost/ws/server.php" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn:some.com" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="urn:some.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="urn:some.com">
<s:complexType name="ArrayOfString">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="run">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="param" type="tns:ArrayOfString" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="runResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="runResult" type="tns:ArrayOfString" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="runSoapIn">
<wsdl:part name="parameters" element="tns:run" />
</wsdl:message>
<wsdl:message name="runSoapOut">
<wsdl:part name="parameters" element="tns:runResponse"/>
</wsdl:message>
<wsdl:portType name="Service1Soap">
<wsdl:operation name="run">
<wsdl:input message="tns:runSoapIn" />
<wsdl:output message="tns:runSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Service1Soap" type="tns:Service1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="run">
<soap:operation soapAction="urn:some.com/run" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="Service1Soap12" type="tns:Service1Soap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="run">
<soap12:operation soapAction="urn:some.com/run" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service1">
<wsdl:port name="Service1Soap" binding="tns:Service1Soap">
<soap:address location="http://localhost/ws/server.php" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>