我的 SOAP 服务器(打算)设置了三个操作:登录、注销和版本。
登录函数的代码目前正在“伪造”它,接受两个参数,用户名和密码,通过将它们存储在函数类的私有用户名和密码变量中来自动“验证”它们。我在 Web 服务操作的入口点启动了一个会话,并且在初始化期间在 SoapServer 中设置函数类时,我将保持连接如下:
$this->setClass('WebSvcSoapFunctions');
$this->setPersistence(SOAP_PERSISTENCE_SESSION);
当我创建一个 SOAP CLIENT 并调用我的服务时,无论调用哪个函数,似乎总是执行 version() 函数而不是调用的函数。我想这可能是由于我的 WSDL 的编写方式,但我看不到问题(我是新人)....
我通过 PHP SoapServer 监听了以下 WSDL:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:types>
<schema xmlns:rns="http://soap.jrimer-amp64/" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soap.jrimer-amp64/" version="1.0.0" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<complexType name="versionRequest">
</complexType>
<complexType name="versionResponse">
<sequence>
<element name="result" type="string" minOccurs="1"/>
</sequence>
</complexType>
<complexType name="loginRequest">
<sequence>
<element name="username" type="string" use="required"/>
<element name="password" type="string" use="required"/>
</sequence>
</complexType>
<complexType name="loginResponse">
<sequence>
<element name="result" type="string" minOccurs="1"/>
</sequence>
</complexType>
<complexType name="logoutRequest">
</complexType>
<complexType name="logoutResponse">
<sequence>
<element name="result" type="string" minOccurs="1"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:service name="XxxxxxSvc">
<wsdl:port name="XxxxxxSvc-Endpoint0" binding="tns:XxxxxxSvc-Endpoint0Binding">
<soap:address location="http://soap.jrimer-amp64/"/>
</wsdl:port>
</wsdl:service>
<wsdl:portType name="portType">
<wsdl:operation name="version">
<wsdl:input message="tns:versionRequest"/>
<wsdl:output message="tns:versionResponse"/>
</wsdl:operation>
<wsdl:operation name="login">
<wsdl:input message="tns:loginRequest"/>
<wsdl:output message="tns:loginResponse"/>
</wsdl:operation>
<wsdl:operation name="logout">
<wsdl:input message="tns:logoutRequest"/>
<wsdl:output message="tns:logoutResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="XxxxxxSvc-Endpoint0Binding" type="tns:portType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="version">
<soap:operation style="document" soapAction="http://soap.jrimer-amp64/"/>
<wsdl:input>
<soap:body use="literal" parts="parameters"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="parameters"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="login">
<soap:operation style="document" soapAction="http://soap.jrimer-amp64/"/>
<wsdl:input>
<soap:body use="literal" parts="parameters"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="parameters"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="logout">
<soap:operation style="document" soapAction="http://soap.jrimer-amp64/"/>
<wsdl:input>
<soap:body use="literal" parts="parameters"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" parts="parameters"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:message name="versionRequest">
<wsdl:part name="parameters" element="ns0:versionRequest"/>
</wsdl:message>
<wsdl:message name="versionResponse">
<wsdl:part name="parameters" element="ns0:versionResponse"/>
</wsdl:message>
<wsdl:message name="loginRequest">
<wsdl:part name="parameters" element="ns0:loginRequest"/>
</wsdl:message>
<wsdl:message name="loginResponse">
<wsdl:part name="parameters" element="ns0:loginResponse"/>
</wsdl:message>
<wsdl:message name="logoutRequest">
<wsdl:part name="parameters" element="ns0:logoutRequest"/>
</wsdl:message>
<wsdl:message name="logoutResponse">
<wsdl:part name="parameters" element="ns0:logoutResponse"/>
</wsdl:message>
我的 SOAP 函数类如下(通过 setClass() 包含在我的 SOapServer 中):
class WebSvcSoapFunctions
{
private $username = ''; // username provided by the client during login() request
private $password = ''; // password provided by the client during login() request
/**
* Handle a login request
*
* @param string $user - Client's Username
* @param string $pass - Client's Password
*/
public function login($user,$pass)
{
$this->username = $user;
$this->password = $pass;
// should check for validity here, but for testing, return true.
return 'Successful Login. Welcome, '.$user;
}
/**
* Logs the client out.
*
*/
public function logout()
{
$this->username = '';
$this->password = '';
$_SESSION = array();
session_destroy();
return 'Logged Out Successfully.';
}
/**
* checks if the client has logged in successfully
*
* @return bool - true=logged in, false = unauthenticated
*/
private function isAuthenticated()
{
if (isset($this->username) && $this->username != '')
{
return true;
}
else
{
return false;
}
}
/**
* Returns the version of the SOAP Server to the requesting client
*
*/
public function version()
{
if ($this->isAuthenticated())
{
return 'Affinegy Service v1.0.0';
}
else
{
return 'NOT AUTHORIZED.';
}
}
}
我的 SOAP CLIENT 测试类如下:
ini_set("soap.wsdl_cache_enabled", "0");
define('WSDL_URL','http://soap.jrimer-amp64/?wsdl');
try
{
$client = new SoapClient(WSDL_URL, array('trace'=>true));
$request = 'version';
$args = array();
$SOAPResult = $client->$request($args); // call the SOAP Server's "version" function
OutputLastRequestResponse($client, $request, $args, $SOAPResult);
$request = 'login';
$args['username'] = 'testuser';
$args['password'] = '1234';
$SOAPResult = $client->$request($args); // call the SOAP Server's "login" function
OutputLastRequestResponse($client, $request, $args, $SOAPResult);
$request = 'version';
$args = array();
$SOAPResult = $client->$request($args); // call the SOAP Server's "version" function
OutputLastRequestResponse($client, $request, $args, $SOAPResult);
$request = 'logout';
$args = array();
$SOAPResult = $client->$request($args); // call the SOAP Server's "logout" function
OutputLastRequestResponse($client, $request, $args, $SOAPResult);
$request = 'version';
$SOAPResult = $client->$request($args); // call the SOAP Server's "version" function
OutputLastRequestResponse($client, $request, $args, $SOAPResult);
}
catch (Exception $e)
{
echo '<pre>FAILED: '.print_r($e,1).'</pre>'; // dump the client exception to screen
OutputLastRequestResponse($client);
}
/**
* Displays the request and response of the test service call
*
* @param SoapServer $client - Object of type SoapClient that does the request
* @param string $requested - name of the SOAP function called
* @param array $args - Arguments sent to the SOAP function
* @param string $returned - PHP readable value returned by the client calling the provided SOAP function
*/
function OutputLastRequestResponse($client, $requested = '', $args=array(), $returned='')
{
echo '<h1>XXXXXXXX SERVICE SOAP SERVER TEST</h1>';
echo 'Request: <pre>'.$requested.'</pre>';
echo 'Request Arguments: <pre>'.print_r($args,1).'</pre>';
echo 'Returned: <pre>'.$returned.'</pre>';
echo 'Raw Request: <pre>'.htmlspecialchars($client->__getLastRequestHeaders());
echo htmlspecialchars($client->__getLastRequest()).'</pre>';
echo 'Raw Response: <pre>'.htmlspecialchars($client->__getLastResponseHeaders())."\n";
echo htmlspecialchars($client->__getLastResponse()).'</pre>';
}
测试类运行的结果如下...注意“未授权”。是对所有内容的响应,表明只有 WebSvcSoapFunctions::version() 函数正在运行
Xxxxxx SERVICE SOAP 服务器测试请求:
版本
请求参数:
大批 ( )
回来:
未经授权。
原始请求:
POST / HTTP/1.1 主机:soap.jrimer-amp64 连接:Keep-Alive 用户代理:PHP-SOAP/5.2.10 内容类型:text/xml;charset=utf-8 SOAPAction:“http://soap.jrimer-amp64/”内容长度:227
原始响应:
HTTP/1.1 200 OK 日期:2011 年 6 月 16 日星期四 19:43:32 GMT 服务器:Apache/2.2.3 (CentOS) X-Powered-By: PHP/5.2.10 Set-Cookie: PHPSESSID=scbuin269990ahfargfq7k0972; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-长度:209 连接:关闭 内容类型:text/xml;字符集=utf-8
未经授权。
Xxxxxx SERVICE SOAP 服务器测试请求:
登录
请求参数:
数组([用户名] => jrimer [密码] => 1234)
回来:
未经授权。
原始请求:
POST / HTTP/1.1 主机:soap.jrimer-amp64 连接:Keep-Alive 用户代理:PHP-SOAP/5.2.10 内容类型:text/xml;charset=utf-8 SOAPAction:“http://soap.jrimer-amp64/” 内容长度:298 Cookie:PHPSESSID=scbuin269990ahfargfq7k0972;
用户名jrimerpassword1234
原始响应:
HTTP/1.1 200 OK 日期:2011 年 6 月 16 日星期四 19:43:32 GMT 服务器:Apache/2.2.3 (CentOS) X-Powered-By:PHP/5.2.10 到期时间:1981 年 11 月 19 日星期四 08:52: 00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 209 Connection: close Content-Type: text/xml; 字符集=utf-8
未经授权。
Xxxxxx SERVICE SOAP 服务器测试请求:
版本
请求参数:
大批 ( )
回来:
未经授权。
原始请求:
POST / HTTP/1.1 主机:soap.jrimer-amp64 连接:Keep-Alive 用户代理:PHP-SOAP/5.2.10 内容类型:text/xml;charset=utf-8 SOAPAction:“http://soap.jrimer-amp64/”内容长度:227 Cookie:PHPSESSID=scbuin269990ahfargfq7k0972;
原始响应:
HTTP/1.1 200 OK 日期:2011 年 6 月 16 日星期四 19:43:32 GMT 服务器:Apache/2.2.3 (CentOS) X-Powered-By:PHP/5.2.10 到期时间:1981 年 11 月 19 日星期四 08:52: 00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 209 Connection: close Content-Type: text/xml; 字符集=utf-8
未经授权。
Xxxxxx SERVICE SOAP 服务器测试请求:
登出
请求参数:
大批 ( )
回来:
未经授权。
原始请求:
POST / HTTP/1.1 主机:soap.jrimer-amp64 连接:Keep-Alive 用户代理:PHP-SOAP/5.2.10 内容类型:text/xml;charset=utf-8 SOAPAction:“http://soap.jrimer-amp64/”内容长度:227 Cookie:PHPSESSID=scbuin269990ahfargfq7k0972;
原始响应:
HTTP/1.1 200 OK 日期:2011 年 6 月 16 日星期四 19:43:32 GMT 服务器:Apache/2.2.3 (CentOS) X-Powered-By:PHP/5.2.10 到期时间:1981 年 11 月 19 日星期四 08:52: 00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 209 Connection: close Content-Type: text/xml; 字符集=utf-8
未经授权。
Xxxxxx SERVICE SOAP 服务器测试请求:
版本
请求参数:
大批 ( )
回来:
未经授权。
原始请求:
POST / HTTP/1.1 主机:soap.jrimer-amp64 连接:Keep-Alive 用户代理:PHP-SOAP/5.2.10 内容类型:text/xml;charset=utf-8 SOAPAction:“http://soap.jrimer-amp64/”内容长度:227 Cookie:PHPSESSID=scbuin269990ahfargfq7k0972;
原始响应:
HTTP/1.1 200 OK 日期:2011 年 6 月 16 日星期四 19:43:32 GMT 服务器:Apache/2.2.3 (CentOS) X-Powered-By:PHP/5.2.10 到期时间:1981 年 11 月 19 日星期四 08:52: 00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 209 Connection: close Content-Type: text/xml; 字符集=utf-8
未经授权。
有什么想法吗?
注意:我注意到,如果我只是在 WSDL 中为 VERSION 函数注释掉定义,那么下一个定义的函数将成为“始终调用”函数(登录)......我在该 WSDL 中配置了什么错误?