核心概念
我们需要明确几个关键点:

- WebService 协议:最经典和广泛支持的协议是 SOAP (Simple Object Access Protocol),它使用 XML 格式进行数据交换,并通过 WSDL (Web Services Description Language) 文件来描述服务的接口(有哪些方法、参数、返回值类型等),我们这里主要讲解调用 SOAP WebService。
- PHP 的 SOAP 扩展:PHP 内置了
SOAP扩展,这是处理 SOAP 协议最直接、最高效的方式,确保你的 PHP 环境已经启用了这个扩展(在php.ini中检查extension=soap是否被取消注释)。 - Java WebService 框架:Java 世界里创建 WebService 的工具有很多,如 Apache Axis2, Apache CXF, JAX-WS (Java API for XML Web Services) 等,它们生成的 WSDL 文件格式略有不同,但都遵循 SOAP 标准,PHP 客户端的调用方法是通用的。
使用 PHP 原生 SOAP 扩展(最推荐)
这是最标准、最简单、性能最好的方法,PHP 的 SoapClient 类可以直接通过 WSDL 地址来创建客户端,并自动解析所有可用的方法。
步骤 1:获取 WSDL 文件地址
你的 Java WebService 必须提供一个 WSDL 文件,通常这个文件的地址是 http://your-java-server/your-service?wsdl,Java 使用 JAX-WS 框架部署的服务,通常会有这样一个地址。
步骤 2:编写 PHP 客户端代码
假设我们有一个 Java WebService,它提供一个 getUserInfo 方法,需要一个 userId 字符串参数,并返回一个包含用户信息的复杂对象。
创建 PHP 脚本 (client.php)

<?php
// 1. 设置 WSDL 文件的 URL
$wsdl = 'http://your-java-server/YourService?wsdl';
// 2. 创建 SoapClient 实例
// 第一个参数是 WSDL URL
// 第二个参数是选项数组,'trace' => true 非常有用,可以开启 SOAP 请求/响应的追踪
$client = new SoapClient($wsdl, ['trace' => 1, 'exceptions' => true]);
// 3. 准备调用服务所需的参数
// 参数必须是一个数组,键是参数名,值是对应的值。
// 这个参数名需要和 WSDL 文件中定义的参数名一致。
$params = [
'userId' => '12345'
];
// 4. 调用 WebService 方法
// 方法名 'getUserInfo' 必须和 WSDL 中定义的操作名一致。
try {
$result = $client->getUserInfo($params);
// 5. 处理返回结果
// $result 是一个 PHP 对象或数组,其结构由 WSDL 定义。
echo "调用成功!\n";
echo "返回结果: \n";
print_r($result);
// 如果开启了 'trace',可以查看详细的 SOAP 请求和响应
echo "\n--- SOAP 请求 ---\n";
echo $client->__getLastRequest();
echo "\n--- SOAP 响应 ---\n";
echo $client->__getLastResponse();
} catch (SoapFault $e) {
// 捕获 SOAP 错误
echo "SOAP 错误: [{$e->faultcode}] {$e->faultstring}\n";
echo "请求详情: \n";
echo $client->__getLastRequest();
} catch (Exception $e) {
// 捕获其他异常
echo "发生错误: " . $e->getMessage();
}
?>
运行脚本
在命令行中执行:
php client.php
代码解释
new SoapClient($wsdl, [...]): 这是核心,PHP 会自动下载并解析 WSDL 文件,生成一个客户端代理对象,之后你就可以像调用本地方法一样调用远程服务的方法。$params: 参数数组。键名必须与 WSDL 中定义的参数名完全匹配,这是最容易出错的地方,WSDL 中参数是userId,你就不能用id。$client->getUserInfo($params): 调用方法,PHP 会自动将 PHP 数组/对象序列化为符合 SOAP 规范的 XML 请求,发送给服务器,并接收服务器返回的 XML 响应,然后反序列化为 PHP 的对象或数组。SoapFault: 当服务端返回一个 SOAP 错误(参数类型错误、服务内部错误等)时,会抛出SoapFault异常。try...catch块是必不可少的。__getLastRequest()和__getLastResponse(): 当选项中设置'trace' => 1时,这两个方法会非常有用,当调用失败时,你可以打印出它们的内容,查看发送了什么 XML 给服务器,服务器又返回了什么 XML,这对于调试非常有帮助。
使用 WSDL 生成 PHP 客户端代码(辅助方法)
WSDL 结构非常复杂,或者你想提前在代码中看到所有可用的方法和参数结构,你可以使用 PHP 内置的 wsdl2php.php 工具来生成一个包装类。
步骤
-
找到
wsdl2php.php工具 这个工具通常位于 PHP 的安装目录下,C:\php\extras\soap\wsdl2php.php(Windows) 或/usr/share/php/Soap/wsdl2php.php(Linux)。 -
运行命令生成代码 在命令行中执行以下命令:
php /path/to/wsdl2php.php --location=http://your-java-server/YourService?wsdl --output-dir=./generated_client
--location: 你的 WSDL 地址。--output-dir: 生成的 PHP 类文件存放的目录。
-
使用生成的客户端类 执行命令后,你会在
generated_client目录下得到一个或多个 PHP 文件(通常一个服务对应一个类文件),然后你就可以在代码中include并使用它了。<?php require_once './generated_client/YourService.php'; // 引入生成的类 $wsdl = 'http://your-java-server/YourService?wsdl'; $client = new YourService(['trace' => 1]); // 直接使用生成的类 $params = ['userId' => '12345']; $result = $client->getUserInfo($params); print_r($result); ?>
这种方法的好处是代码提示更好(如果你使用 IDE),但通常不如直接使用
SoapClient简洁。
使用 cURL 手动发送 SOAP 请求(不推荐,仅作了解)
如果因为某些原因(PHP 环境无法安装 SOAP 扩展,或者服务端有特殊的 HTTP 头要求),你不能使用 SoapClient,你可以手动构建 SOAP 请求的 XML,并通过 cURL 发送。
这种方法非常繁琐,因为你需要自己处理 XML 的构建、SOAPAction 头的设置、以及 XML 响应的解析。
<?php
$wsdlUrl = 'http://your-java-server/YourService?wsdl';
$endpointUrl = 'http://your-java-server/YourService'; // 实际的请求地址,可能和 WSDL 不同
// 1. 手动构建 SOAP 请求 XML
$soapRequest = <<<XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://your.service.namespace/">
<soapenv:Header/>
<soapenv:Body>
<ser:getUserInfo>
<!--Optional:-->
<ser:userId>12345</ser:userId>
</ser:getUserInfo>
</soapenv:Body>
</soapenv:Envelope>
XML;
// 2. 初始化 cURL
$ch = curl_init();
// 3. 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $endpointUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $soapRequest);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "http://your.service.namespace/YourService/getUserInfo"' // SOAPAction 必须和 WSDL 中的 Action 匹配
]);
// 4. 执行请求并获取响应
$response = curl_exec($ch);
// 5. 检查错误
if (curl_errno($ch)) {
echo 'c 