php的soap方法怎么调用

发布时间:2021-11-30 11:33:05 作者:iii
来源:亿速云 阅读:206
# PHP的SOAP方法怎么调用

## 一、SOAP协议基础概念

### 1.1 什么是SOAP协议

SOAP(Simple Object Access Protocol)简单对象访问协议是一种基于XML的通信协议,用于在Web服务之间交换结构化信息。它被设计用来在分布式环境中实现应用程序之间的通信,具有以下核心特点:

- **平台无关性**:可以在任何操作系统上运行
- **语言独立性**:支持多种编程语言实现
- **基于XML**:所有消息都采用XML格式编码
- **传输协议无关**:可通过HTTP、SMTP等多种协议传输

### 1.2 SOAP与REST的区别

| 特性        | SOAP                          | REST                   |
|-----------|-------------------------------|------------------------|
| 协议        | 严格定义的协议规范                   | 架构风格,非正式协议          |
| 消息格式      | 仅XML                          | XML/JSON/纯文本等         |
| 传输协议      | HTTP/SMTP等                    | 通常仅HTTP              |
| 安全性       | WS-Security等内置安全标准            | 依赖HTTPS等传输层安全       |
| 性能        | 相对较低(XML解析开销大)              | 相对较高                 |
| 适用场景      | 企业级应用、高安全性要求的系统            | 移动应用、快速开发场景         |

### 1.3 SOAP消息结构剖析

一个完整的SOAP消息包含以下部分:

