PHP SOAP中的数据类型

0 投票
1 回答
1082 浏览
提问于 2025-04-17 09:59

我在根据我的WebService WSDL创建合适的变量时遇到了问题。我已经成功地在Python中使用suds 0.4 SOAP库实现了这个简单的功能。

Python的实现(tracker是我的SOAP客户端对象,用来消费wsdl):

c = self.tracker.factory.create("ns4:Text")
c.type = "text/html"
c.content = "my content goes here"
self.tracker.service.createComment(c)

我该如何在PHP中实现这个功能呢?乍一看,我不太明白如何用PHP的SOAP扩展来做到这一点。Python中的"...factory.create("ns4:Text")"看起来很方便。我可以检查对象的属性,并轻松地将其传递给我可用的函数。

我真的需要在PHP中这样定义对象吗:

$c->type = "text/html";
$c->content = "my content goes here";
$this->tracker->__soapCall('createComment',array($c));

这个实现要求我知道并定义对象的所有属性。我有复杂的数据类型,有37个以上的属性,还有嵌套的属性。只有4个属性是必需的,我希望只填充这4个属性就能将其传递给服务器,但仍然希望作为一个完整的对象,所有属性都被定义...?

这样说有道理吗?

总结一下:Python从wsdl文件中为我创建了完整的对象,我该如何在PHP中做到这一点呢?

1 个回答

1

PHP可以利用WSDL文件来生成一套合适的方法,这些方法可以接收通用对象、数组或基本数据类型作为参数。你还可以指定哪些类对应哪些方法(这叫做classmap选项),以及哪些类型声明对应哪些序列化回调函数(这叫做typemap选项),这些都是通过SoapClient类的第二个参数来实现的。

class doRequestMethod {
    public $id;
    public $attribute;
}

class theResponseClass {
    /* ... */
}

$options = array(
    'classmap' => array(
        'doRequest'   => 'doRequestMethod',
        'theResponse' => 'theResponseClass'
        /* ... */
    ),
    'typemap' => array(
        0 => array(
            'type_ns' => 'http://example.com/schema/wsdl_type.xsd',
            'type_name"'   => 'wsdl_type',
            'from_xml'     => function ($xml_string) { /* ... */ },
            'to_xml'       => function ($soap_object) { /* ... */ }
        )
        /* ... */
    )
)

$client = new SoapClient('/path/to/filename.wsdl', $options);

$request = new doRequestMethod();
$request->id = 0;
$request->attribute = "FooBar";
$result = $client->doRequest($request);

/* 
 * If 'dorequest' returns a 'theResponse' in the WSDL, 
 * then $result should of the type 'theResponseClass'.
 */
assert(get_class($result) === 'theResponseClass');

这项工作量很大,所以我建议你为自己的使用创建一个SoapClient的子类。此外,为了让代码更容易调试,尽量在函数和参数上使用PHP的类型提示。这可以避免很多类型的错误,虽然会稍微影响性能,但这是值得的。

撰写回答