使用typemap选项的PHP SoapClient示例

时间:2011-01-26 16:39:07

标签: php soap

我在PHP的SoapClient中使用命名空间时遇到了一些问题。 从文档中我相信构造函数的typemap选项将解决我的问题。

http://php.net/manual/en/soapclient.soapclient.php

我还没有找到一个可靠的例子。

有人有例子吗?

1 个答案:

答案 0 :(得分:13)

这是一个从测试源中获取的简单示例,其中添加了我的注释:

SOAP请求

<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"
  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
  xmlns:enc=\"http://schemas.xmlsoap.org/soap/encoding/\"
  xmlns:ns1=\"http://schemas.nothing.com\"
>
<env:Body>
  <ns1:dotest>
    <book xsi:type=\"ns1:book\">
      <a xsi:type=\"xsd:string\">foo</a>
      <b xsi:type=\"xsd:string\">bar</b>
    </book>
  </ns1:dotest>
</env:Body>
<env:Header/>
</env:Envelope>";

守则

// data object class
class book{
    public $a="a";
    public $b="c";
}

// XML transform callback function (for converting the "type" into an object)
function book_from_xml($xml) {
    $sxe = simplexml_load_string($xml);
    $obj = new book;
    $obj->a = (string)$sxe->a;
    $obj->b = (string)$sxe->b;
    return $obj;
}

// SOAP action class (called by soap handle() method)
class test
{
    function dotest($book)
    {
        $classname=get_class($book);
        return "Object: ".$classname. "(".$book->a.",".$book->b.")";
    }
}

// SOAPServer Instantiation
$options=Array(
    'actor' =>'http://schemas.nothing.com',
    'typemap' => array(
        array(
            // type namespaces have to match those declared in the WSDL
            'type_ns' => 'http://schemas.nothing.com',
            'type_name' => 'book',
            'from_xml' => 'book_from_xml',
        ),
        // additional typemap definition arrays go here
    )
);
$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options);
$server->setClass("test");
$server->handle($HTTP_RAW_POST_DATA);

Source Reference File

有用但重要的注意事项

  1. 输入类型地图必须定义了from_xml回调,否则您将收到细分错误。
  2. 输出类型地图必须定义了to_xml回调,否则您将收到细分错误。
  3. type_ns命名空间值必须与WSDL中定义的文字命名空间匹配,否则不会发生类型匹配。
  4. 回调可能比上例中使用的简单函数回调更复杂。支持类/对象方法。见下文。
  5. 复杂回调

    当使用对象或类方法进行回调时,您需要确保使用类的FQCN(如果您正在使用名称空间),并且a)如果您将回调方法声明为public static不希望实例化实例或b)首先创建对象的实例并使用其方法作为回调。

    以下是typemap数组中更复杂的回调的一些示例:

    静态类方法调用
    ...
    array(
        // type namespaces have to match those declared in the WSDL
        'type_ns' => 'http://schemas.nothing.com',
        'type_name' => 'book',
        // myStaticCallbackMethod must be a public static function of MyClass
        'from_xml' => array('\My\Name\Space\MyClass', 'myStaticCallbackMethod'),
    ),
    

    或者PHP PHP 5.2.3及以上版本:

    array(
        // type namespaces have to match those declared in the WSDL
        'type_ns' => 'http://schemas.nothing.com',
        'type_name' => 'book',
        // myStaticCallbackMethod must be a public static function of MyClass
        'from_xml' => array('\My\Name\Space\MyClass::myStaticCallbackMethod'),
    ),
    

    班级定义:

    namespace My\Name\Space;
    
    class MyClass
    {
        public static function myStaticCallbackMethod($xml)
        {
            // do something
        }
    }
    
    对象方法调用
    $obj = new \My\Name\Space\MyClass();
    ...
    // static class method call
    array(
        // type namespaces have to match those declared in the WSDL
        'type_ns' => "http://schemas.nothing.com",
        'type_name' => 'book',
        'from_xml' => array($obj, 'myCallbackMethod'),
    ),
    

    班级定义:

    namespace My\Name\Space;
    
    class MyClass
    {
        public function myCallbackMethod($xml)
        {
            // do something
        }
    }
    
    闭包
    $myCallback = function($xml) {
        // do something
    };
    ...
    // static class method call
    array(
        // type namespaces have to match those declared in the WSDL
        'type_ns' => 'http://schemas.nothing.com',
        'type_name' => 'book',
        'from_xml' => $myCallback,
    ),