```xml
<?xml version="1.0"?>
<soap:Envelope
  xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
  soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
  
  <soap:Header>
    <!-- 可选头部信息,如认证令牌 -->
  </soap:Header>
  
  <soap:Body>
    <!-- 实际请求或响应内容 -->
    <m:GetProductPrice xmlns:m="http://example.org/product">
      <m:ProductID>12345</m:ProductID>
    </m:GetProductPrice>
  </soap:Body>
  
  <soap:Fault>
    <!-- 错误时出现 -->
  </soap:Fault>
</soap:Envelope>

二、PHP SOAP扩展环境配置

2.1 安装SOAP扩展

在大多数PHP环境中,SOAP扩展默认不启用。安装方法如下:

Linux环境(Ubuntu/Debian)

sudo apt-get install php-soap
sudo systemctl restart apache2

Windows环境: 1. 打开php.ini文件 2. 取消注释或添加:extension=soap 3. 重启Web服务器

2.2 验证安装

创建测试脚本soap_test.php

<?php
phpinfo();
?>

在浏览器中访问该文件,搜索”soap”应能看到SOAP扩展的相关信息。

2.3 常见配置参数

在php.ini中可以配置以下SOAP相关参数:

[soap]
; 是否启用WSDL缓存
soap.wsdl_cache_enabled=1
; WSDL缓存目录
soap.wsdl_cache_dir="/tmp"
; 缓存有效期(秒)
soap.wsdl_cache_ttl=86400

三、PHP SOAP客户端开发

3.1 创建SOAP客户端基础方法

PHP提供了SoapClient类用于创建SOAP客户端:

$client = new SoapClient(
    "http://example.com/service.wsdl",
    [
        'trace' => 1,      // 启用跟踪以便调试
        'exceptions' => 1, // 抛出SOAP异常
        'cache_wsdl' => WSDL_CACHE_NONE // 开发时禁用缓存
    ]
);

3.2 调用远程方法

假设服务端提供了getUserInfo方法:

try {
    $response = $client->__soapCall('getUserInfo', [
        ['userId' => 123]
    ]);
    
    // 或者直接调用
    $response = $client->getUserInfo(['userId' => 123]);
    
    print_r($response);
} catch (SoapFault $e) {
    echo "SOAP Error: " . $e->getMessage();
}

3.3 处理复杂类型

当需要传递复杂对象时:

class User {
    public $id;
    public $name;
    public $email;
}

$user = new User();
$user->id = 123;
$user->name = "John Doe";
$user->email = "john@example.com";

$response = $client->updateUser(['user' => $user]);

3.4 调试技巧

// 获取最后请求的XML
echo "Request: \n" . $client->__getLastRequest() . "\n";

// 获取最后响应的XML
echo "Response: \n" . $client->__getLastResponse() . "\n";

// 获取所有可用方法
print_r($client->__getFunctions());

// 获取类型信息
print_r($client->__getTypes());

四、PHP SOAP服务端开发

4.1 创建SOAP服务端基础

class ProductService {
    /**
     * @param int $id
     * @return float
     */
    public function getPrice($id) {
        // 实际业务逻辑
        return 99.99;
    }
}

$server = new SoapServer("service.wsdl");
$server->setClass("ProductService");
$server->handle();

4.2 WSDL文件生成

可以使用工具如php-wsdl-creator或手动编写:

<!-- service.wsdl -->
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
             targetNamespace="http://example.com/product">
    
    <types>
        <xsd:schema>
            <xsd:element name="getPriceRequest">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="id" type="xsd:int"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="getPriceResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="price" type="xsd:float"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:schema>
    </types>
    
    <message name="getPriceInput">
        <part name="parameters" element="tns:getPriceRequest"/>
    </message>
    <message name="getPriceOutput">
        <part name="parameters" element="tns:getPriceResponse"/>
    </message>
    
    <portType name="ProductPortType">
        <operation name="getPrice">
            <input message="tns:getPriceInput"/>
            <output message="tns:getPriceOutput"/>
        </operation>
    </portType>
    
    <binding name="ProductBinding" type="tns:ProductPortType">
        <soap:binding style="document" 
                      transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="getPrice">
            <soap:operation soapAction="http://example.com/getPrice"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    
    <service name="ProductService">
        <port name="ProductPort" binding="tns:ProductBinding">
            <soap:address location="http://example.com/soap_server.php"/>
        </port>
    </service>
</definitions>

4.3 处理身份验证

class SecureService {
    private $validTokens = ['12345', '67890'];
    
    public function __construct() {
        $this->checkAuth();
    }
    
    private function checkAuth() {
        $headers = getallheaders();
        if (!isset($headers['Authorization'])) {
            throw new SoapFault('Server', 'Unauthorized');
        }
        
        $token = str_replace('Bearer ', '', $headers['Authorization']);
        if (!in_array($token, $this->validTokens)) {
            throw new SoapFault('Server', 'Invalid token');
        }
    }
    
    public function sensitiveOperation() {
        return "Secret data";
    }
}

$server = new SoapServer("secure.wsdl");
$server->setClass("SecureService");
$server->handle();

五、高级应用与最佳实践

5.1 处理附件(MTOM)

// 客户端发送附件
$client = new SoapClient('service.wsdl', [
    'stream_context' => stream_context_create([
        'http' => [
            'header' => 'Content-Type: application/xop+xml'
        ]
    ]),
    'features' => SOAP_SINGLE_ELEMENT_ARRAYS
]);

// 服务端接收附件
if (isset($HTTP_RAW_POST_DATA)) {
    $data = $HTTP_RAW_POST_DATA;
} else {
    $data = file_get_contents('php://input');
}

5.2 性能优化建议

  1. WSDL缓存:生产环境启用WSDL缓存
  2. 连接复用:重用SoapClient实例
  3. 精简数据:减少传输数据量
  4. 异步处理:耗时操作采用异步方式

5.3 常见错误排查

  1. “Could not connect to host”

    • 检查服务URL是否正确
    • 验证网络连接
    • 检查防火墙设置
  2. “Function not found”

    • 检查方法名拼写
    • 验证WSDL是否最新
    • 检查服务端是否实现了该方法
  3. “Invalid XML”

    • 检查特殊字符处理
    • 验证XML格式是否正确
    • 使用__getLastRequest()查看原始请求

5.4 实际案例:天气预报服务

// 客户端代码
$weather = new SoapClient(
    "http://www.webservicex.net/globalweather.asmx?WSDL",
    ['trace' => 1]
);

try {
    $response = $weather->GetWeather([
        'CityName' => 'New York',
        'CountryName' => 'United States'
    ]);
    
    echo "Weather Info: \n";
    print_r($response);
} catch (SoapFault $e) {
    echo "Error: " . $e->getMessage();
    echo "\nRequest: " . $weather->__getLastRequest();
}

六、安全注意事项

  1. 输入验证:始终验证SOAP请求的输入数据
  2. 敏感信息:不要在SOAP消息中直接传输敏感数据
  3. HTTPS:生产环境必须使用HTTPS
  4. 限流措施:防止API滥用
  5. 错误处理:避免暴露系统内部信息

七、替代方案与未来趋势

虽然SOAP仍在许多企业系统中使用,但RESTful API已成为主流。考虑以下场景选择技术:

新兴技术如gRPC也提供了强大的跨语言服务调用能力,可以作为现代替代方案。

结语

PHP的SOAP扩展提供了完整的Web服务实现方案,虽然学习曲线较陡,但在特定场景下仍是不可或缺的技术。掌握SOAP开发需要理解XML、WSDL等底层技术,但一旦掌握,可以轻松集成各种企业级系统。建议开发者在实际项目中根据需求选择合适的Web服务技术,平衡开发效率与系统需求。

注意:本文示例代码需要根据实际环境调整,部分Web服务可能需要注册或认证才能使用。 “`

推荐阅读:
  1. PHP SOAP 发送XML
  2. PHP添加SOAP模块

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

php soap

上一篇:php中的-=是什么意思

下一篇:C/C++ Qt TreeWidget单层树形组件怎么应用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》