j2ee|php5|web|web服务|程序|访问
PHP Weather 客户机
这一节将建立我们自己的 PHP Weather 客户机。这里提供了一些代码片段,建议下载完整的客户机和 WSDL 文件。
用于表示 Weather Service 的 ext/soap 类是 SoapClient。正如我们介绍 Weather Forecast 应用程序时所讨论的,我们知道应用服务器在 http://host:port/ItsoWebServer2RouterWeb/wsdl/itso/session/WeatherForecastEJB.wsdl 中提供了 WSDL。我们使用的是默认端口,并且在作为服务器的计算机上工作,这样就可以通过查找 WSDL 文件创建第一个 SoapClient:
<?php
$soapClient = new SoapClient("http://localhost:9080/" .
"ItsoWebService2RouterWeb/wsdl/itso/session/WeatherForecastEJB.wsdl");
?>
注意,因为 ext/soap 是内置的,所以,在引用 SoapClient 之前,不需要任何 include 或 require 语句。
现在已经实例化了客户机,还要联系 Weather 服务,并调用它的 getForecast 操作。在 WSDL 模式下使用 SoapClient 时,ext/soap 有一种很好的特性,即可以直接引用远程操作,就像它是 SoapClient 自身的函数一样。但是在建立输入参数时需要一点技巧。ext/soap 可以提供从 WSDL 中发现的操作和参数的数组:
$functions = $soapClient->__getFunctions();
print_r($functions);
$types = $soapClient->__getTypes();
print_r($types);
只需要显示与 getForecast 相关的结果,并重新格式化这些结果,以方便阅读,于是我们看到以下代码:
getForecastResponse getForecast(getForecast $parameters)
struct getForecast {
dateTime startDate;
int days;
}
struct getForecastResponse {
Weather getForecastReturn;
}
struct Weather {
string condition;
dateTime date;
string windDirection;
int windSpeed;
int temperatureCelsius;
boolean dbflag;
}
ext/soap 实际上并没有为我们定义 getForecast 类,我们必须创建该操作所需要的输入参数数组:
$getForecastParam = array('startDate' =>time(), 'days' => 3);
然后像 SoapClient 的方法那样调用该操作:
$forecastResponse = $soapClient->getForecast($getForecastParam);
最后我们得到了返回的 getForecastResponse 对象,它本身是一个 Weather 对象数组,然后在表格中显示结果:
echo "<table border=1 cellpadding=5>";
echo "<tr><th>Date</th><th>Condition</th><th>Temperature</th><th>Wind</th></tr>";
$weatherArray = $forecastResponse->getForecastReturn;
foreach ($weatherArray as $weather) {
echo "<tr>",
"<td>",strftime("%a. %b %d, %Y", strtotime($weather->date)),"</td>",
"<td>$weather->condition</td>",
"<td>$weather->temperatureCelsius</td>",
"<td>$weather->windDirection $weather->windSpeed</td>",
"</tr>";
}
echo "</table>";
PHP 客户机与 Java 客户机的输出相同,于是我们知道圣诞节期间 San Jose 不会下雪……
图 3. PHP WeatherClient
观察 SOAP 流
我们成功地与 Weather 服务取得了联系,并显示了结果。但是如果出现错误,得不到预期的结果,该怎么办?ext/soap 可以显示客户机与服务器之间交换的 SOAP 消息,能够帮助我们确定问题所在。
只有使用 trace 选项创建 SoapClient 时,才要使用跟踪功能。我们在 options 数组参数中设置 trace 选项,将该参数传递给 SoapClient 构造函数。我们将构造函数的使用改为:
$soapClient = new SoapClient("http://localhost:9080/" .
"ItsoWebService2RouterWeb/wsdl/itso/session/WeatherForecastEJB.wsdl",
array('trace' => 1));
并在调用 goForecast 之后调用 trace 方法:
echo "Request :<br>", htmlspecialchars($soapClient->__getLastRequest()), "<br>";
echo "Response :<br>", htmlspecialchars($soapClient->__getLastResponse()), "<br>";
一定要使用 htmlspecialchars 内置函数对 trace 输出进行编码,因为它将 SOAP xml 分界符转换成特殊字符,如
下面是某个请求的 trace 输出:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://session.itso">
<SOAP-ENV:Body>
<ns1:getForecast>
<ns1:startDate>2004-11-30T13:41:59</ns1:startDate>
<ns1:days>0</ns1:days>
</ns1:getForecast>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
对应的应答是:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getForecastResponse xmlns="http://session.itso">
<getForecastReturn xmlns:ns-239399687="http://mapping.itso">
<ns-239399687:condition>sunny</ns-239399687:condition>
<ns-239399687:date>2004-11-30T00:00:00.000Z</ns-239399687:date>
<ns-239399687:windDirection>W</ns-239399687:windDirection>
<ns-239399687:windSpeed>18</ns-239399687:windSpeed>
<ns-239399687:temperatureCelsius>6</ns-239399687:temperatureCelsius>
<ns-239399687:dbflag>1</ns-239399687:dbflag>
</getForecastReturn>
</getForecastResponse>
</soapenv:Body>
</soapenv:Envelope>
如果在开启跟踪功能的情况下运行客户机来收集这些输出,那么需要将 days 参数设置为 0,只有这样做,SOAP 应答才会输出较少的行。但是我们遇到了没有预料到的行为。我们本来期望 getForecastResponse 和以前一样是一个 Weather 对象数组,但是它应该只有一个元素,而不是 4 个元素。然而,它被转换成了一个简单的 Weather 对象,我们必须根据这种行为进行编码,就像您在最终的示例 PHP 客户机代码中看到的那样。这与 Java 客户机的行为有所不同,在客户机行为中,getForecast 总是返回 Weather 对象数组,无论服务器响应中有多少个 Weather 对象。SoapClient::_getTypes() 输出并没有为我们理解这种差异提供足够的细节,因此我们要求助于 WSDL 文档来了解完整的接口规范。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

禅工作室 13.0.1
功能强大的PHP集成开发环境

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

Dreamweaver CS6
视觉化网页开发工具