NuSOAP教程

  •   2009-07-31/22:54
  • 这个文档描述了如何取得和安装 NuSOAP,然后提供一些实例来说明 NuSOAP 的功能,这并不是一个全面的 NuSOAP 的介绍,但是希望能够然一些 PHP 开发者可以有一个很好的入门。

    NuSOAP 是一组 PHP 类,它让开发者可以创建和使用 SOAP web services。它不需要安装任何的 PHP 扩展。它是在2004年12月3日被开发,当前的版本是 NuSOAP(0.6.7) 。支持 SOAP 1.1 规范,它能够生产 WSDL 1.1 ,当然也可以使用它,同时也支持 rpc/encoded and document/literal service。但是,必须注意 NuSOAP 没有像 .NET 和 Apache Axis 那样提供完全的实现。

    Hello, World
    我会以 "Hello, World" 为实例做开始,编写基本的 NuSOAP 客户端和服务器端的代码。

    我们先从服务器端开始,应为没有服务器端,有客户端也是没有意义的。我们将编写一个带有单个参数并返回一个字符串,名叫 Hello 的 SOAP 方法,希望代码中的注释能够提供有效的说明。

    <?php
    // Pull in the NuSOAP code
    require_once('nusoap.php');
    // Create the server instance
    $server = new soap_server;
    // Register the method to expose
    $server->register('hello');
    // Define the method as a PHP function
    function hello($name) {
        return 'Hello, ' . $name;
    }
    // Use the request to (try to) invoke the service
    $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
    $server->service($HTTP_RAW_POST_DATA);
    ?>

    以下是客户端的代码,有一些重要的事情需要注意:首先,当创建实例 soapclient 时,需要指定一个 service 的 URL 为参数,在这个实例中,helloworld.php 从 访问的。当然,你要使用的 services 放在不同的 URL;第二,当调用service 时,第一个参数是 service 的名字,必须要匹配有效的方法名(有的服务器是大小写敏感的)。在这个实例,他必须匹配在 helloworld.php 中已经注册了的方法。最后,第二个参数是一个数组,它将是传递给 SOAP service 方法作为参数。既然 helloworld.php 中的方法 hello 只有一个参数,那么数组就只有一个元素。

    <?php
    // Pull in the NuSOAP code
    require_once('nusoap.php');
    // Create the client instance
    $client = new soapclient('http://localhost/phphack/helloworld.php');
    // Call the SOAP method
    $result = $client->call('hello', array('name' => 'Scott'));
    // Display the result
    print_r($result);
    ?>

    Debugging
    编程时,当有问题出现的时候你都需要调试。NuSOAP 提供了一组工具来帮助你做这个工作。NuSOAP 调试的时候需要查看的信息是发送的请求信息和返回的相应信息。NuSOAP 的客户端类允许你通过它的两个成员来查看这些信息。例如,这里是显示请求和响应的 helloworldclient.php 的修改版。在下一部分我会回顾显示在客户端代码的请求和响应信息。

    <?php
    // Pull in the NuSOAP code
    require_once('nusoap.php');
    // Create the client instance
    $client = new soapclient('http://localhost/phphack/helloworld.php');
    // Call the SOAP method
    $result = $client->call('hello', array('name' => 'Scott'));
    // Display the result
    print_r($result);
    // Display the request and response
    echo '<h2>Request</h2>';
    echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
    echo '<h2>Response</h2>';
    echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
    ?>

    NuSOAP 也提供了一个方法使用它的类就可以通过日志来查看调试信息。加入以下的代码将会显示冗长的调试信息。不幸的是输出的说明必须留给读者。

    // Display the debug messages
    echo '<h2>Debug</h2>';
    echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';

    服务器端能够提供相似的调试信息,有趣的是,这些调试信息是在SOAP 的相应的末尾以 xml 格式显示,因此它可以在客户端中查看到。服务器端的调试看起来像这样:

    <?php
    // Pull in the NuSOAP code
    require_once('nusoap.php');
    // Enable debugging *before* creating server instance
    $debug = 1;
    // Create the server instance
    $server = new soap_server;
    // Register the method to expose
    $server->register('hello');
    // Define the method as a PHP function
    function hello($name) {
        return 'Hello, ' . $name;
    }
    // Use the request to (try to) invoke the service
    $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
    $server->service($HTTP_RAW_POST_DATA);
    ?>

    调试的第三个方法不算是真正的调试,它是很好的编程实践。上面的实例在调用 SOAP 的时候没有做错误的检查,更健壮的客户端会像这样:

    <?php
    // Pull in the NuSOAP code
    require_once('nusoap.php');
    // Create the client instance
    $client = new soapclient('http://localhost/phphack/helloworld.php');
    // Check for an error
    $err = $client->getError();
    if ($err) {
        // Display the error
        echo '<p><b>Constructor error: ' . $err . '</b></p>';
        // At this point, you know the call that follows will fail
    }
    // Call the SOAP method
    $result = $client->call('hello', array('name' => 'Scott'));
    // Check for a fault
    if ($client->fault) {
        echo '<p><b>Fault: ';
        print_r($result);
        echo '</b></p>';
    } else {
        // Check for errors
        $err = $client->getError();
        if ($err) {
            // Display the error
            echo '<p><b>Error: ' . $err . '</b></p>';
        } else {
            // Display the result
            print_r($result);
        }
    }
    ?>

    为了测试代码,需要引起错误发生,例如,改变调用的方法名称 hello 为 goodbye。

    Request and Response
    我在上面的例子中已经展示了显示 SOAP 的请求和响应信息是如此的容易,在这里 hello2client.php 的请求信息:

    POST /phphack/helloworld2.php HTTP/1.0
    Host: localhost
    User-Agent: NuSOAP/0.6.8 (1.81)
    Content-Type: text/xml; charset=ISO-8859-1
    SOAPAction: ""
    Content-Length: 538

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <SOAP-ENV:Envelope
      SOAP-ENV:encodingStyle=""
      xmlns:SOAP-ENV=""
      xmlns:xsd=""
      xmlns:xsi=""
      xmlns:SOAP-ENC=""
      xmlns:si="">
    <SOAP-ENV:Body>
      <ns1:hello xmlns:ns1="">
       <name xsi:type="xsd:string">Scott</name>
      </ns1:hello>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    在 HTTP headers 里,你会看到 SOAPAction 是一个空的字符串,这是它的默认值。你的 service 方法可以设置 SOAPAction 的值,你的客户端代码可以指定 SOAPAction 作为参数来调用方法。

    在 XML payload,你可以看到 NuSOAP 使用和Latin-1一样著名的 ISO-8859-1 做为编码,为了指定不同的编码,你可以在客户端 soapclient 的实例设置 soap_defencoding 属性。使用指定的编码来编码参数的数据当然就是程序员的责任。幸运地,在 SOAP 里PHP提供了很多函数来编码和解码最通用的编码数据,如 UTF-8。


    另一件事情要注意的是,元素指定要调用的方法,名称为 hello 的元素被放在 的域名下,指定真实的域名是最佳的实践,对于很多 services 也是很有必要的。这里展示了一个未来的文档:

    SOAP 服务的响应像以下:

    HTTP/1.1 200 OK
    Server: Microsoft-IIS/5.0
    Date: Wed, 03 Nov 2004 21:32:34 GMT
    X-Powered-By: ASP.NET
    X-Powered-By: PHP/4.3.4
    Server: NuSOAP Server v0.6.8
    X-SOAP-Server: NuSOAP/0.6.8 (1.81)
    Content-Type: text/xml; charset=ISO-8859-1
    Content-Length: 556

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <SOAP-ENV:Envelope
      SOAP-ENV:encodingStyle=""
      xmlns:SOAP-ENV=""
      xmlns:xsd=""
      xmlns:xsi=""
      xmlns:SOAP-ENC=""
      xmlns:si="">
    <SOAP-ENV:Body>
      <ns1:helloResponse xmlns:ns1="">
       <return xsi:type="xsd:string">Hello, Scott</return>
      </helloResponse>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多