我应该如何处理XML :: RPC和Drupal中的数字字符串?

时间:2008-11-03 22:03:37

标签: perl drupal xml-rpc

我正在尝试在我的Drupal(PHP)后端使用XML-RPC服务器,以便我的Perl后端更容易与之通信。但是,我遇到了一个问题,我不确定哪些部分(如果有的话)是错误的。本质上,我需要传递给Drupal的一些变量是字符串,有时是充满数字的字符串,Drupal XML-RPC服务器返回一个错误,当一个字符串满了数字时,它没有正确形成。

我的Perl代码目前看起来像这样。

use strict;
use warnings;
use XML::RPC;
use Data::Dumper;
my $xmlrpc = XML::RPC->new(URL);
my $result = $xmlrpc->call( FUNCTION, 'hello world', '9876352345');
print Dumper $result;

输出结果为:

$VAR1 = {
      'faultString' => 'Server error. Invalid method parameters.',
      'faultCode' => '-32602'
};

当我让Drupal XML-RPC服务器打印出它收到的数据时,我注意到第二个参数被输入为i4:

<param>
<value>
<i4>9876352345</i4>
</value>

我认为当Drupal完成处理项目时,它将该变量键入为int而不是字符串。这意味着当Drupal稍后尝试检查变量值是否为字符串正确形成时,is_string PHP函数返回false。

foreach ($signature as $key => $type) {
  $arg = $args[$key];
  switch ($type) {
    case 'int':
    case 'i4':
      if (is_array($arg) || !is_int($arg)) {
        $ok = FALSE;
      }
      break;
    case 'base64':
    case 'string':
      if (!is_string($arg)) {
        $ok = FALSE;
      }
      break;
    case 'boolean':
      if ($arg !== FALSE && $arg !== TRUE) {
        $ok = FALSE;
      }
      break;
    case 'float':
    case 'double':
      if (!is_float($arg)) {
        $ok = FALSE;
      }
      break;
    case 'date':
    case 'dateTime.iso8601':
      if (!$arg->is_date) {
        $ok = FALSE;
      }
      break;
  }
  if (!$ok) {
    return xmlrpc_error(-32602, t('Server error. Invalid method parameters.'));
  }
}

我不确定的问题在于问题存在于哪一方面,或者我还应该使用其他方面。如果Perl端的请求是将字符串输入为字符串而不是i4,或者请求的Drupal端是否对字符串类型过于严格?我的猜测是问题是后者,但我不太了解XML-RPC服务器应该如何工作以确定。

3 个答案:

答案 0 :(得分:1)

数字9876352345太大,无法容纳32位整数。这可能会导致问题。

答案 1 :(得分:1)

你正在使用边境吗?也许你可以明确地声明字符串?

my $result =
  $xmlrpc->call( FUNCTION, 'hello world', $xmlrpc->string('9876352345') );
来自client docs

信息:

  

默认情况下,您可以传递要编码的普通Perl值(标量)。如果RPC2看起来像整数,浮点或字符串,它们会自动将它们转换为XML-RPC类型。当您想要传递看起来像“0096”的字符串时,此假设会导致问题,RPC2会将其转换为a,因为它看起来像一个整数。

答案 2 :(得分:0)

我对XML :: RPC包没有任何经验,但我是RPC::XML CPAN模块的作者。与Frontier包一样,我提供了一种方法,可以将值强制转换为特定类型,否则将默认为其他类型。

如果我不得不猜测,我会说你使用简单的软件包会对数据进行正则表达式匹配,以决定如何输入它。我的包有一个类似的问题,并且考虑到Perl处理标量值的方式,唯一真正的方法是强制它使用显式声明。正如先前的回答者所指出的,所讨论的值实际上在&lt; i4&gt;的范围之外。 type(有符号的32位值)。因此,即使您希望它是一个整数值,它在XML-RPC规范方面也是无效的。

我建议切换到其他XML-RPC包之一,这些包具有明确键入数据的更清晰的方式。根据XML :: RPC的文档,可以强制输入数据,但我发现它不清楚并且没有很好地解释。