版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/moeryang/article/details/82895322
<?php
ini_set("display_errors", "On");
class MyTestClass{
public function Hey($a) {
return "123 ha ha reutrn my Hey --- ".$a;
}
}
class MySoapServer{
public $aryClass;
public $class_name ="";
public $function_name ="";
public $parameter_name ="";
public $url ="";
public $service_name = "";
public function __construct(array $m_aryClass, $m_class_name, $m_function_name,
$m_parameter_name,
$m_url,
$m_service_name="MyPHPWS"
) {
$this->aryClass = $m_aryClass;
$this->class_name = $m_class_name;
$this->function_name = $m_function_name;
$this->parameter_name = $m_parameter_name;
$this->url = $m_url;
$this->service_name = $m_service_name;
}
/**
*@description:001 构建wsdl
*@param:类型,方法名称,参数名称,掉哟给地址,服务名称(随便,c#里面会体现为namespace),
*C#里面调用应该传入服务名称+Soap 的节点参数名
*@author:
*@date:
*/
public function create_wsdl(){
$parameter_name = $this->parameter_name;
$service_name = $this->service_name;
$url = $this->url ;
$class_name = $this->class_name;
$function_name = $this->function_name;
$xml ='
<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="http://tempuri.org/" 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="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="'. $function_name . '">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="'.$parameter_name.'" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="' . $class_name . '">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="' . $function_name . 'Result" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="' . $function_name . 'SoapIn">
<wsdl:part name="parameters" element="tns:' . $function_name . '" />
</wsdl:message>
<wsdl:message name="' . $function_name . 'SoapOut">
<wsdl:part name="parameters" element="tns:' . $class_name . '" />
</wsdl:message>
<wsdl:portType name="'. $service_name . 'Soap">
<wsdl:operation name="' . $function_name . '">
<wsdl:input message="tns:' . $function_name . 'SoapIn" />
<wsdl:output message="tns:' . $function_name . 'SoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="' . $service_name . 'Soap" type="tns:' . $service_name . 'Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="' . $function_name . '">
<soap:operation soapAction="http://tempuri.org/' . $function_name . '" 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="' . $service_name . 'Soap12" type="tns:' . $service_name . 'Soap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="TestFunction">
<soap12:operation soapAction="http://tempuri.org/' . $function_name . '" 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="' . $service_name . '">
<wsdl:port name="' . $service_name . 'Soap" binding="tns:' . $service_name . 'Soap">
<soap:address location="'. $url .'" />
</wsdl:port>
<wsdl:port name="' . $service_name . 'Soap12" binding="tns:' . $service_name . 'Soap12">
<soap12:address location="' . $url . '" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>';
return $xml;
}
/**
*@description:002 输出调用结果
*@param: 用来反射的数组[类对象,方法],类名,方法名,方法参数
*@author:
*@date:
*/
public function reponse_result($xml){
$aryFuncParameter = array();
$p = $this->get_parameter_value($xml);
if (!empty($p)){
$aryFuncParameter[] = $p ;
}
$class_name = $this->class_name;
$function_name = $this->function_name;
$handler = $this->aryClass;
// [new MyTestClass(), 'Hey'];
if (is_callable($handler)) {
$data = call_user_func_array($handler, $aryFuncParameter);
};
header("Content-Type: text/xml; charset=utf-8");
$xml = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<'.$class_name.' xmlns="http://tempuri.org/">
<'. $function_name .'Result>' . $data . '</'. $function_name.'Result>
</'.$class_name.'>
</soap:Body>
</soap:Envelope>';
echo $xml;
}
/**
*@description: 解析调用方回传的参数
*@param:
*@author:
*@date:
*/
private function get_parameter_value($xml)
{
//var_dump($xml);
//exit;
$parameter_name = $this->parameter_name;
$aryResult = array();
$xml = str_replace(chr(13),'',$xml);
$xml = str_replace(chr(10), '', $xml);
$xml = str_replace("\r", '', $xml);
$xml = str_replace("\n", '', $xml);
preg_match_all("|<$parameter_name>(.+)</$parameter_name>|", $xml, $aryResult);
if (count($aryResult)>1 && count($aryResult[0])){
return $aryResult[1][0];
}
else{
return "";
}
}
}
//执行 url 就是当前文件的地址
$s = new MySoapServer([new MyTestClass(), 'Hey'], "MyTestClass","Hey","a","http://10.74.12.7:88/t1.php", "MyTestsClassWS");
if (isset($_GET) && count($_GET)>0){
header("Content-Type: text/xml; charset=utf-8");
echo $s->create_wsdl();
}
else{
$xml = file_get_contents(("php://input")) ;
if ($xml){
$s->reponse_result($xml);
}
else{
echo "no data";
}
}
以上是代码。
PHP提供的SoapServer 来写webservice,不过对于C#或者JAVA 需要提供WSDL的,真是一个灾难,它没法自动生成。
webservice 本质上就是一个HTTP POST的调用,所以只要构造好XML然后处理POST参数,再反射PHP类即可。
WSDL 的说明https://www.w3.org/TR/wsdl/在这里,是的又丑又长。
我的WSDL是用C#的asmx文件生成,所以这个php的webservice 用c#也是测试过。
只提供一个简单的class和一个简单的方法,不过你可以传json进去也可以返回出json。好吧,又回到HTTP API了。
这年头,还用webservice的也是耍流氓,我们是PHP不是JAVA和C#,只负责调用,要我们提供,变态啊。